VirtualBox

Changeset 68936 in vbox


Ignore:
Timestamp:
Sep 29, 2017 4:11:06 PM (7 years ago)
Author:
vboxsync
Message:

IPRT/RTGetOpt: Added 32-bit and 64-bit pair types.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/getopt.h

    r67598 r68936  
    9494 * expression true and false. */
    9595#define RTGETOPT_REQ_BOOL                       17
     96/** The value must two unsigned 32-bit integer values separated by a colon,
     97 * slash, pipe or space(s).  */
     98#define RTGETOPT_REQ_UINT32_PAIR                18
     99/** The value must two unsigned 64-bit integer values separated by a colon,
     100 * slash, pipe or space(s). */
     101#define RTGETOPT_REQ_UINT64_PAIR                19
     102/** The value must at least unsigned 32-bit integer value, optionally
     103 * followed by a second separated by a colon, slash, pipe or space(s). */
     104#define RTGETOPT_REQ_UINT32_OPTIONAL_PAIR       20
     105/** The value must at least unsigned 64-bit integer value, optionally
     106 * followed by a second separated by a colon, slash, pipe or space(s). */
     107#define RTGETOPT_REQ_UINT64_OPTIONAL_PAIR       21
    96108/** The mask of the valid required types. */
    97109#define RTGETOPT_REQ_MASK                       31
     
    185197    /** A boolean flag. */
    186198    bool            f;
     199    /** A RTGETOPT_REQ_UINT32_PAIR or RTGETOPT_REQ_UINT32_OPTIONAL_PAIR option
     200     *  argument. */
     201    struct
     202    {
     203        uint32_t    uFirst;
     204        uint32_t    uSecond; /**< Set to UINT32_MAX if optional and not present. */
     205    } PairU32;
     206    /** A RTGETOPT_REQ_UINT64_COLON_PAIR option argument. */
     207    struct
     208    {
     209        uint64_t    uFirst;
     210        uint64_t    uSecond; /**< Set to UINT64_MAX if optional and not present. */
     211    } PairU64;
    187212} RTGETOPTUNION;
    188213/** Pointer to an option argument union. */
  • trunk/src/VBox/Runtime/common/misc/getopt.cpp

    r64602 r68936  
    254254     * generic ints as octals.
    255255     */
    256     switch (fFlags & (  RTGETOPT_REQ_MASK
    257                       | RTGETOPT_FLAG_HEX
    258                       | RTGETOPT_FLAG_DEC
    259                       | RTGETOPT_FLAG_OCT))
     256    uint32_t const fSwitchValue =  fFlags & (  RTGETOPT_REQ_MASK
     257                                             | RTGETOPT_FLAG_HEX
     258                                             | RTGETOPT_FLAG_DEC
     259                                             | RTGETOPT_FLAG_OCT);
     260    switch (fSwitchValue)
    260261    {
    261262        case RTGETOPT_REQ_STRING:
     
    407408        }
    408409
     410#define MY_INT_PAIR_CASE(a_fReqValue, a_fReqValueOptional, a_Type, a_MemberPrefix, a_fnConv, a_ConvBase, a_DefaultValue) \
     411            case a_fReqValue: \
     412            case a_fReqValueOptional: \
     413            { \
     414                /* First value: */ \
     415                a_Type Value1; \
     416                char *pszNext = NULL; \
     417                unsigned uBase =   pszValue[0] == '0' \
     418                                && (pszValue[1] == 'x' || pszValue[1] == 'X') \
     419                                && RT_C_IS_XDIGIT(pszValue[2]) \
     420                              ? 16 : a_ConvBase; \
     421                int rc = a_fnConv(pszValue, &pszNext, uBase, &Value1); \
     422                if (rc == VINF_SUCCESS || rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES) \
     423                { \
     424                    /* The second value, could be optional: */ \
     425                    a_Type Value2 = a_DefaultValue; \
     426                    pszValue = pszNext;\
     427                    if (pszValue) \
     428                    { \
     429                        while (RT_C_IS_BLANK(*pszValue)) \
     430                            pszValue++; \
     431                        if (*pszValue == ':' || *pszValue == '/' || *pszValue == '|') \
     432                            do pszValue++; \
     433                            while (RT_C_IS_BLANK(*pszValue)); \
     434                        if (pszValue != pszNext) \
     435                        { \
     436                            unsigned uBase =    pszValue[0] == '0' \
     437                                             && (pszValue[1] == 'x' || pszValue[1] == 'X') \
     438                                             && RT_C_IS_XDIGIT(pszValue[2]) \
     439                                           ? 16 : a_ConvBase; \
     440                            rc = a_fnConv(pszValue, &pszNext, uBase, &Value2); \
     441                            if (rc == VINF_SUCCESS) \
     442                            { /* likely */ } \
     443                            else \
     444                               { RTAssertMsg2("z rc=%Rrc: '%s' '%s' uBase=%d\n", rc, pszValue, pszNext, uBase); return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; } \
     445                        } \
     446                        else if (fSwitchValue != (a_fReqValueOptional)) \
     447                        { RTAssertMsg2("x\n"); return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; } \
     448                    } \
     449                    else if (fSwitchValue != (a_fReqValueOptional)) \
     450                        { RTAssertMsg2("y\n"); return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; } \
     451                    pValueUnion->a_MemberPrefix##Second = Value2; \
     452                    pValueUnion->a_MemberPrefix##First  = Value1; \
     453                    break; \
     454                } \
     455                return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
     456            }
     457
     458        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT32_PAIR,                      RTGETOPT_REQ_UINT32_OPTIONAL_PAIR,
     459                         uint32_t, PairU32.u, RTStrToUInt32Ex, 10, UINT32_MAX)
     460        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT32_PAIR | RTGETOPT_FLAG_DEC,  RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_DEC,
     461                         uint32_t, PairU32.u, RTStrToUInt32Ex, 10, UINT32_MAX)
     462        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT32_PAIR | RTGETOPT_FLAG_HEX,  RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX,
     463                         uint32_t, PairU32.u, RTStrToUInt32Ex, 16, UINT32_MAX)
     464        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT32_PAIR | RTGETOPT_FLAG_OCT,  RTGETOPT_REQ_UINT32_OPTIONAL_PAIR | RTGETOPT_FLAG_OCT,
     465                         uint32_t, PairU32.u, RTStrToUInt32Ex,  8, UINT32_MAX)
     466
     467        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT64_PAIR,                      RTGETOPT_REQ_UINT64_OPTIONAL_PAIR,
     468                         uint64_t, PairU64.u, RTStrToUInt64Ex, 10, UINT64_MAX)
     469        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT64_PAIR | RTGETOPT_FLAG_DEC,  RTGETOPT_REQ_UINT64_OPTIONAL_PAIR | RTGETOPT_FLAG_DEC,
     470                         uint64_t, PairU64.u, RTStrToUInt64Ex, 10, UINT64_MAX)
     471        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT64_PAIR | RTGETOPT_FLAG_HEX,  RTGETOPT_REQ_UINT64_OPTIONAL_PAIR | RTGETOPT_FLAG_HEX,
     472                         uint64_t, PairU64.u, RTStrToUInt64Ex, 16, UINT64_MAX)
     473        MY_INT_PAIR_CASE(RTGETOPT_REQ_UINT64_PAIR | RTGETOPT_FLAG_OCT,  RTGETOPT_REQ_UINT64_OPTIONAL_PAIR | RTGETOPT_FLAG_OCT,
     474                         uint64_t, PairU64.u, RTStrToUInt64Ex,  8, UINT64_MAX)
     475
    409476        default:
    410477            AssertMsgFailed(("f=%#x\n", fFlags));
  • trunk/src/VBox/Runtime/testcase/tstRTGetOpt.cpp

    r62477 r68936  
    106106        { "--boolean",          408, RTGETOPT_REQ_BOOL_ONOFF },
    107107        { "--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  },
    108111    };
    109112
     
    187190        "-version",
    188191        "-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",
    189200
    190201        /* done */
     
    426437    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 'V', 1);
    427438    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);
    428460
    429461    /* the end */
Note: See TracChangeset for help on using the changeset viewer.

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