- Timestamp:
- Feb 25, 2009 5:09:22 PM (16 years ago)
- Location:
- trunk
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/getopt.h
r17096 r17141 166 166 /** Number of items in paOptions. */ 167 167 size_t cOptions; 168 /** The next short option. 169 * (For parsing ls -latrT4 kind of option lists.) */ 170 const char *pszNextShort; 168 171 /* More members will be added later for dealing with initial 169 172 call, optional sorting, '--' and so on. */ -
trunk/src/VBox/Runtime/common/misc/getopt.cpp
r17101 r17141 46 46 AssertReturn(!fFlags, VERR_INVALID_PARAMETER); 47 47 48 pState->argv = argv; 49 pState->argc = argc; 50 pState->paOptions = paOptions; 51 pState->cOptions = cOptions; 52 pState->iNext = iFirst; 48 pState->argv = argv; 49 pState->argc = argc; 50 pState->paOptions = paOptions; 51 pState->cOptions = cOptions; 52 pState->iNext = iFirst; 53 pState->pszNextShort = NULL; 53 54 54 55 /* validate the options. */ … … 127 128 RTDECL(int) RTGetOpt(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion) 128 129 { 130 /* 131 * Make sure the union is completely cleared out, whatever happens below. 132 */ 129 133 pValueUnion->u64 = 0; 130 134 pValueUnion->pDef = NULL; 131 135 132 if (pState->iNext >= pState->argc) 133 return 0; 136 /* 137 * The next option. 138 */ 139 bool fShort; 140 int iThis; 141 const char *pszArgThis; 142 PCRTGETOPTDEF pOpt; 143 144 if (pState->pszNextShort) 145 { 146 /* 147 * We've got short options left over from the previous call. 148 */ 149 pOpt = rtGetOptSearchShort(*pState->pszNextShort, pState->paOptions, pState->cOptions); 150 if (!pOpt) 151 { 152 pValueUnion->psz = pState->pszNextShort; 153 return VERR_GETOPT_UNKNOWN_OPTION; 154 } 155 pState->pszNextShort++; 156 pszArgThis = pState->pszNextShort - 2; 157 iThis = pState->iNext; 158 fShort = true; 159 } 160 else 161 { 162 /* 163 * Pop off the next argument. 164 */ 165 if (pState->iNext >= pState->argc) 166 return 0; 167 iThis = pState->iNext++; 168 pszArgThis = pState->argv[iThis]; 169 170 /* 171 * Do a long option search first and the a short option one. 172 * This way we can make sure single dash long options doesn't 173 * get mixed up with short ones. 174 */ 175 pOpt = rtGetOptSearchLong(pszArgThis, pState->paOptions, pState->cOptions); 176 if ( !pOpt 177 && pszArgThis[0] == '-' 178 && pszArgThis[1] != '-' 179 && pszArgThis[1] != '\0') 180 { 181 pOpt = rtGetOptSearchShort(pszArgThis[1], pState->paOptions, pState->cOptions); 182 fShort = pOpt != NULL; 183 } 184 else 185 fShort = false; 186 } 187 134 188 135 189 /** @todo Handle '--' and possibly implement an RTGetOptInit that lets us … … 140 194 */ 141 195 142 /*143 * Pop off the next argument.144 */145 int iThis = pState->iNext++;146 const char *pszArgThis = pState->argv[iThis];147 148 /*149 * Do a long option search first and the a short option one.150 * This way we can make sure single dash long options doesn't151 * get mixed up with short ones.152 */153 bool fShort = false;154 PCRTGETOPTDEF pOpt = rtGetOptSearchLong(pszArgThis, pState->paOptions, pState->cOptions);155 if ( !pOpt156 && pszArgThis[0] == '-'157 && pszArgThis[1] != '-'158 && pszArgThis[1] != '\0')159 {160 pOpt = rtGetOptSearchShort(pszArgThis[1], pState->paOptions, pState->cOptions);161 fShort = pOpt != NULL;162 }163 196 if (pOpt) 164 197 { … … 191 224 else /* same argument. */ 192 225 pszValue = &pszArgThis[2 + (pszArgThis[2] == ':' || pszArgThis[2] == '=')]; 226 if (pState->pszNextShort) 227 { 228 pState->pszNextShort = NULL; 229 pState->iNext++; 230 } 193 231 } 194 232 else … … 285 323 } 286 324 } 325 else if (fShort) 326 { 327 /* 328 * Deal with "compressed" short option lists, correcting the next 329 * state variables for the start and end cases. 330 */ 331 if (pszArgThis[2]) 332 { 333 if (!pState->pszNextShort) 334 { 335 /* start */ 336 pState->pszNextShort = &pszArgThis[2]; 337 pState->iNext--; 338 } 339 } 340 else if (pState->pszNextShort) 341 { 342 /* end */ 343 pState->pszNextShort = NULL; 344 pState->iNext++; 345 } 346 } 347 287 348 return pOpt->iShort; 288 349 } … … 294 355 295 356 if (*pszArgThis == '-') 357 { 358 pValueUnion->psz = pszArgThis; 296 359 return VERR_GETOPT_UNKNOWN_OPTION; 360 } 297 361 298 362 pValueUnion->psz = pszArgThis; -
trunk/src/VBox/Runtime/testcase/tstGetOpt.cpp
r17100 r17141 41 41 int cErrors = 0; 42 42 RTR3Init(); 43 RTPrintf("tstGetOpt: TESTING...\n"); 43 44 44 45 RTGETOPTSTATE GetState; 45 46 RTGETOPTUNION Val; 46 47 #define CHECK(expr) do { if (!(expr)) { RTPrintf("tstGetOpt: error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); cErrors++; } } while (0) 48 #define CHECK2(expr, fmt) \ 49 do { \ 50 if (!(expr)) { \ 51 RTPrintf("tstGetOpt: error line %d (iNext=%d): %s\n", __LINE__, GetState.iNext, #expr); \ 52 RTPrintf fmt; \ 53 cErrors++; \ 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)); 47 59 48 60 #define CHECK_GETOPT(expr, chRet, iInc) \ 49 61 do { \ 50 62 const int iPrev = GetState.iNext; \ 51 CHECK((expr) == (chRet)); \ 52 CHECK(GetState.iNext == (iInc) + iPrev); \ 63 const int rc = (expr); \ 64 CHECK2(rc == (chRet), ("got %d, expected %d\n", rc, (chRet))); \ 65 CHECK2(GetState.iNext == (iInc) + iPrev, ("iNext=%d expected %d\n", GetState.iNext, (iInc) + iPrev)); \ 53 66 GetState.iNext = (iInc) + iPrev; \ 54 67 } while (0) 55 68 69 70 56 71 /* 57 * Simple.72 * The basics. 58 73 */ 59 74 static const RTGETOPTDEF s_aOpts2[] = … … 64 79 { NULL, 'q', RTGETOPT_REQ_NOTHING }, 65 80 { "--quiet", 384, RTGETOPT_REQ_NOTHING }, 66 { "-startvm", 385, RTGETOPT_REQ_NOTHING }, 81 { "-novalue", 385, RTGETOPT_REQ_NOTHING }, 82 { "-startvm", 386, RTGETOPT_REQ_STRING }, 83 { "nodash", 387, RTGETOPT_REQ_NOTHING }, 84 { "nodashval", 388, RTGETOPT_REQ_STRING }, 67 85 }; 68 86 … … 71 89 "-s", "string1", 72 90 "--optwithstring", "string2", 91 73 92 "-i", "-42", 74 93 "-i:-42", … … 76 95 "-i:", "-42", 77 96 "-i=", "-42", 97 78 98 "--optwithint", "42", 79 99 "--optwithint:42", … … 81 101 "--optwithint:", "42", 82 102 "--optwithint=", "42", 103 83 104 "-v", 84 105 "--verbose", 85 106 "-q", 86 107 "--quiet", 87 "-startvm", 108 109 "-novalue", 110 "-startvm", "myvm", 111 112 "nodash", 113 "nodashval", "string3", 114 88 115 "filename1", 89 116 "-q", 90 117 "filename2", 118 119 "-vqi999", 91 120 NULL 92 121 }; … … 125 154 126 155 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 1); 127 CHECK (Val.pDef == &s_aOpts2[2]);156 CHECK_pDef(s_aOpts2, 2); 128 157 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 1); 129 CHECK(Val.pDef == &s_aOpts2[2]); 158 CHECK_pDef(s_aOpts2, 2); 159 130 160 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 1); 131 CHECK (Val.pDef == &s_aOpts2[3]);161 CHECK_pDef(s_aOpts2, 3); 132 162 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 384, 1); 133 CHECK(Val.pDef == &s_aOpts2[4]); 163 CHECK_pDef(s_aOpts2, 4); 164 165 /* -novalue / -startvm (single dash long options) */ 134 166 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 385, 1); 135 CHECK(Val.pDef == &s_aOpts2[5]); 136 167 CHECK_pDef(s_aOpts2, 5); 168 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 386, 2); 169 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "myvm")); 170 171 /* no-dash options */ 172 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 387, 1); 173 CHECK_pDef(s_aOpts2, 7); 174 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 388, 2); 175 CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string3")); 176 177 /* non-option, option, non-option */ 137 178 CHECK_GETOPT(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1); 138 179 CHECK(Val.psz && !strcmp(Val.psz, "filename1")); 139 180 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 1); 140 CHECK (Val.pDef == &s_aOpts2[3]);181 CHECK_pDef(s_aOpts2, 3); 141 182 CHECK_GETOPT(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1); 142 183 CHECK(Val.psz && !strcmp(Val.psz, "filename2")); 143 184 185 /* compress short options */ 186 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'v', 0); 187 CHECK_pDef(s_aOpts2, 2); 188 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 0); 189 CHECK_pDef(s_aOpts2, 3); 190 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'i', 1); 191 CHECK(Val.i32 == 999); 192 193 /* the end */ 144 194 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0); 145 195 CHECK(Val.pDef == NULL);
Note:
See TracChangeset
for help on using the changeset viewer.