儲存庫 vbox 的更動 17100
- 時間撮記:
- 2009-2-24 下午09:37:20 (16 年 以前)
- 位置:
- trunk/src/VBox/Runtime
- 檔案:
-
- 修改 2 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/Runtime/common/misc/getopt.cpp
r17093 r17100 52 52 pState->iNext = iFirst; 53 53 54 /* validate the options. */ 55 for (size_t i = 0; i < cOptions; i++) 56 { 57 Assert(!(paOptions[i].fFlags & ~RTGETOPT_VALID_MASK)); 58 Assert(paOptions[i].iShort > 0); 59 Assert(paOptions[i].iShort != VINF_GETOPT_NOT_OPTION); 60 Assert(paOptions[i].iShort != '-'); 61 } 62 54 63 return VINF_SUCCESS; 64 } 65 66 67 /** 68 * Searches for a long option. 69 * 70 * @returns Pointer to a matching option. 71 * @param pszOption The alleged long option. 72 * @param paOptions Option array. 73 * @param cOptions Number of items in the array. 74 */ 75 static PCRTGETOPTDEF rtGetOptSearchLong(const char *pszOption, PCRTGETOPTDEF paOptions, size_t cOptions) 76 { 77 PCRTGETOPTDEF pOpt = paOptions; 78 while (cOptions-- > 0) 79 { 80 if (pOpt->pszLong) 81 { 82 if ((pOpt->fFlags & RTGETOPT_REQ_MASK) != RTGETOPT_REQ_NOTHING) 83 { 84 /* 85 * A value is required with the argument. We're trying to be very 86 * understanding here and will permit any of the following: 87 * -svalue, -s:value, -s=value, 88 * -s value, -s: value, -s= value 89 * (Ditto for long options.) 90 */ 91 size_t cchLong = strlen(pOpt->pszLong); 92 if ( !strncmp(pszOption, pOpt->pszLong, cchLong) 93 && ( pszOption[cchLong] == '\0' 94 || pszOption[cchLong] == ':' 95 || pszOption[cchLong] == '=')) 96 return pOpt; 97 } 98 else if (!strcmp(pszOption, pOpt->pszLong)) 99 return pOpt; 100 } 101 pOpt++; 102 } 103 return NULL; 104 } 105 106 107 /** 108 * Searches for a matching short option. 109 * 110 * @returns Pointer to a matching option. 111 * @param chOption The option char. 112 * @param paOptions Option array. 113 * @param cOptions Number of items in the array. 114 */ 115 static PCRTGETOPTDEF rtGetOptSearchShort(int chOption, PCRTGETOPTDEF paOptions, size_t cOptions) 116 { 117 PCRTGETOPTDEF pOpt = paOptions; 118 while (cOptions-- > 0) 119 { 120 if (pOpt->iShort == chOption) 121 return pOpt; 122 pOpt++; 123 } 124 return NULL; 55 125 } 56 126 … … 64 134 return 0; 65 135 136 /** @todo Handle '--' and possibly implement an RTGetOptInit that lets us 137 * optionally sort the stuff and set other policeis sorts the result. */ 138 /** @todo Implement short form short option like in: 139 * ls -latr . 140 * tar -xzvf foobar.tar.gz 141 */ 142 143 /* 144 * Pop off the next argument. 145 */ 66 146 int iThis = pState->iNext++; 67 147 const char *pszArgThis = pState->argv[iThis]; 68 size_t const cOptions = pState->cOptions; 69 PCRTGETOPTDEF paOptions = pState->paOptions; 70 71 for (size_t i = 0; i < cOptions; i++) 72 { 73 Assert(!(paOptions[i].fFlags & ~RTGETOPT_VALID_MASK)); 74 Assert(paOptions[i].iShort > 0); 75 Assert(paOptions[i].iShort != VINF_GETOPT_NOT_OPTION); 76 77 bool fShort = *pszArgThis == '-' 78 && pszArgThis[1] == paOptions[i].iShort; 79 80 if ((paOptions[i].fFlags & RTGETOPT_REQ_MASK) != RTGETOPT_REQ_NOTHING) 148 149 /* 150 * Do a long option search first and the a short option one. 151 * This way we can make sure single dash long options doesn't 152 * get mixed up with short ones. 153 */ 154 bool fShort = false; 155 PCRTGETOPTDEF pOpt = rtGetOptSearchLong(pszArgThis, pState->paOptions, pState->cOptions); 156 if ( !pOpt 157 && pszArgThis[0] == '-' 158 && pszArgThis[1] != '-' 159 && pszArgThis[1] != '\0') 160 { 161 pOpt = rtGetOptSearchShort(pszArgThis[1], pState->paOptions, pState->cOptions); 162 fShort = pOpt != NULL; 163 } 164 if (pOpt) 165 { 166 pValueUnion->pDef = pOpt; /* in case of no value or error. */ 167 168 if ((pOpt->fFlags & RTGETOPT_REQ_MASK) != RTGETOPT_REQ_NOTHING) 81 169 { 82 170 /* 171 * Find the argument value. 172 * 83 173 * A value is required with the argument. We're trying to be very 84 174 * understanding here and will permit any of the following: … … 87 177 * (Ditto for long options.) 88 178 */ 89 size_t cchLong = 2; 90 if ( ( paOptions[i].pszLong 91 && !strncmp(pszArgThis, paOptions[i].pszLong, (cchLong = strlen(paOptions[i].pszLong))) 92 && ( pszArgThis[cchLong] == '\0' 93 || pszArgThis[cchLong] == ':' 94 || pszArgThis[cchLong] == '=') 95 ) 96 || fShort 97 ) 179 const char *pszValue; 180 if (fShort) 98 181 { 99 pValueUnion->pDef = &paOptions[i]; /* in case of error. */ 100 101 /* 102 * Find the argument value 103 */ 104 const char *pszValue; 105 if ( fShort 106 ? pszArgThis[2] == '\0' 107 || ((pszArgThis[2] == ':' || pszArgThis[2] == '=') && pszArgThis[3] == '\0') 108 : pszArgThis[cchLong] == '\0' || pszArgThis[cchLong + 1] == '\0') 182 if ( pszArgThis[2] == '\0' 183 || ( pszArgThis[3] == '\0' 184 && ( pszArgThis[2] == ':' 185 || pszArgThis[2] == '=')) ) 109 186 { 110 187 if (iThis + 1 >= pState->argc) … … 114 191 } 115 192 else /* same argument. */ 116 pszValue = fShort 117 ? &pszArgThis[2 + (pszArgThis[2] == ':' || pszArgThis[2] == '=')] 118 : &pszArgThis[cchLong + 1]; 119 120 /* 121 * Transform into a option value as requested. 122 * If decimal conversion fails, we'll check for "0x<xdigit>" and 123 * try a 16 based conversion. We will not interpret any of the 124 * generic ints as octals. 125 */ 126 switch (paOptions[i].fFlags & (RTGETOPT_REQ_MASK | RTGETOPT_FLAG_HEX | RTGETOPT_FLAG_OCT | RTGETOPT_FLAG_DEC)) 193 pszValue = &pszArgThis[2 + (pszArgThis[2] == ':' || pszArgThis[2] == '=')]; 194 } 195 else 196 { 197 size_t cchLong = strlen(pOpt->pszLong); 198 if ( pszArgThis[cchLong] == '\0' 199 || pszArgThis[cchLong + 1] == '\0') 127 200 { 128 case RTGETOPT_REQ_STRING: 129 pValueUnion->psz = pszValue; 130 break; 201 if (iThis + 1 >= pState->argc) 202 return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING; 203 pszValue = pState->argv[iThis + 1]; 204 pState->iNext++; 205 } 206 else /* same argument. */ 207 pszValue = &pszArgThis[cchLong + 1]; 208 } 209 210 /* 211 * Transform into a option value as requested. 212 * If decimal conversion fails, we'll check for "0x<xdigit>" and 213 * try a 16 based conversion. We will not interpret any of the 214 * generic ints as octals. 215 */ 216 switch (pOpt->fFlags & (RTGETOPT_REQ_MASK | RTGETOPT_FLAG_HEX | RTGETOPT_FLAG_OCT | RTGETOPT_FLAG_DEC)) 217 { 218 case RTGETOPT_REQ_STRING: 219 pValueUnion->psz = pszValue; 220 break; 131 221 132 222 #define MY_INT_CASE(req,type,memb,convfn) \ 133 134 135 136 137 138 139 140 141 142 143 144 223 case req: \ 224 { \ 225 type Value; \ 226 if ( convfn(pszValue, 10, &Value) != VINF_SUCCESS \ 227 && ( pszValue[0] != '0' \ 228 || (pszValue[1] != 'x' && pszValue[1] != 'X') \ 229 || !RT_C_IS_XDIGIT(pszValue[2]) \ 230 || convfn(pszValue, 16, &Value) != VINF_SUCCESS ) ) \ 231 return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \ 232 pValueUnion->memb = Value; \ 233 break; \ 234 } 145 235 #define MY_BASE_INT_CASE(req,type,memb,convfn,base) \ 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 236 case req: \ 237 { \ 238 type Value; \ 239 if (convfn(pszValue, base, &Value) != VINF_SUCCESS) \ 240 return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \ 241 pValueUnion->memb = Value; \ 242 break; \ 243 } 244 245 MY_INT_CASE(RTGETOPT_REQ_INT8, int8_t, i, RTStrToInt8Full) 246 MY_INT_CASE(RTGETOPT_REQ_INT16, int16_t, i, RTStrToInt16Full) 247 MY_INT_CASE(RTGETOPT_REQ_INT32, int32_t, i, RTStrToInt32Full) 248 MY_INT_CASE(RTGETOPT_REQ_INT64, int64_t, i, RTStrToInt64Full) 249 MY_INT_CASE(RTGETOPT_REQ_UINT8, uint8_t, u, RTStrToUInt8Full) 250 MY_INT_CASE(RTGETOPT_REQ_UINT16, uint16_t, u, RTStrToUInt16Full) 251 MY_INT_CASE(RTGETOPT_REQ_UINT32, uint32_t, u, RTStrToUInt32Full) 252 MY_INT_CASE(RTGETOPT_REQ_UINT64, uint64_t, u, RTStrToUInt64Full) 253 254 MY_BASE_INT_CASE(RTGETOPT_REQ_INT8 | RTGETOPT_FLAG_HEX, int8_t, i, RTStrToInt8Full, 16) 255 MY_BASE_INT_CASE(RTGETOPT_REQ_INT16 | RTGETOPT_FLAG_HEX, int16_t, i, RTStrToInt16Full, 16) 256 MY_BASE_INT_CASE(RTGETOPT_REQ_INT32 | RTGETOPT_FLAG_HEX, int32_t, i, RTStrToInt32Full, 16) 257 MY_BASE_INT_CASE(RTGETOPT_REQ_INT64 | RTGETOPT_FLAG_HEX, int64_t, i, RTStrToInt64Full, 16) 258 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8 | RTGETOPT_FLAG_HEX, uint8_t, u, RTStrToUInt8Full, 16) 259 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_HEX, uint16_t, u, RTStrToUInt16Full, 16) 260 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX, uint32_t, u, RTStrToUInt32Full, 16) 261 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX, uint64_t, u, RTStrToUInt64Full, 16) 262 263 MY_BASE_INT_CASE(RTGETOPT_REQ_INT8 | RTGETOPT_FLAG_DEC, int8_t, i, RTStrToInt8Full, 10) 264 MY_BASE_INT_CASE(RTGETOPT_REQ_INT16 | RTGETOPT_FLAG_DEC, int16_t, i, RTStrToInt16Full, 10) 265 MY_BASE_INT_CASE(RTGETOPT_REQ_INT32 | RTGETOPT_FLAG_DEC, int32_t, i, RTStrToInt32Full, 10) 266 MY_BASE_INT_CASE(RTGETOPT_REQ_INT64 | RTGETOPT_FLAG_DEC, int64_t, i, RTStrToInt64Full, 10) 267 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8 | RTGETOPT_FLAG_DEC, uint8_t, u, RTStrToUInt8Full, 10) 268 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_DEC, uint16_t, u, RTStrToUInt16Full, 10) 269 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_DEC, uint32_t, u, RTStrToUInt32Full, 10) 270 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_DEC, uint64_t, u, RTStrToUInt64Full, 10) 271 272 MY_BASE_INT_CASE(RTGETOPT_REQ_INT8 | RTGETOPT_FLAG_OCT, int8_t, i, RTStrToInt8Full, 8) 273 MY_BASE_INT_CASE(RTGETOPT_REQ_INT16 | RTGETOPT_FLAG_OCT, int16_t, i, RTStrToInt16Full, 8) 274 MY_BASE_INT_CASE(RTGETOPT_REQ_INT32 | RTGETOPT_FLAG_OCT, int32_t, i, RTStrToInt32Full, 8) 275 MY_BASE_INT_CASE(RTGETOPT_REQ_INT64 | RTGETOPT_FLAG_OCT, int64_t, i, RTStrToInt64Full, 8) 276 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8 | RTGETOPT_FLAG_OCT, uint8_t, u, RTStrToUInt8Full, 8) 277 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_OCT, uint16_t, u, RTStrToUInt16Full, 8) 278 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT, uint32_t, u, RTStrToUInt32Full, 8) 279 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_OCT, uint64_t, u, RTStrToUInt64Full, 8) 190 280 #undef MY_INT_CASE 191 281 #undef MY_BASE_INT_CASE 192 282 193 default: 194 AssertMsgFailed(("i=%d f=%#x\n", i, paOptions[i].fFlags)); 195 return VERR_INTERNAL_ERROR; 196 } 197 return paOptions[i].iShort; 283 default: 284 AssertMsgFailed(("i=%d f=%#x\n", pOpt - &pState->paOptions[0], pOpt->fFlags)); 285 return VERR_INTERNAL_ERROR; 198 286 } 199 287 } 200 else if ( ( paOptions[i].pszLong 201 && !strcmp(pszArgThis, paOptions[i].pszLong)) 202 || ( fShort 203 && pszArgThis[2] == '\0') /** @todo implement support for ls -lsR like stuff? */ 204 ) 205 { 206 pValueUnion->pDef = &paOptions[i]; 207 return paOptions[i].iShort; 208 } 209 } 210 211 /* Option or not? */ 288 return pOpt->iShort; 289 } 290 291 /* 292 * Not a known option argument. If it starts with a switch char (-) we'll 293 * fail with unkown option, and if it doesn't we'll return it as a non-option. 294 */ 295 212 296 if (*pszArgThis == '-') 213 297 return VERR_GETOPT_UNKNOWN_OPTION; 214 298 215 /** @todo Handle '--' and possibly implement an RTGetOptInit that lets us216 * optionally sort the stuff and set other policeis sorts the result. */217 218 /*219 * Not an option.220 */221 299 pValueUnion->psz = pszArgThis; 222 300 return VINF_GETOPT_NOT_OPTION; -
trunk/src/VBox/Runtime/testcase/tstGetOpt.cpp
r17093 r17100 64 64 { NULL, 'q', RTGETOPT_REQ_NOTHING }, 65 65 { "--quiet", 384, RTGETOPT_REQ_NOTHING }, 66 { "- quiet2",385, RTGETOPT_REQ_NOTHING },66 { "-startvm", 385, RTGETOPT_REQ_NOTHING }, 67 67 }; 68 68 … … 85 85 "-q", 86 86 "--quiet", 87 "-quiet2", 88 /* "filename1", */ 89 /* "filename2", */ 87 "-startvm", 88 "filename1", 89 "-q", 90 "filename2", 90 91 NULL 91 92 }; … … 133 134 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 385, 1); 134 135 CHECK(Val.pDef == &s_aOpts2[5]); 136 137 CHECK_GETOPT(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1); 138 CHECK(Val.psz && !strcmp(Val.psz, "filename1")); 139 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'q', 1); 140 CHECK(Val.pDef == &s_aOpts2[3]); 141 CHECK_GETOPT(RTGetOpt(&GetState, &Val), VINF_GETOPT_NOT_OPTION, 1); 142 CHECK(Val.psz && !strcmp(Val.psz, "filename2")); 143 135 144 CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0); 136 145 CHECK(Val.pDef == NULL); … … 148 157 return !!cErrors; 149 158 } 159
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器