Changeset 26485 in vbox
- Timestamp:
- Feb 14, 2010 6:59:06 AM (15 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/getopt.h
r26476 r26485 205 205 /** The index of an index option, otherwise UINT32_MAX. */ 206 206 uint32_t uIndex; 207 /* More members will be added later for dealing with initial 208 call, optional sorting, '--' and so on. */ 207 /** The flags passed to RTGetOptInit. */ 208 uint32_t fFlags; 209 /** Number of non-options that we're skipping during a sorted get. The value 210 * INT32_MAX is used to indicate that there are no more options. This is used 211 * to implement '--'. */ 212 int32_t cNonOptions; 213 214 /* More members may be added later for dealing with new features. */ 209 215 } RTGETOPTSTATE; 210 216 /** Pointer to RTGetOpt state. */ … … 235 241 PCRTGETOPTDEF paOptions, size_t cOptions, 236 242 int iFirst, uint32_t fFlags); 243 244 /** @name RTGetOptInit flags. 245 * @{ */ 246 /** Sort the arguments so that options comes first, then non-options. */ 247 #define RTGETOPTINIT_FLAGS_OPTS_FIRST RT_BIT_32(0) 248 /** Prevent add the standard version and help options: 249 * - "--help", "-h" and "-?" returns 'h'. 250 * - "--version" and "-V" return 'V'. 251 */ 252 #define RTGETOPTINIT_FLAGS_NO_STD_OPTS RT_BIT_32(1) 253 /** @} */ 237 254 238 255 /** -
trunk/src/VBox/Runtime/common/misc/getopt.cpp
r25323 r26485 5 5 6 6 /* 7 * Copyright (C) 2007 Sun Microsystems, Inc.7 * Copyright (C) 2007-2010 Sun Microsystems, Inc. 8 8 * 9 9 * This file is part of VirtualBox Open Source Edition (OSE), as … … 44 44 45 45 46 /******************************************************************************* 47 * Global Variables * 48 *******************************************************************************/ 49 /** 50 * Standard options that gets included unless RTGETOPTINIT_FLAGS_NO_STD_OPTS is 51 * set. 52 */ 53 static RTGETOPTDEF const g_aStdOptions[] = 54 { 55 { "--help", 'h', RTGETOPT_REQ_NOTHING }, 56 { "-help", 'h', RTGETOPT_REQ_NOTHING }, 57 { "--version", 'V', RTGETOPT_REQ_NOTHING }, 58 { "-version", 'V', RTGETOPT_REQ_NOTHING }, 59 }; 60 /** The index of --help in g_aStdOptions. Used for some trickery. */ 61 #define RTGETOPT_STD_OPTIONS_HELP_IDX 0 62 63 46 64 47 65 RTDECL(int) RTGetOptInit(PRTGETOPTSTATE pState, int argc, char **argv, … … 49 67 int iFirst, uint32_t fFlags) 50 68 { 51 AssertReturn(! fFlags, VERR_INVALID_PARAMETER);69 AssertReturn(!(fFlags & ~(RTGETOPTINIT_FLAGS_OPTS_FIRST | RTGETOPTINIT_FLAGS_NO_STD_OPTS)), VERR_INVALID_PARAMETER); 52 70 53 71 pState->argv = argv; … … 58 76 pState->pszNextShort = NULL; 59 77 pState->pDef = NULL; 78 pState->uIndex = UINT32_MAX; 79 pState->fFlags = fFlags; 80 pState->cNonOptions = 0; 60 81 61 82 /* validate the options. */ … … 68 89 } 69 90 70 /** @todo Add an flag for sorting the arguments so that all the options comes71 * first. */72 91 return VINF_SUCCESS; 73 92 } … … 180 199 * @param paOptions Option array. 181 200 * @param cOptions Number of items in the array. 182 */ 183 static PCRTGETOPTDEF rtGetOptSearchLong(const char *pszOption, PCRTGETOPTDEF paOptions, size_t cOptions) 201 * @param fFlags Init flags. 202 */ 203 static PCRTGETOPTDEF rtGetOptSearchLong(const char *pszOption, PCRTGETOPTDEF paOptions, size_t cOptions, uint32_t fFlags) 184 204 { 185 205 PCRTGETOPTDEF pOpt = paOptions; … … 233 253 pOpt++; 234 254 } 255 256 if (!(fFlags & RTGETOPTINIT_FLAGS_NO_STD_OPTS)) 257 for (uint32_t i = 0; i < RT_ELEMENTS(g_aStdOptions); i++) 258 if (!strcmp(pszOption, g_aStdOptions[i].pszLong)) 259 return &g_aStdOptions[i]; 260 235 261 return NULL; 236 262 } … … 244 270 * @param paOptions Option array. 245 271 * @param cOptions Number of items in the array. 246 */ 247 static PCRTGETOPTDEF rtGetOptSearchShort(int chOption, PCRTGETOPTDEF paOptions, size_t cOptions) 272 * @param fFlags Init flags. 273 */ 274 static PCRTGETOPTDEF rtGetOptSearchShort(int chOption, PCRTGETOPTDEF paOptions, size_t cOptions, uint32_t fFlags) 248 275 { 249 276 PCRTGETOPTDEF pOpt = paOptions; … … 253 280 return pOpt; 254 281 pOpt++; 282 } 283 284 if (!(fFlags & RTGETOPTINIT_FLAGS_NO_STD_OPTS)) 285 { 286 for (uint32_t i = 0; i < RT_ELEMENTS(g_aStdOptions); i++) 287 if (g_aStdOptions[i].iShort == chOption) 288 return &g_aStdOptions[i]; 289 if (chOption == '?') 290 return &g_aStdOptions[RTGETOPT_STD_OPTIONS_HELP_IDX]; 255 291 } 256 292 return NULL; … … 395 431 396 432 433 /** 434 * Moves one argv option entries. 435 * 436 * @param papszTo Destination. 437 * @param papszFrom Source. 438 */ 439 static void rtGetOptMoveArgvEntries(char **papszTo, char **papszFrom) 440 { 441 if (papszTo != papszFrom) 442 { 443 Assert((uintptr_t)papszTo < (uintptr_t)papszFrom); 444 char * const pszMoved = papszFrom[0]; 445 memmove(&papszTo[1], &papszTo[0], (uintptr_t)papszFrom - (uintptr_t)papszTo); 446 papszTo[0] = pszMoved; 447 } 448 } 449 450 397 451 RTDECL(int) RTGetOpt(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion) 398 452 { … … 408 462 pValueUnion->u64 = 0; 409 463 pValueUnion->pDef = NULL; 410 411 /** @todo Handle '--' (end of options).*/412 /** @todo Add a flag to RTGetOptInit for handling the various help options in413 * a common way. (-?,-h,-help,--help,++) */414 /** @todo Add a flag to RTGetOptInit for handling the standard version options415 * in a common way. (-V,--version) */416 464 417 465 /* … … 428 476 * We've got short options left over from the previous call. 429 477 */ 430 pOpt = rtGetOptSearchShort(*pState->pszNextShort, pState->paOptions, pState->cOptions );478 pOpt = rtGetOptSearchShort(*pState->pszNextShort, pState->paOptions, pState->cOptions, pState->fFlags); 431 479 if (!pOpt) 432 480 { … … 442 490 { 443 491 /* 444 * Pop off the next argument. 492 * Pop off the next argument. Sorting options and dealing with the 493 * dash-dash makes this a little extra complicated. 445 494 */ 446 if (pState->iNext >= pState->argc) 447 return 0; 448 iThis = pState->iNext++; 449 pszArgThis = pState->argv[iThis]; 450 451 /* 452 * Do a long option search first and then a short option one. 453 * This way we can make sure single dash long options doesn't 454 * get mixed up with short ones. 455 */ 456 pOpt = rtGetOptSearchLong(pszArgThis, pState->paOptions, pState->cOptions); 457 if ( !pOpt 458 && pszArgThis[0] == '-' 459 && pszArgThis[1] != '-' 460 && pszArgThis[1] != '\0') 461 { 462 pOpt = rtGetOptSearchShort(pszArgThis[1], pState->paOptions, pState->cOptions); 463 fShort = pOpt != NULL; 464 } 465 else 466 fShort = false; 495 for (;;) 496 { 497 if (pState->iNext >= pState->argc) 498 return 0; 499 500 if (pState->cNonOptions) 501 { 502 if (pState->cNonOptions == INT32_MAX) 503 { 504 pValueUnion->psz = pState->argv[pState->iNext++]; 505 return VINF_GETOPT_NOT_OPTION; 506 } 507 508 if (pState->iNext + pState->cNonOptions >= pState->argc) 509 { 510 pState->cNonOptions = INT32_MAX; 511 continue; 512 } 513 } 514 515 iThis = pState->iNext++; 516 pszArgThis = pState->argv[iThis + pState->cNonOptions]; 517 518 /* 519 * Do a long option search first and then a short option one. 520 * This way we can make sure single dash long options doesn't 521 * get mixed up with short ones. 522 */ 523 pOpt = rtGetOptSearchLong(pszArgThis, pState->paOptions, pState->cOptions, pState->fFlags); 524 if ( !pOpt 525 && pszArgThis[0] == '-' 526 && pszArgThis[1] != '-' 527 && pszArgThis[1] != '\0') 528 { 529 pOpt = rtGetOptSearchShort(pszArgThis[1], pState->paOptions, pState->cOptions, pState->fFlags); 530 fShort = pOpt != NULL; 531 } 532 else 533 fShort = false; 534 535 /* Look for dash-dash. */ 536 if (!pOpt && !strcmp(pszArgThis, "--")) 537 { 538 rtGetOptMoveArgvEntries(&pState->argv[iThis], &pState->argv[iThis + pState->cNonOptions]); 539 pState->cNonOptions = INT32_MAX; 540 continue; 541 } 542 543 /* Options first hacks. */ 544 if (pState->fFlags & RTGETOPTINIT_FLAGS_OPTS_FIRST) 545 { 546 if (pOpt) 547 rtGetOptMoveArgvEntries(&pState->argv[iThis], &pState->argv[iThis + pState->cNonOptions]); 548 else if (*pszArgThis == '-') 549 { 550 pValueUnion->psz = pszArgThis; 551 return VERR_GETOPT_UNKNOWN_OPTION; 552 } 553 else 554 { 555 /* not an option, add it to the non-options and try again. */ 556 pState->iNext--; 557 pState->cNonOptions++; 558 559 /* Switch to returning non-options if we've reached the end. */ 560 if (pState->iNext + pState->cNonOptions >= pState->argc) 561 pState->cNonOptions = INT32_MAX; 562 continue; 563 } 564 } 565 566 /* done */ 567 break; 568 } 467 569 } 468 570 … … 492 594 if (iThis + 1 >= pState->argc) 493 595 return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING; 494 pszValue = pState->argv[iThis + 1]; 596 pszValue = pState->argv[iThis + pState->cNonOptions + 1]; 597 rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]); 495 598 pState->iNext++; 496 599 } … … 528 631 return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING; 529 632 pState->uIndex = uIndex; 530 pszValue = pState->argv[iThis + 1]; 633 pszValue = pState->argv[iThis + pState->cNonOptions + 1]; 634 rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]); 531 635 pState->iNext++; 532 636 } … … 541 645 if (iThis + 1 >= pState->argc) 542 646 return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING; 543 pszValue = pState->argv[iThis + 1]; 647 pszValue = pState->argv[iThis + pState->cNonOptions + 1]; 648 rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]); 544 649 pState->iNext++; 545 650 } … … 600 705 * fail with unkown option, and if it doesn't we'll return it as a non-option. 601 706 */ 602 603 707 if (*pszArgThis == '-') 604 708 { … … 635 739 return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING; 636 740 int iThis = pState->iNext++; 637 const char *pszValue = pState->argv[iThis ];741 const char *pszValue = pState->argv[iThis + (pState->cNonOptions != INT32_MAX ? pState->cNonOptions : 0)]; 638 742 pValueUnion->pDef = pOpt; /* in case of no value or error. */ 743 744 if (pState->cNonOptions && pState->cNonOptions != INT32_MAX) 745 rtGetOptMoveArgvEntries(&pState->argv[iThis], &pState->argv[iThis + pState->cNonOptions]); 639 746 640 747 return rtGetOptProcessValue(fFlags, pszValue, pValueUnion); -
trunk/src/VBox/Runtime/testcase/tstGetOpt.cpp
r25323 r26485 35 35 #include <iprt/net.h> 36 36 #include <iprt/getopt.h> 37 #include <iprt/stream.h> 38 #include <iprt/ initterm.h>37 38 #include <iprt/err.h> 39 39 #include <iprt/string.h> 40 #include <iprt/ err.h>40 #include <iprt/test.h> 41 41 42 42 43 43 int main() 44 44 { 45 int cErrors = 0; 46 RTR3Init(); 47 RTPrintf("tstGetOpt: TESTING...\n"); 45 RTTEST hTest; 46 int rc = RTTestInitAndCreate("tstRTGetOpt", &hTest); 47 if (rc) 48 return rc; 48 49 49 50 RTGETOPTSTATE GetState; 50 51 RTGETOPTUNION Val; 51 #define CHECK(expr) do { if (!(expr)) { RT Printf("tstGetOpt: error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); cErrors++; } } while (0)52 #define CHECK(expr) do { if (!(expr)) { RTTestIFailed("error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); } } while (0) 52 53 #define CHECK2(expr, fmt) \ 53 54 do { \ 54 55 if (!(expr)) { \ 55 RTPrintf("tstGetOpt: error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); \ 56 RTPrintf fmt; \ 57 cErrors++; \ 56 RTTestIFailed("error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); \ 57 RTTestIFailureDetails fmt; \ 58 58 } \ 59 59 } while (0) … … 65 65 do { \ 66 66 const int iPrev = GetState.iNext; \ 67 const int rc = (expr); \68 CHECK2(rc == (chRet), ("got %d, expected %d\n", rc, (chRet))); \67 const int rcGetOpt = (expr); \ 68 CHECK2(rcGetOpt == (chRet), ("got %d, expected %d\n", rcGetOpt, (chRet))); \ 69 69 CHECK2(GetState.iNext == (iInc) + iPrev, ("iNext=%d expected %d\n", GetState.iNext, (iInc) + iPrev)); \ 70 70 GetState.iNext = (iInc) + iPrev; \ 71 71 } while (0) 72 72 73 #define CHECK_GETOPT_STR(expr, chRet, iInc, str) \ 74 do { \ 75 const int iPrev = GetState.iNext; \ 76 const int rcGetOpt = (expr); \ 77 CHECK2(rcGetOpt == (chRet), ("got %d, expected %d\n", rcGetOpt, (chRet))); \ 78 CHECK2(GetState.iNext == (iInc) + iPrev, ("iNext=%d expected %d\n", GetState.iNext, (iInc) + iPrev)); \ 79 CHECK2(VALID_PTR(Val.psz) && !strcmp(Val.psz, (str)), ("got %s, expected %s\n", Val.psz, (str))); \ 80 GetState.iNext = (iInc) + iPrev; \ 81 } while (0) 82 73 83 74 84 /* 75 85 * The basics. 76 86 */ 87 RTTestSub(hTest, "Basics"); 77 88 static const RTGETOPTDEF s_aOpts2[] = 78 89 { … … 157 168 "--threevalues", "1", "0xC", "thirdvalue", 158 169 170 /* bool on/off */ 159 171 "--boolean", "on", 160 172 "--boolean", "off", … … 164 176 "--booleanindex9", "invalid", 165 177 178 /* standard options */ 179 "--help", 180 "-help", 181 "-?", 182 "-h", 183 "--version", 184 "-version", 185 "-V", 186 187 /* done */ 166 188 NULL 167 189 }; … … 240 262 241 263 /* IPv4 */ 264 RTTestSub(hTest, "RTGetOpt - IPv4"); 242 265 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'g', 1); 243 266 CHECK(Val.IPv4Addr.u == RT_H2N_U32_C(RT_BSWAP_U32_C(RT_MAKE_U32_FROM_U8(192,168,1,1)))); 244 267 245 268 /* Ethernet MAC address. */ 269 RTTestSub(hTest, "RTGetOpt - MAC Address"); 246 270 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'm', 1); 247 271 CHECK( Val.MacAddr.au8[0] == 0x08 … … 260 284 261 285 /* string with indexed argument */ 286 RTTestSub(hTest, "RTGetOpt - Option w/ Index"); 262 287 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2); 263 288 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string4")); … … 304 329 305 330 /* RTGetOptFetchValue tests */ 331 RTTestSub(hTest, "RTGetOptFetchValue"); 306 332 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 405, 2); 307 333 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "firstvalue")); … … 343 369 344 370 /* bool on/off tests */ 371 RTTestSub(hTest, "RTGetOpt - bool on/off"); 345 372 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 408, 2); 346 373 CHECK(Val.f); … … 360 387 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "invalid")); 361 388 389 /* standard options. */ 390 RTTestSub(hTest, "Standard options"); 391 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1); 392 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1); 393 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1); 394 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'h', 1); 395 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1); 396 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1); 397 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1); 398 362 399 /* the end */ 363 400 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0); … … 365 402 CHECK(argc2 == GetState.iNext); 366 403 404 /* 405 * Options first. 406 */ 407 RTTestSub(hTest, "Options first"); 408 const char *argv3[] = 409 { 410 "foo1", 411 "-s", "string1", 412 "foo2", 413 "--optwithstring", "string2", 414 "foo3", 415 "-i", "-42", 416 "foo4", 417 "-i:-42", 418 "-i=-42", 419 "foo5", 420 "foo6", 421 "foo7", 422 "-i:", "-42", 423 "-i=", "-42", 424 "foo8", 425 "--twovalues", "firstvalue", "secondvalue", 426 "foo9", 427 "--twovalues:firstvalue", "secondvalue", 428 "foo10", 429 "--", 430 "--optwithstring", 431 "foo11", 432 "foo12", 433 434 /* done */ 435 NULL 436 }; 437 int argc3 = (int)RT_ELEMENTS(argv3) - 1; 438 439 CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc3, (char **)argv3, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0, 440 RTGETOPTINIT_FLAGS_OPTS_FIRST))); 441 442 /* -s */ 443 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string1"); 444 CHECK(GetState.uIndex == UINT32_MAX); 445 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string2"); 446 CHECK(GetState.uIndex == UINT32_MAX); 447 448 /* -i */ 449 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); 450 CHECK(Val.i32 == -42); 451 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); 452 CHECK(Val.i32 == -42); 453 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); 454 CHECK(Val.i32 == -42); 455 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); 456 CHECK(Val.i32 == -42); 457 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); 458 CHECK(Val.i32 == -42); 459 460 /* --twovalues */ 461 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 2, "firstvalue"); 462 CHECK(GetState.uIndex == UINT32_MAX); 463 CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue"); 464 CHECK(GetState.uIndex == UINT32_MAX); 465 466 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 1, "firstvalue"); 467 CHECK(GetState.uIndex == UINT32_MAX); 468 CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue"); 469 CHECK(GetState.uIndex == UINT32_MAX); 470 471 /* -- */ 472 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 2, "foo1"); 473 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo2"); 474 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo3"); 475 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo4"); 476 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo5"); 477 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo6"); 478 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo7"); 479 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo8"); 480 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo9"); 481 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo10"); 482 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "--optwithstring"); 483 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo11"); 484 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo12"); 485 486 /* the end */ 487 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0); 488 CHECK(Val.pDef == NULL); 489 CHECK(argc3 == GetState.iNext); 490 491 /* 492 * Options first, part 2: No dash-dash. 493 */ 494 const char *argv4[] = 495 { 496 "foo1", 497 "-s", "string1", 498 "foo2", 499 "--optwithstring", "string2", 500 "foo3", 501 "-i", "-42", 502 "foo4", 503 "-i:-42", 504 "-i=-42", 505 "foo5", 506 "foo6", 507 "foo7", 508 "-i:", "-42", 509 "-i=", "-42", 510 "foo8", 511 "--twovalues", "firstvalue", "secondvalue", 512 "foo9", 513 "--twovalues:firstvalue", "secondvalue", 514 "foo10", 515 "foo11", 516 "foo12", 517 518 /* done */ 519 NULL 520 }; 521 int argc4 = (int)RT_ELEMENTS(argv4) - 1; 522 523 CHECK(RT_SUCCESS(RTGetOptInit(&GetState, argc4, (char **)argv4, &s_aOpts2[0], RT_ELEMENTS(s_aOpts2), 0, 524 RTGETOPTINIT_FLAGS_OPTS_FIRST))); 525 526 /* -s */ 527 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string1"); 528 CHECK(GetState.uIndex == UINT32_MAX); 529 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 's', 2, "string2"); 530 CHECK(GetState.uIndex == UINT32_MAX); 531 532 /* -i */ 533 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); 534 CHECK(Val.i32 == -42); 535 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); 536 CHECK(Val.i32 == -42); 537 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); 538 CHECK(Val.i32 == -42); 539 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); 540 CHECK(Val.i32 == -42); 541 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 2); 542 CHECK(Val.i32 == -42); 543 544 /* --twovalues */ 545 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 2, "firstvalue"); 546 CHECK(GetState.uIndex == UINT32_MAX); 547 CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue"); 548 CHECK(GetState.uIndex == UINT32_MAX); 549 550 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), 405, 1, "firstvalue"); 551 CHECK(GetState.uIndex == UINT32_MAX); 552 CHECK_GETOPT_STR(RTGetOptFetchValue(&GetState, &Val, RTGETOPT_REQ_STRING), VINF_SUCCESS, 1, "secondvalue"); 553 CHECK(GetState.uIndex == UINT32_MAX); 554 555 /* -- */ 556 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo1"); 557 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo2"); 558 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo3"); 559 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo4"); 560 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo5"); 561 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo6"); 562 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo7"); 563 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo8"); 564 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo9"); 565 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo10"); 566 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo11"); 567 CHECK_GETOPT_STR(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1, "foo12"); 568 569 /* the end */ 570 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0); 571 CHECK(Val.pDef == NULL); 572 CHECK(argc4 == GetState.iNext); 573 574 367 575 368 576 /* 369 577 * Summary. 370 578 */ 371 if (!cErrors) 372 RTPrintf("tstGetOpt: SUCCESS\n"); 373 else 374 RTPrintf("tstGetOpt: FAILURE - %d errors\n", cErrors); 375 376 return !!cErrors; 579 return RTTestSummaryAndDestroy(hTest); 377 580 } 378 581
Note:
See TracChangeset
for help on using the changeset viewer.