VirtualBox

Changeset 23644 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Oct 9, 2009 12:28:56 PM (15 years ago)
Author:
vboxsync
Message:

Runtime: Added indexed options to RTGetOpt (eg: "--strwithindex14 value")

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

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

    r21337 r23644  
    192192                 * A value is required with the argument. We're trying to be very
    193193                 * understanding here and will permit any of the following:
    194                  *      --long:value,  --long=value, --long value,
    195                  *      --long: value, --long= value
     194                 *      --long12:value,  --long12=value, --long12 value,
     195                 *      --long:value,    --long=value,   --long value,
     196                 *      --long: value,   --long= value
     197                 *
     198                 * If the option is index, then all trailing chars must be
     199                 * digits.  For error reporting reasons we also match where
     200                 * there is no index.
    196201                 */
    197202                size_t cchLong = strlen(pOpt->pszLong);
    198                 if (    !strncmp(pszOption, pOpt->pszLong, cchLong)
    199                     && (   pszOption[cchLong] == '\0'
     203                if (!strncmp(pszOption, pOpt->pszLong, cchLong))
     204                {
     205                    if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
     206                        while (RT_C_IS_DIGIT(pszOption[cchLong]))
     207                            cchLong++;
     208                    if (   pszOption[cchLong] == '\0'
    200209                        || pszOption[cchLong] == ':'
    201                         || pszOption[cchLong] == '='))
    202                     return pOpt;
     210                        || pszOption[cchLong] == '=')
     211                        return pOpt;
     212                }
     213            }
     214            else if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
     215            {
     216                /*
     217                 * The option takes an index but no value.
     218                 * As above, we also match where there is no index.
     219                 */
     220                size_t cchLong = strlen(pOpt->pszLong);
     221                if (!strncmp(pszOption, pOpt->pszLong, cchLong))
     222                {
     223                    while (RT_C_IS_DIGIT(pszOption[cchLong]))
     224                        cchLong++;
     225                    if (pszOption[cchLong] == '\0')
     226                        return pOpt;
     227                }
    203228            }
    204229            else if (!strcmp(pszOption, pOpt->pszLong))
     
    234259RTDECL(int) RTGetOpt(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion)
    235260{
     261    /*
     262     * Reset the variables kept in state.
     263     */
    236264    pState->pDef = NULL;
     265    pState->uIndex = UINT64_MAX;
     266
    237267    /*
    238268     * Make sure the union is completely cleared out, whatever happens below.
     
    338368            {
    339369                size_t cchLong = strlen(pOpt->pszLong);
    340                 if (    pszArgThis[cchLong]     == '\0'
    341                     ||  pszArgThis[cchLong + 1] == '\0')
    342                 {
    343                     if (iThis + 1 >= pState->argc)
    344                         return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
    345                     pszValue = pState->argv[iThis + 1];
    346                     pState->iNext++;
    347                 }
    348                 else /* same argument. */
    349                     pszValue = &pszArgThis[cchLong + 1];
     370                if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
     371                {
     372
     373                    if (pszArgThis[cchLong] == '\0')
     374                        return VERR_GETOPT_INDEX_MISSING;
     375
     376                    uint64_t uIndex;
     377                    char *pszRet = NULL;
     378                    int rc = RTStrToUInt64Ex(&pszArgThis[cchLong], &pszRet, 10, &uIndex);
     379                    if (rc == VWRN_TRAILING_CHARS)
     380                    {
     381                        if (   pszRet[0] != ':'
     382                            && pszRet[0] != '=')
     383                            return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
     384                        pState->uIndex = uIndex;
     385                        pszValue = pszRet + 1;
     386                    }
     387                    else if (rc == VINF_SUCCESS)
     388                    {
     389                        if (iThis + 1 >= pState->argc)
     390                            return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
     391                        pState->uIndex = uIndex;
     392                        pszValue = pState->argv[iThis + 1];
     393                        pState->iNext++;
     394                    }
     395                    else
     396                        AssertMsgFailedReturn(("%s\n", pszArgThis), VERR_GETOPT_INVALID_ARGUMENT_FORMAT); /* search bug */
     397                }
     398                else
     399                {
     400                    if (    pszArgThis[cchLong]     == '\0'
     401                        ||  pszArgThis[cchLong + 1] == '\0')
     402                    {
     403                        if (iThis + 1 >= pState->argc)
     404                            return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
     405                        pszValue = pState->argv[iThis + 1];
     406                        pState->iNext++;
     407                    }
     408                    else /* same argument. */
     409                        pszValue = &pszArgThis[cchLong + 1];
     410                }
    350411            }
    351412
     
    356417             * generic ints as octals.
    357418             */
    358             switch (pOpt->fFlags & (RTGETOPT_REQ_MASK | RTGETOPT_FLAG_HEX | RTGETOPT_FLAG_OCT | RTGETOPT_FLAG_DEC))
     419            switch (pOpt->fFlags & (  RTGETOPT_REQ_MASK
     420                                    | RTGETOPT_FLAG_HEX
     421                                    | RTGETOPT_FLAG_DEC
     422                                    | RTGETOPT_FLAG_OCT))
    359423            {
    360424                case RTGETOPT_REQ_STRING:
     
    480544            }
    481545        }
     546        else if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
     547        {
     548            size_t cchLong = strlen(pOpt->pszLong);
     549            if (pszArgThis[cchLong] == '\0')
     550                return VERR_GETOPT_INDEX_MISSING;
     551
     552            uint64_t uIndex;
     553            char *pszRet = NULL;
     554            if (RTStrToUInt64Full(&pszArgThis[cchLong], 10, &uIndex) == VINF_SUCCESS)
     555                pState->uIndex = uIndex;
     556            else
     557                AssertMsgFailedReturn(("%s\n", pszArgThis), VERR_GETOPT_INVALID_ARGUMENT_FORMAT); /* search bug */
     558        }
    482559
    483560        pState->pDef = pOpt;
  • trunk/src/VBox/Runtime/testcase/tstGetOpt.cpp

    r18318 r23644  
    8888        { "--gateway",          'g', RTGETOPT_REQ_IPV4ADDR },
    8989        { "--mac",              'm', RTGETOPT_REQ_MACADDR },
     90        { "--strindex",         400, RTGETOPT_REQ_STRING  | RTGETOPT_FLAG_INDEX },
     91        { "strindex",           400, RTGETOPT_REQ_STRING  | RTGETOPT_FLAG_INDEX },
     92        { "--intindex",         401, RTGETOPT_REQ_INT32   | RTGETOPT_FLAG_INDEX },
     93        { "--macindex",         402, RTGETOPT_REQ_MACADDR | RTGETOPT_FLAG_INDEX },
     94        { "--indexnovalue",     403, RTGETOPT_REQ_NOTHING | RTGETOPT_FLAG_INDEX },
     95        { "--macindexnegative", 404, RTGETOPT_REQ_NOTHING },
    9096    };
    9197
     
    129135        "--mac:1:::::c",
    130136
     137        "--strindex786",    "string4",
     138        "--strindex786:string5",
     139        "--strindex786=string6",
     140        "strindex687",      "string7",
     141        "strindex687:string8",
     142        "strindex687=string9",
     143        "--intindex137",    "1000",
     144        "--macindex138",    "08:0:27:00:ab:f3",
     145        "--indexnovalue1",
     146        "--macindexnegative",
     147
    131148        NULL
    132149    };
     
    137154    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 2);
    138155    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string1"));
     156    CHECK(GetState.uIndex == UINT64_MAX);
    139157    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 's', 2);
    140158    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string2"));
     159    CHECK(GetState.uIndex == UINT64_MAX);
    141160
    142161    /* -i */
     
    222241          && Val.MacAddr.au8[5] == 0x0c);
    223242
     243    /* string with indexed argument */
     244    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2);
     245    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string4"));
     246    CHECK(GetState.uIndex == 786);
     247
     248    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
     249    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string5"));
     250    CHECK(GetState.uIndex == 786);
     251
     252    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
     253    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string6"));
     254    CHECK(GetState.uIndex == 786);
     255
     256    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 2);
     257    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string7"));
     258    CHECK(GetState.uIndex == 687);
     259
     260    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
     261    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string8"));
     262    CHECK(GetState.uIndex == 687);
     263
     264    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 400, 1);
     265    CHECK(VALID_PTR(Val.psz) && !strcmp(Val.psz, "string9"));
     266    CHECK(GetState.uIndex == 687);
     267
     268    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 401, 2);
     269    CHECK(Val.i32 == 1000);
     270    CHECK(GetState.uIndex == 137);
     271
     272    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 402, 2);
     273    CHECK(   Val.MacAddr.au8[0] == 0x08
     274          && Val.MacAddr.au8[1] == 0x00
     275          && Val.MacAddr.au8[2] == 0x27
     276          && Val.MacAddr.au8[3] == 0x00
     277          && Val.MacAddr.au8[4] == 0xab
     278          && Val.MacAddr.au8[5] == 0xf3);
     279    CHECK(GetState.uIndex == 138);
     280
     281    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 403, 1);
     282    CHECK(GetState.uIndex == 1);
     283
     284    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 404, 1);
     285    CHECK(GetState.uIndex == UINT64_MAX);
     286
    224287    /* the end */
    225288    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0);
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