VirtualBox

儲存庫 vbox 的更動 17100


忽略:
時間撮記:
2009-2-24 下午09:37:20 (16 年 以前)
作者:
vboxsync
訊息:

RTGetOpt: Fixed 'tstHeadless -startvm vm' breakage from earlier today.

位置:
trunk/src/VBox/Runtime
檔案:
修改 2 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Runtime/common/misc/getopt.cpp

    r17093 r17100  
    5252    pState->iNext       = iFirst;
    5353
     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
    5463    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 */
     75static 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 */
     115static 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;
    55125}
    56126
     
    64134        return 0;
    65135
     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     */
    66146    int             iThis = pState->iNext++;
    67147    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)
    81169        {
    82170            /*
     171             * Find the argument value.
     172             *
    83173             * A value is required with the argument. We're trying to be very
    84174             * understanding here and will permit any of the following:
     
    87177             * (Ditto for long options.)
    88178             */
    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)
    98181            {
    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] == '=')) )
    109186                {
    110187                    if (iThis + 1 >= pState->argc)
     
    114191                }
    115192                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')
    127200                {
    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;
    131221
    132222#define MY_INT_CASE(req,type,memb,convfn) \
    133                         case req: \
    134                         { \
    135                             type Value; \
    136                             if (    convfn(pszValue, 10, &Value) != VINF_SUCCESS \
    137                                 &&  (   pszValue[0] != '0' \
    138                                      || (pszValue[1] != 'x' && pszValue[1] != 'X') \
    139                                      || !RT_C_IS_XDIGIT(pszValue[2]) \
    140                                      || convfn(pszValue, 16, &Value) != VINF_SUCCESS ) ) \
    141                                 return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
    142                             pValueUnion->memb = Value; \
    143                             break; \
    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                    }
    145235#define MY_BASE_INT_CASE(req,type,memb,convfn,base) \
    146                         case req: \
    147                         { \
    148                             type Value; \
    149                             if (convfn(pszValue, base, &Value) != VINF_SUCCESS) \
    150                                 return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
    151                             pValueUnion->memb = Value; \
    152                             break; \
    153                         }
    154 
    155                     MY_INT_CASE(RTGETOPT_REQ_INT8,   int8_t,   i,   RTStrToInt8Full)
    156                     MY_INT_CASE(RTGETOPT_REQ_INT16,  int16_t,  i,   RTStrToInt16Full)
    157                     MY_INT_CASE(RTGETOPT_REQ_INT32,  int32_t,  i,   RTStrToInt32Full)
    158                     MY_INT_CASE(RTGETOPT_REQ_INT64,  int64_t,  i,   RTStrToInt64Full)
    159                     MY_INT_CASE(RTGETOPT_REQ_UINT8,  uint8_t,  u,   RTStrToUInt8Full)
    160                     MY_INT_CASE(RTGETOPT_REQ_UINT16, uint16_t, u,   RTStrToUInt16Full)
    161                     MY_INT_CASE(RTGETOPT_REQ_UINT32, uint32_t, u,   RTStrToUInt32Full)
    162                     MY_INT_CASE(RTGETOPT_REQ_UINT64, uint64_t, u,   RTStrToUInt64Full)
    163 
    164                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_HEX, int8_t,   i,   RTStrToInt8Full,   16)
    165                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_HEX, int16_t,  i,   RTStrToInt16Full,  16)
    166                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_HEX, int32_t,  i,   RTStrToInt32Full,  16)
    167                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_HEX, int64_t,  i,   RTStrToInt64Full,  16)
    168                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_HEX, uint8_t,  u,   RTStrToUInt8Full,  16)
    169                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_HEX, uint16_t, u,   RTStrToUInt16Full, 16)
    170                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX, uint32_t, u,   RTStrToUInt32Full, 16)
    171                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX, uint64_t, u,   RTStrToUInt64Full, 16)
    172 
    173                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_DEC, int8_t,   i,   RTStrToInt8Full,   10)
    174                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_DEC, int16_t,  i,   RTStrToInt16Full,  10)
    175                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_DEC, int32_t,  i,   RTStrToInt32Full,  10)
    176                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_DEC, int64_t,  i,   RTStrToInt64Full,  10)
    177                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_DEC, uint8_t,  u,   RTStrToUInt8Full,  10)
    178                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_DEC, uint16_t, u,   RTStrToUInt16Full, 10)
    179                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_DEC, uint32_t, u,   RTStrToUInt32Full, 10)
    180                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_DEC, uint64_t, u,   RTStrToUInt64Full, 10)
    181 
    182                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT8   | RTGETOPT_FLAG_OCT, int8_t,   i,   RTStrToInt8Full,   8)
    183                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT16  | RTGETOPT_FLAG_OCT, int16_t,  i,   RTStrToInt16Full,  8)
    184                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT32  | RTGETOPT_FLAG_OCT, int32_t,  i,   RTStrToInt32Full,  8)
    185                     MY_BASE_INT_CASE(RTGETOPT_REQ_INT64  | RTGETOPT_FLAG_OCT, int64_t,  i,   RTStrToInt64Full,  8)
    186                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8  | RTGETOPT_FLAG_OCT, uint8_t,  u,   RTStrToUInt8Full,  8)
    187                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_OCT, uint16_t, u,   RTStrToUInt16Full, 8)
    188                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT, uint32_t, u,   RTStrToUInt32Full, 8)
    189                     MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_OCT, uint64_t, u,   RTStrToUInt64Full, 8)
     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)
    190280#undef MY_INT_CASE
    191281#undef MY_BASE_INT_CASE
    192282
    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;
    198286            }
    199287        }
    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
    212296    if (*pszArgThis == '-')
    213297        return VERR_GETOPT_UNKNOWN_OPTION;
    214298
    215     /** @todo Handle '--' and possibly implement an RTGetOptInit that lets us
    216      *        optionally sort the stuff and set other policeis sorts the result.  */
    217 
    218     /*
    219      * Not an option.
    220      */
    221299    pValueUnion->psz = pszArgThis;
    222300    return VINF_GETOPT_NOT_OPTION;
  • trunk/src/VBox/Runtime/testcase/tstGetOpt.cpp

    r17093 r17100  
    6464        { NULL,                 'q', RTGETOPT_REQ_NOTHING },
    6565        { "--quiet",            384, RTGETOPT_REQ_NOTHING },
    66         { "-quiet2",            385, RTGETOPT_REQ_NOTHING },
     66        { "-startvm",           385, RTGETOPT_REQ_NOTHING },
    6767    };
    6868
     
    8585        "-q",
    8686        "--quiet",
    87         "-quiet2",
    88         /* "filename1", */
    89         /* "filename2", */
     87        "-startvm",
     88        "filename1",
     89        "-q",
     90        "filename2",
    9091        NULL
    9192    };
     
    133134    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 385, 1);
    134135    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
    135144    CHECK_GETOPT(RTGetOpt(&GetState, &Val), 0, 0);
    136145    CHECK(Val.pDef == NULL);
     
    148157    return !!cErrors;
    149158}
     159
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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