VirtualBox

Ignore:
Timestamp:
Oct 19, 2009 2:22:42 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
53639
Message:

RTGetOpt: Added RTGetOptFetchValue to fetch an additional value for an argument

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/getopt.cpp

    r23644 r23868  
    254254    }
    255255    return NULL;
     256}
     257
     258
     259/**
     260 * Value string -> Value union.
     261 *
     262 * @returns IPRT status code.
     263 * @param   fFlags              The value flags.
     264 * @param   pszValue            The value string.
     265 * @param   pValueUnion         Where to return the processed value.
     266 */
     267static int rtGetOptProcessValue(uint32_t fFlags, const char *pszValue, PRTGETOPTUNION pValueUnion)
     268{
     269    /*
     270     * Transform into a option value as requested.
     271     * If decimal conversion fails, we'll check for "0x<xdigit>" and
     272     * try a 16 based conversion. We will not interpret any of the
     273     * generic ints as octals.
     274     */
     275    switch (fFlags & (  RTGETOPT_REQ_MASK
     276                      | RTGETOPT_FLAG_HEX
     277                      | RTGETOPT_FLAG_DEC
     278                      | RTGETOPT_FLAG_OCT))
     279    {
     280        case RTGETOPT_REQ_STRING:
     281            pValueUnion->psz = pszValue;
     282            break;
     283
     284#define MY_INT_CASE(req,type,memb,convfn) \
     285            case req: \
     286            { \
     287                type Value; \
     288                if (    convfn(pszValue, 10, &Value) != VINF_SUCCESS \
     289                    &&  (   pszValue[0] != '0' \
     290                         || (pszValue[1] != 'x' && pszValue[1] != 'X') \
     291                         || !RT_C_IS_XDIGIT(pszValue[2]) \
     292                         || convfn(pszValue, 16, &Value) != VINF_SUCCESS ) ) \
     293                    return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
     294                pValueUnion->memb = Value; \
     295                break; \
     296            }
     297#define MY_BASE_INT_CASE(req,type,memb,convfn,base) \
     298            case req: \
     299            { \
     300                type Value; \
     301                if (convfn(pszValue, base, &Value) != VINF_SUCCESS) \
     302                    return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
     303                pValueUnion->memb = Value; \
     304                break; \
     305            }
     306
     307        MY_INT_CASE(RTGETOPT_REQ_INT8,   int8_t,   i,   RTStrToInt8Full)
     308        MY_INT_CASE(RTGETOPT_REQ_INT16,  int16_t,  i,   RTStrToInt16Full)
     309        MY_INT_CASE(RTGETOPT_REQ_INT32,  int32_t,  i,   RTStrToInt32Full)
     310        MY_INT_CASE(RTGETOPT_REQ_INT64,  int64_t,  i,   RTStrToInt64Full)
     311        MY_INT_CASE(RTGETOPT_REQ_UINT8,  uint8_t,  u,   RTStrToUInt8Full)
     312        MY_INT_CASE(RTGETOPT_REQ_UINT16, uint16_t, u,   RTStrToUInt16Full)
     313        MY_INT_CASE(RTGETOPT_REQ_UINT32, uint32_t, u,   RTStrToUInt32Full)
     314        MY_INT_CASE(RTGETOPT_REQ_UINT64, uint64_t, u,   RTStrToUInt64Full)
     315
     316        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_HEX, int8_t,   i,   RTStrToInt8Full,   16)
     317        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_HEX, int16_t,  i,   RTStrToInt16Full,  16)
     318        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_HEX, int32_t,  i,   RTStrToInt32Full,  16)
     319        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_HEX, int64_t,  i,   RTStrToInt64Full,  16)
     320        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_HEX, uint8_t,  u,   RTStrToUInt8Full,  16)
     321        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_HEX, uint16_t, u,   RTStrToUInt16Full, 16)
     322        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX, uint32_t, u,   RTStrToUInt32Full, 16)
     323        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX, uint64_t, u,   RTStrToUInt64Full, 16)
     324
     325        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_DEC, int8_t,   i,   RTStrToInt8Full,   10)
     326        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_DEC, int16_t,  i,   RTStrToInt16Full,  10)
     327        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_DEC, int32_t,  i,   RTStrToInt32Full,  10)
     328        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_DEC, int64_t,  i,   RTStrToInt64Full,  10)
     329        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_DEC, uint8_t,  u,   RTStrToUInt8Full,  10)
     330        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_DEC, uint16_t, u,   RTStrToUInt16Full, 10)
     331        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_DEC, uint32_t, u,   RTStrToUInt32Full, 10)
     332        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_DEC, uint64_t, u,   RTStrToUInt64Full, 10)
     333
     334        MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_OCT, int8_t,   i,   RTStrToInt8Full,   8)
     335        MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_OCT, int16_t,  i,   RTStrToInt16Full,  8)
     336        MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_OCT, int32_t,  i,   RTStrToInt32Full,  8)
     337        MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_OCT, int64_t,  i,   RTStrToInt64Full,  8)
     338        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_OCT, uint8_t,  u,   RTStrToUInt8Full,  8)
     339        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_OCT, uint16_t, u,   RTStrToUInt16Full, 8)
     340        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT, uint32_t, u,   RTStrToUInt32Full, 8)
     341        MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_OCT, uint64_t, u,   RTStrToUInt64Full, 8)
     342
     343#undef MY_INT_CASE
     344#undef MY_BASE_INT_CASE
     345
     346        case RTGETOPT_REQ_IPV4ADDR:
     347        {
     348            RTNETADDRIPV4 Addr;
     349            if (rtgetoptConvertIPv4Addr(pszValue, &Addr) != VINF_SUCCESS)
     350                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
     351            pValueUnion->IPv4Addr = Addr;
     352            break;
     353        }
     354#if 0  /** @todo CIDR */
     355#endif
     356
     357        case RTGETOPT_REQ_MACADDR:
     358        {
     359            RTMAC Addr;
     360            if (rtgetoptConvertMacAddr(pszValue, &Addr) != VINF_SUCCESS)
     361                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
     362            pValueUnion->MacAddr = Addr;
     363            break;
     364        }
     365
     366        case RTGETOPT_REQ_UUID:
     367        {
     368            RTUUID Uuid;
     369            if (RTUuidFromStr(&Uuid, pszValue) != VINF_SUCCESS)
     370                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
     371            pValueUnion->Uuid = Uuid;
     372            break;
     373        }
     374
     375        default:
     376            AssertMsgFailed(("f=%#x\n", fFlags));
     377            return VERR_INTERNAL_ERROR;
     378    }
     379
     380    return VINF_SUCCESS;
    256381}
    257382
     
    412537
    413538            /*
    414              * Transform into a option value as requested.
    415              * If decimal conversion fails, we'll check for "0x<xdigit>" and
    416              * try a 16 based conversion. We will not interpret any of the
    417              * generic ints as octals.
     539             * Set up the ValueUnion.
    418540             */
    419             switch (pOpt->fFlags & (  RTGETOPT_REQ_MASK
    420                                     | RTGETOPT_FLAG_HEX
    421                                     | RTGETOPT_FLAG_DEC
    422                                     | RTGETOPT_FLAG_OCT))
    423             {
    424                 case RTGETOPT_REQ_STRING:
    425                     pValueUnion->psz = pszValue;
    426                     break;
    427 
    428 #define MY_INT_CASE(req,type,memb,convfn) \
    429                     case req: \
    430                     { \
    431                         type Value; \
    432                         if (    convfn(pszValue, 10, &Value) != VINF_SUCCESS \
    433                             &&  (   pszValue[0] != '0' \
    434                                  || (pszValue[1] != 'x' && pszValue[1] != 'X') \
    435                                  || !RT_C_IS_XDIGIT(pszValue[2]) \
    436                                  || convfn(pszValue, 16, &Value) != VINF_SUCCESS ) ) \
    437                             return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
    438                         pValueUnion->memb = Value; \
    439                         break; \
    440                     }
    441 #define MY_BASE_INT_CASE(req,type,memb,convfn,base) \
    442                     case req: \
    443                     { \
    444                         type Value; \
    445                         if (convfn(pszValue, base, &Value) != VINF_SUCCESS) \
    446                             return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
    447                         pValueUnion->memb = Value; \
    448                         break; \
    449                     }
    450 
    451                 MY_INT_CASE(RTGETOPT_REQ_INT8,   int8_t,   i,   RTStrToInt8Full)
    452                 MY_INT_CASE(RTGETOPT_REQ_INT16,  int16_t,  i,   RTStrToInt16Full)
    453                 MY_INT_CASE(RTGETOPT_REQ_INT32,  int32_t,  i,   RTStrToInt32Full)
    454                 MY_INT_CASE(RTGETOPT_REQ_INT64,  int64_t,  i,   RTStrToInt64Full)
    455                 MY_INT_CASE(RTGETOPT_REQ_UINT8,  uint8_t,  u,   RTStrToUInt8Full)
    456                 MY_INT_CASE(RTGETOPT_REQ_UINT16, uint16_t, u,   RTStrToUInt16Full)
    457                 MY_INT_CASE(RTGETOPT_REQ_UINT32, uint32_t, u,   RTStrToUInt32Full)
    458                 MY_INT_CASE(RTGETOPT_REQ_UINT64, uint64_t, u,   RTStrToUInt64Full)
    459 
    460                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_HEX, int8_t,   i,   RTStrToInt8Full,   16)
    461                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_HEX, int16_t,  i,   RTStrToInt16Full,  16)
    462                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_HEX, int32_t,  i,   RTStrToInt32Full,  16)
    463                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_HEX, int64_t,  i,   RTStrToInt64Full,  16)
    464                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_HEX, uint8_t,  u,   RTStrToUInt8Full,  16)
    465                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_HEX, uint16_t, u,   RTStrToUInt16Full, 16)
    466                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX, uint32_t, u,   RTStrToUInt32Full, 16)
    467                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX, uint64_t, u,   RTStrToUInt64Full, 16)
    468 
    469                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_DEC, int8_t,   i,   RTStrToInt8Full,   10)
    470                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_DEC, int16_t,  i,   RTStrToInt16Full,  10)
    471                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_DEC, int32_t,  i,   RTStrToInt32Full,  10)
    472                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_DEC, int64_t,  i,   RTStrToInt64Full,  10)
    473                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_DEC, uint8_t,  u,   RTStrToUInt8Full,  10)
    474                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_DEC, uint16_t, u,   RTStrToUInt16Full, 10)
    475                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_DEC, uint32_t, u,   RTStrToUInt32Full, 10)
    476                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_DEC, uint64_t, u,   RTStrToUInt64Full, 10)
    477 
    478                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_OCT, int8_t,   i,   RTStrToInt8Full,   8)
    479                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_OCT, int16_t,  i,   RTStrToInt16Full,  8)
    480                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_OCT, int32_t,  i,   RTStrToInt32Full,  8)
    481                 MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_OCT, int64_t,  i,   RTStrToInt64Full,  8)
    482                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_OCT, uint8_t,  u,   RTStrToUInt8Full,  8)
    483                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_OCT, uint16_t, u,   RTStrToUInt16Full, 8)
    484                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT, uint32_t, u,   RTStrToUInt32Full, 8)
    485                 MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_OCT, uint64_t, u,   RTStrToUInt64Full, 8)
    486 
    487 #undef MY_INT_CASE
    488 #undef MY_BASE_INT_CASE
    489 
    490                 case RTGETOPT_REQ_IPV4ADDR:
    491                 {
    492                     RTNETADDRIPV4 Addr;
    493                     if (rtgetoptConvertIPv4Addr(pszValue, &Addr) != VINF_SUCCESS)
    494                         return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
    495                     pValueUnion->IPv4Addr = Addr;
    496                     break;
    497                 }
    498 #if 0  /** @todo CIDR */
    499 #endif
    500 
    501                 case RTGETOPT_REQ_MACADDR:
    502                 {
    503                     RTMAC Addr;
    504                     if (rtgetoptConvertMacAddr(pszValue, &Addr) != VINF_SUCCESS)
    505                         return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
    506                     pValueUnion->MacAddr = Addr;
    507                     break;
    508                 }
    509 
    510                 case RTGETOPT_REQ_UUID:
    511                 {
    512                     RTUUID Uuid;
    513                     if (RTUuidFromStr(&Uuid, pszValue) != VINF_SUCCESS)
    514                         return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
    515                     pValueUnion->Uuid = Uuid;
    516                     break;
    517                 }
    518 
    519                 default:
    520                     AssertMsgFailed(("i=%d f=%#x\n", pOpt - &pState->paOptions[0], pOpt->fFlags));
    521                     return VERR_INTERNAL_ERROR;
    522             }
     541            int rc = rtGetOptProcessValue(pOpt->fFlags, pszValue, pValueUnion);
     542            if (RT_FAILURE(rc))
     543                return rc;
    523544        }
    524545        else if (fShort)
     
    578599RT_EXPORT_SYMBOL(RTGetOpt);
    579600
     601
     602RTDECL(int) RTGetOptFetchValue(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion, uint32_t fFlags)
     603{
     604    /*
     605     * Validate input.
     606     */
     607    PCRTGETOPTDEF pOpt = pState->pDef;
     608    AssertReturn(pOpt, VERR_GETOPT_UNKNOWN_OPTION);
     609    AssertReturn(!(fFlags & ~RTGETOPT_VALID_MASK), VERR_INVALID_PARAMETER);
     610    AssertReturn((fFlags & RTGETOPT_REQ_MASK) != RTGETOPT_REQ_NOTHING, VERR_INVALID_PARAMETER);
     611
     612    /*
     613     * Make sure the union is completely cleared out, whatever happens below.
     614     */
     615    pValueUnion->u64 = 0;
     616    pValueUnion->pDef = NULL;
     617
     618    /*
     619     * Pop off the next argument and convert it into a value union.
     620     */
     621    if (pState->iNext >= pState->argc)
     622        return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
     623    int         iThis    = pState->iNext++;
     624    const char *pszValue = pState->argv[iThis];
     625    pValueUnion->pDef    = pOpt; /* in case of no value or error. */
     626
     627    return rtGetOptProcessValue(fFlags, pszValue, pValueUnion);
     628}
     629RT_EXPORT_SYMBOL(RTGetOptFetchValue);
Note: See TracChangeset for help on using the changeset viewer.

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