VirtualBox

Changeset 23644 in vbox for trunk/src/VBox/Runtime/common


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

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

File:
1 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;
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