VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTGetOpt.cpp@ 74414

Last change on this file since 74414 was 71009, checked in by vboxsync, 7 years ago

RTGetOpt: Fixed bug handling missing option values when RTGETOPTINIT_FLAGS_OPTS_FIRST is active.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 24.6 KB
Line 
1/* $Id: tstRTGetOpt.cpp 71009 2018-02-14 13:29:47Z vboxsync $ */
2/** @file
3 * IPRT Testcase - RTGetOpt
4 */
5
6/*
7 * Copyright (C) 2007-2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 */
26
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/net.h>
32#include <iprt/getopt.h>
33
34#include <iprt/err.h>
35#include <iprt/string.h>
36#include <iprt/test.h>
37
38
39int main()
40{
41 RTTEST hTest;
42 int rc = RTTestInitAndCreate("tstRTGetOpt", &hTest);
43 if (rc)
44 return rc;
45
46 RTGETOPTSTATE GetState;
47 RTGETOPTUNION Val;
48#define CHECK(expr) do { if (!(expr)) { RTTestIFailed("error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); } } while (0)
49#define CHECK2(expr, fmt) \
50 do { \
51 if (!(expr)) { \
52 RTTestIFailed("error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); \
53 RTTestIFailureDetails fmt; \
54 } \
55 } while (0)
56
57#define CHECK_pDef(paOpts, i) \
58 CHECK2(Val.pDef == &(paOpts)[(i)], ("Got #%d (%p) expected #%d\n", (int)(Val.pDef - &(paOpts)[0]), Val.pDef, i));
59
60#define CHECK_GETOPT(expr, chRet, iInc) \
61 do { \
62 const int iPrev = GetState.iNext; \
63 const int rcGetOpt = (expr); \
64 CHECK2(rcGetOpt == (chRet), ("got %d, expected %d\n", rcGetOpt, (chRet))); \
65 CHECK2(GetState.iNext == (iInc) + iPrev, ("iNext=%d expected %d\n", GetState.iNext, (iInc) + iPrev)); \
66 GetState.iNext = (iInc) + iPrev; \
67 } while (0)
68
69#define CHECK_GETOPT_STR(expr, chRet, iInc, str) \
70 do { \
71 const int iPrev = GetState.iNext; \
72 const int rcGetOpt = (expr); \
73 CHECK2(rcGetOpt == (chRet), ("got %d, expected %d\n", rcGetOpt, (chRet))); \
74 CHECK2(GetState.iNext == (iInc) + iPrev, ("iNext=%d expected %d\n", GetState.iNext, (iInc) + iPrev)); \
75 CHECK2(VALID_PTR(Val.psz) && !strcmp(Val.psz, (str)), ("got %s, expected %s\n", Val.psz, (str))); \
76 GetState.iNext = (iInc) + iPrev; \
77 } while (0)
78
79
80 /*
81 * The basics.
82 */
83 RTTestSub(hTest, "Basics");
84 static const RTGETOPTDEF s_aOpts2[] =
85 {
86 { "--optwithstring", 's', RTGETOPT_REQ_STRING },
87 { "--optwithint", 'i', RTGETOPT_REQ_INT32 },
88 { "--verbose", 'v', RTGETOPT_REQ_NOTHING },
89 { NULL, 'q', RTGETOPT_REQ_NOTHING },
90 { "--quiet", 384, RTGETOPT_REQ_NOTHING },
91 { "-novalue", 385, RTGETOPT_REQ_NOTHING },
92 { "-startvm", 386, RTGETOPT_REQ_STRING },
93 { "nodash", 387, RTGETOPT_REQ_NOTHING },
94 { "nodashval", 388, RTGETOPT_REQ_STRING },
95 { "--gateway", 'g', RTGETOPT_REQ_IPV4ADDR },
96 { "--mac", 'm', RTGETOPT_REQ_MACADDR },
97 { "--strindex", 400, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
98 { "strindex", 400, RTGETOPT_REQ_STRING | RTGETOPT_FLAG_INDEX },
99 { "--intindex", 401, RTGETOPT_REQ_INT32 | RTGETOPT_FLAG_INDEX },
100 { "--macindex", 402, RTGETOPT_REQ_MACADDR | RTGETOPT_FLAG_INDEX },
101 { "--indexnovalue", 403, RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_INDEX },
102 { "--macindexnegative", 404, RTGETOPT_REQ_NOTHING },
103 { "--twovalues", 405, RTGETOPT_REQ_STRING },
104 { "--twovaluesindex", 406, RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_INDEX },
105 { "--threevalues", 407, RTGETOPT_REQ_UINT32 },
106 { "--boolean", 408, RTGETOPT_REQ_BOOL_ONOFF },
107 { "--booleanindex", 409, RTGETOPT_REQ_BOOL_ONOFF | RTGETOPT_FLAG_INDEX },
108 { "--pair32", 410, RTGETOPT_REQ_UINT32_PAIR },
109 { "--optpair32", 411, RTGETOPT_REQ_UINT32_OPTIONAL_PAIR },
110 { "--optpair64", 412, RTGETOPT_REQ_UINT64_OPTIONAL_PAIR },
111 };
112
113 const char *argv2[] =
114 {
115 "-s", "string1",
116 "-sstring2",
117 "-s:string3",
118 "-s=string4",
119 "-s:",
120 "-s=",
121 "--optwithstring", "string5",
122 "--optwithstring:string6",
123 "--optwithstring=string7",
124 "--optwithstring:",
125 "--optwithstring=",
126
127 "-i", "-42",
128 "-i:-42",
129 "-i=-42",
130
131 "--optwithint", "42",
132 "--optwithint:42",
133 "--optwithint=42",
134
135 "-v",
136 "--verbose",
137 "-q",
138 "--quiet",
139
140 "-novalue",
141 "-startvm", "myvm",
142
143 "nodash",
144 "nodashval", "string9",
145
146 "filename1",
147 "-q",
148 "filename2",
149
150 "-vqi999",
151
152 "-g192.168.1.1",
153
154 "-m08:0:27:00:ab:f3",
155 "--mac:1:::::c",
156
157 "--strindex786", "string10",
158 "--strindex786:string11",
159 "--strindex786=string12",
160 "strindex687", "string13",
161 "strindex687:string14",
162 "strindex687=string15",
163 "strindex688:",
164 "strindex689=",
165 "--intindex137", "1000",
166 "--macindex138", "08:0:27:00:ab:f3",
167 "--indexnovalue1",
168 "--macindexnegative",
169
170 "--twovalues", "firstvalue", "secondvalue",
171 "--twovalues:firstvalue", "secondvalue",
172 "--twovaluesindex4", "1", "0xA",
173 "--twovaluesindex5=2", "0xB",
174 "--threevalues", "1", "0xC", "thirdvalue",
175
176 /* bool on/off */
177 "--boolean", "on",
178 "--boolean", "off",
179 "--boolean", "invalid",
180 "--booleanindex2", "on",
181 "--booleanindex7", "off",
182 "--booleanindex9", "invalid",
183
184 /* standard options */
185 "--help",
186 "-help",
187 "-?",
188 "-h",
189 "--version",
190 "-version",
191 "-V",
192
193 /* 32-bit pairs */
194 "--pair32", "1536:0x1536",
195 "--optpair32", "0x42:042",
196 "--optpair32", "0128",
197 "--optpair64", "0x128 0x42",
198 "--optpair64", "0x128 :0x42",
199 "--optpair64", "0x128",
200
201 /* done */
202 NULL
203 };
204 int argc2 = (int)RT_ELEMENTS(argv2) - 1;
205
206 CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc2, (char **)argv2, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0, 0 /* fFlags */)));
207
208 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 2);
209 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string1"));
210 CHECK(GetState.uIndex == UINT32_MAX);
211 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
212 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string2"));
213 CHECK(GetState.uIndex == UINT32_MAX);
214 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
215 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string3"));
216 CHECK(GetState.uIndex == UINT32_MAX);
217 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
218 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string4"));
219 CHECK(GetState.uIndex == UINT32_MAX);
220 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
221 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, ""));
222 CHECK(GetState.uIndex == UINT32_MAX);
223 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
224 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, ""));
225 CHECK(GetState.uIndex == UINT32_MAX);
226 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 2);
227 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string5"));
228 CHECK(GetState.uIndex == UINT32_MAX);
229 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
230 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string6"));
231 CHECK(GetState.uIndex == UINT32_MAX);
232 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
233 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string7"));
234 CHECK(GetState.uIndex == UINT32_MAX);
235 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
236 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, ""));
237 CHECK(GetState.uIndex == UINT32_MAX);
238 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 1);
239 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, ""));
240 CHECK(GetState.uIndex == UINT32_MAX);
241
242 /* -i */
243 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2);
244 CHECK(Val.i32 == -42);
245 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
246 CHECK(Val.i32 == -42);
247 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
248 CHECK(Val.i32 == -42);
249
250 /* --optwithint */
251 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2);
252 CHECK(Val.i32 == 42);
253 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
254 CHECK(Val.i32 == 42);
255 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
256 CHECK(Val.i32 == 42);
257
258 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 1);
259 CHECK_pDef(s_aOpts2, 2);
260 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 1);
261 CHECK_pDef(s_aOpts2, 2);
262
263 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 1);
264 CHECK_pDef(s_aOpts2, 3);
265 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 384, 1);
266 CHECK_pDef(s_aOpts2, 4);
267
268 /* -novalue / -startvm (single dash long options) */
269 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 385, 1);
270 CHECK_pDef(s_aOpts2, 5);
271 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 386, 2);
272 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "myvm"));
273
274 /* no-dash options */
275 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 387, 1);
276 CHECK_pDef(s_aOpts2, 7);
277 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 388, 2);
278 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string9"));
279
280 /* non-option, option, non-option */
281 CHECK_GETOPT(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1);
282 CHECK(Val.psz && !strcmp(Val.psz, "filename1"));
283 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 1);
284 CHECK_pDef(s_aOpts2, 3);
285 CHECK_GETOPT(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1);
286 CHECK(Val.psz && !strcmp(Val.psz, "filename2"));
287
288 /* compress short options */
289 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 0);
290 CHECK_pDef(s_aOpts2, 2);
291 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 0);
292 CHECK_pDef(s_aOpts2, 3);
293 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
294 CHECK(Val.i32 == 999);
295
296 /* IPv4 */
297 RTTestSub(hTest, "RTGetOpt - IPv4");
298 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'g', 1);
299 CHECK(Val.IPv4Addr.u == RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8(192,168,1,1))));
300
301 /* Ethernet MAC address. */
302 RTTestSub(hTest, "RTGetOpt - MAC Address");
303 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'm', 1);
304 CHECK( Val.MacAddr.au8[0] == 0x08
305 && Val.MacAddr.au8[1] == 0x00
306 && Val.MacAddr.au8[2] == 0x27
307 && Val.MacAddr.au8[3] == 0x00
308 && Val.MacAddr.au8[4] == 0xab
309 && Val.MacAddr.au8[5] == 0xf3);
310 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'm', 1);
311 CHECK( Val.MacAddr.au8[0] == 0x01
312 && Val.MacAddr.au8[1] == 0x00
313 && Val.MacAddr.au8[2] == 0x00
314 && Val.MacAddr.au8[3] == 0x00
315 && Val.MacAddr.au8[4] == 0x00
316 && Val.MacAddr.au8[5] == 0x0c);
317
318 /* string with indexed argument */
319 RTTestSub(hTest, "RTGetOpt - Option w/ Index");
320 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2);
321 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string10"));
322 CHECK(GetState.uIndex == 786);
323
324 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
325 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string11"));
326 CHECK(GetState.uIndex == 786);
327
328 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
329 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string12"));
330 CHECK(GetState.uIndex == 786);
331
332 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2);
333 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string13"));
334 CHECK(GetState.uIndex == 687);
335
336 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
337 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string14"));
338 CHECK(GetState.uIndex == 687);
339
340 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
341 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string15"));
342 CHECK(GetState.uIndex == 687);
343
344 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
345 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, ""));
346 CHECK(GetState.uIndex == 688);
347
348 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
349 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, ""));
350 CHECK(GetState.uIndex == 689);
351
352 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 401, 2);
353 CHECK(Val.i32 == 1000);
354 CHECK(GetState.uIndex == 137);
355
356 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 402, 2);
357 CHECK( Val.MacAddr.au8[0] == 0x08
358 && Val.MacAddr.au8[1] == 0x00
359 && Val.MacAddr.au8[2] == 0x27
360 && Val.MacAddr.au8[3] == 0x00
361 && Val.MacAddr.au8[4] == 0xab
362 && Val.MacAddr.au8[5] == 0xf3);
363 CHECK(GetState.uIndex == 138);
364
365 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 403, 1);
366 CHECK(GetState.uIndex == 1);
367
368 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 404, 1);
369 CHECK(GetState.uIndex == UINT32_MAX);
370
371 /* RTGetOptFetchValue tests */
372 RTTestSub(hTest, "RTGetOptFetchValue");
373 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 405, 2);
374 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "firstvalue"));
375 CHECK(GetState.uIndex == UINT32_MAX);
376 CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1);
377 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "secondvalue"));
378 CHECK(GetState.uIndex == UINT32_MAX);
379
380 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 405, 1);
381 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "firstvalue"));
382 CHECK(GetState.uIndex == UINT32_MAX);
383 CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1);
384 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "secondvalue"));
385 CHECK(GetState.uIndex == UINT32_MAX);
386
387 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 406, 2);
388 CHECK(Val.u32 == 1);
389 CHECK(GetState.uIndex == 4);
390 CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_UINT32), VINF_SUCCESS, 1);
391 CHECK(Val.u32 == 10);
392 CHECK(GetState.uIndex == 4);
393
394 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 406, 1);
395 CHECK(Val.u32 == 2);
396 CHECK(GetState.uIndex == 5);
397 CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_UINT32), VINF_SUCCESS, 1);
398 CHECK(Val.u32 == 11);
399 CHECK(GetState.uIndex == 5);
400
401 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 407, 2);
402 CHECK(Val.u32 == 1);
403 CHECK(GetState.uIndex == UINT32_MAX);
404 CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_UINT32), VINF_SUCCESS, 1);
405 CHECK(Val.u32 == 12);
406 CHECK(GetState.uIndex == UINT32_MAX);
407 CHECK_GETOPT(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1);
408 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "thirdvalue"));
409 CHECK(GetState.uIndex == UINT32_MAX);
410
411 /* bool on/off tests */
412 RTTestSub(hTest, "RTGetOpt - bool on/off");
413 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 408, 2);
414 CHECK(Val.f);
415 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 408, 2);
416 CHECK(!Val.f);
417 CHECK_GETOPT(RTGetOpt(&GetState, &Val), VERR_GETOPT_UNKNOWN_OPTION, 2);
418 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "invalid"));
419
420 /* bool on/off with indexed argument */
421 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 409, 2);
422 CHECK(Val.f);
423 CHECK(GetState.uIndex == 2);
424 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 409, 2);
425 CHECK(!Val.f);
426 CHECK(GetState.uIndex == 7);
427 CHECK_GETOPT(RTGetOpt(&GetState, &Val), VERR_GETOPT_UNKNOWN_OPTION, 2);
428 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "invalid"));
429
430 /* standard options. */
431 RTTestSub(hTest, "Standard options");
432 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1);
433 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1);
434 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1);
435 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1);
436 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1);
437 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1);
438 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1);
439
440 /* 32-bit pairs */
441 RTTestSub(hTest, "RTGetOpt - pairs");
442 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 410, 2);
443 CHECK(Val.PairU32.uFirst == 1536);
444 CHECK(Val.PairU32.uSecond == 0x1536);
445 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 411, 2);
446 CHECK(Val.PairU32.uFirst == 0x42);
447 CHECK(Val.PairU32.uSecond == 42);
448 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 411, 2);
449 CHECK(Val.PairU32.uFirst == 128);
450 CHECK(Val.PairU32.uSecond == UINT32_MAX);
451 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 412, 2);
452 CHECK(Val.PairU64.uFirst == 0x128);
453 CHECK(Val.PairU64.uSecond == 0x42);
454 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 412, 2);
455 CHECK(Val.PairU64.uFirst == 0x128);
456 CHECK(Val.PairU64.uSecond == 0x42);
457 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 412, 2);
458 CHECK(Val.PairU64.uFirst == 0x128);
459 CHECK(Val.PairU64.uSecond == UINT64_MAX);
460
461 /* the end */
462 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0);
463 CHECK(Val.pDef == NULL);
464 CHECK(argc2 == GetState.iNext);
465
466 /*
467 * Options first.
468 */
469 RTTestSub(hTest, "Options first");
470 const char *argv3[] =
471 {
472 "foo1",
473 "-s", "string1",
474 "foo2",
475 "--optwithstring", "string2",
476 "foo3",
477 "-i", "-42",
478 "foo4",
479 "-i:-42",
480 "-i=-42",
481 "foo5",
482 "foo6",
483 "foo7",
484 "-i:-42",
485 "-i=-42",
486 "foo8",
487 "--twovalues", "firstvalue", "secondvalue",
488 "foo9",
489 "--twovalues:firstvalue", "secondvalue",
490 "foo10",
491 "--",
492 "--optwithstring",
493 "-s",
494 "-i",
495 "foo11",
496 "foo12",
497
498 /* done */
499 NULL
500 };
501 int argc3 = (int)RT_ELEMENTS(argv3) - 1;
502
503 CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc3, (char **)argv3, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0,
504 RTGETOPTINIT_FLAGS_OPTS_FIRST)));
505
506 /* -s */
507 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string1");
508 CHECK(GetState.uIndex == UINT32_MAX);
509 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string2");
510 CHECK(GetState.uIndex == UINT32_MAX);
511
512 /* -i */
513 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2);
514 CHECK(Val.i32 == -42);
515 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
516 CHECK(Val.i32 == -42);
517 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
518 CHECK(Val.i32 == -42);
519 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
520 CHECK(Val.i32 == -42);
521 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
522 CHECK(Val.i32 == -42);
523
524 /* --twovalues */
525 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 2, "firstvalue");
526 CHECK(GetState.uIndex == UINT32_MAX);
527 CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue");
528 CHECK(GetState.uIndex == UINT32_MAX);
529
530 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 1, "firstvalue");
531 CHECK(GetState.uIndex == UINT32_MAX);
532 CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue");
533 CHECK(GetState.uIndex == UINT32_MAX);
534
535 /* -- */
536 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 2, "foo1");
537 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo2");
538 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo3");
539 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo4");
540 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo5");
541 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo6");
542 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo7");
543 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo8");
544 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo9");
545 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo10");
546 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "--optwithstring");
547 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "-s");
548 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "-i");
549 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo11");
550 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo12");
551
552 /* the end */
553 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0);
554 CHECK(Val.pDef == NULL);
555 CHECK(argc3 == GetState.iNext);
556
557 /*
558 * Options first, part 2: No dash-dash.
559 */
560 const char *argv4[] =
561 {
562 "foo1",
563 "-s", "string1",
564 "foo2",
565 "--optwithstring", "string2",
566 "foo3",
567 "-i", "-42",
568 "foo4",
569 "-i:-42",
570 "-i=-42",
571 "foo5",
572 "foo6",
573 "foo7",
574 "-i:-42",
575 "-i=-42",
576 "foo8",
577 "--twovalues", "firstvalue", "secondvalue",
578 "foo9",
579 "--twovalues:firstvalue", "secondvalue",
580 "foo10",
581 "foo11",
582 "foo12",
583
584 /* done */
585 NULL
586 };
587 int argc4 = (int)RT_ELEMENTS(argv4) - 1;
588
589 CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc4, (char **)argv4, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0,
590 RTGETOPTINIT_FLAGS_OPTS_FIRST)));
591
592 /* -s */
593 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string1");
594 CHECK(GetState.uIndex == UINT32_MAX);
595 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string2");
596 CHECK(GetState.uIndex == UINT32_MAX);
597
598 /* -i */
599 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2);
600 CHECK(Val.i32 == -42);
601 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
602 CHECK(Val.i32 == -42);
603 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
604 CHECK(Val.i32 == -42);
605 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
606 CHECK(Val.i32 == -42);
607 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1);
608 CHECK(Val.i32 == -42);
609
610 /* --twovalues */
611 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 2, "firstvalue");
612 CHECK(GetState.uIndex == UINT32_MAX);
613 CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue");
614 CHECK(GetState.uIndex == UINT32_MAX);
615
616 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 1, "firstvalue");
617 CHECK(GetState.uIndex == UINT32_MAX);
618 CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue");
619 CHECK(GetState.uIndex == UINT32_MAX);
620
621 /* -- */
622 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo1");
623 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo2");
624 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo3");
625 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo4");
626 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo5");
627 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo6");
628 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo7");
629 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo8");
630 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo9");
631 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo10");
632 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo11");
633 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo12");
634
635 /* the end */
636 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0);
637 CHECK(Val.pDef == NULL);
638 CHECK(argc4 == GetState.iNext);
639
640 /*
641 * Some negative testing.
642 */
643 const char *argv5[] =
644 {
645 "non-option-argument",
646 "--optwithstring", /* missing string */
647 /* done */
648 NULL
649 };
650 int argc5 = (int)RT_ELEMENTS(argv5) - 1;
651 CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc5, (char **)argv5, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0,
652 RTGETOPTINIT_FLAGS_OPTS_FIRST)));
653 RTTESTI_CHECK_RC(RTGetOpt(&GetState, &Val), VERR_GETOPT_REQUIRED_ARGUMENT_MISSING);
654
655
656 /*
657 * Summary.
658 */
659 return RTTestSummaryAndDestroy(hTest);
660}
661
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette