VirtualBox

Changeset 96127 in vbox


Ignore:
Timestamp:
Aug 9, 2022 10:00:57 AM (2 years ago)
Author:
vboxsync
Message:

IPRT/RTStrTo[U]Int[8|16|32|64][Ex|Full]: Tweaked the base parameter to allow passing a maximum length. Need this for the no-CRT sscanf code. bugref:10261

Location:
trunk
Files:
3 edited

Legend:

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

    r94421 r96127  
    28402840 * @retval  VERR_NO_DIGITS
    28412841 *
    2842  * @param   pszValue    Pointer to the string value.
    2843  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    2844  * @param   uBase       The base of the representation used.
    2845  *                      If 0 the function will look for known prefixes before defaulting to 10.
    2846  * @param   pu64        Where to store the converted number. (optional)
    2847  */
    2848 RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint64_t *pu64);
     2842 * @param   pszValue        Pointer to the string value.
     2843 * @param   ppszNext        Where to store the pointer to the first char
     2844 *                          following the number. (Optional)
     2845 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     2846 *                          upper 24 bits are the max length to parse.  If the base
     2847 *                          is zero the function will look for known prefixes before
     2848 *                          defaulting to 10.  A max length of zero means no length
     2849 *                          restriction.
     2850 * @param   pu64            Where to store the converted number. (optional)
     2851 */
     2852RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndLen, uint64_t *pu64);
    28492853
    28502854/**
     
    28612865 * @retval  VERR_TRAILING_CHARS
    28622866 *
    2863  * @param   pszValue    Pointer to the string value.
    2864  * @param   uBase       The base of the representation used.
    2865  *                      If 0 the function will look for known prefixes before defaulting to 10.
    2866  * @param   pu64        Where to store the converted number. (optional)
     2867 * @param   pszValue        Pointer to the string value.
     2868 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     2869 *                          upper 24 bits are the max length to parse.  If the base
     2870 *                          is zero the function will look for known prefixes before
     2871 *                          defaulting to 10.  A max length of zero means no length
     2872 *                          restriction.
     2873 * @param   pu64            Where to store the converted number. (optional)
    28672874 */
    28682875RTDECL(int) RTStrToUInt64Full(const char *pszValue, unsigned uBase, uint64_t *pu64);
     
    28902897 * @retval  VERR_NO_DIGITS
    28912898 *
    2892  * @param   pszValue    Pointer to the string value.
    2893  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    2894  * @param   uBase       The base of the representation used.
    2895  *                      If 0 the function will look for known prefixes before defaulting to 10.
    2896  * @param   pu32        Where to store the converted number. (optional)
     2899 * @param   pszValue        Pointer to the string value.
     2900 * @param   ppszNext        Where to store the pointer to the first char
     2901 *                          following the number. (Optional)
     2902 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     2903 *                          upper 24 bits are the max length to parse.  If the base
     2904 *                          is zero the function will look for known prefixes before
     2905 *                          defaulting to 10.  A max length of zero means no length
     2906 *                          restriction.
     2907 * @param   pu32            Where to store the converted number. (optional)
    28972908 */
    28982909RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint32_t *pu32);
     
    29112922 * @retval  VERR_TRAILING_CHARS
    29122923 *
    2913  * @param   pszValue    Pointer to the string value.
    2914  * @param   uBase       The base of the representation used.
    2915  *                      If 0 the function will look for known prefixes before defaulting to 10.
    2916  * @param   pu32        Where to store the converted number. (optional)
     2924 * @param   pszValue        Pointer to the string value.
     2925 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     2926 *                          upper 24 bits are the max length to parse.  If the base
     2927 *                          is zero the function will look for known prefixes before
     2928 *                          defaulting to 10.  A max length of zero means no length
     2929 *                          restriction.
     2930 * @param   pu32            Where to store the converted number. (optional)
    29172931 */
    29182932RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBase, uint32_t *pu32);
     
    29402954 * @retval  VERR_NO_DIGITS
    29412955 *
    2942  * @param   pszValue    Pointer to the string value.
    2943  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    2944  * @param   uBase       The base of the representation used.
    2945  *                      If 0 the function will look for known prefixes before defaulting to 10.
    2946  * @param   pu16        Where to store the converted number. (optional)
     2956 * @param   pszValue        Pointer to the string value.
     2957 * @param   ppszNext        Where to store the pointer to the first char
     2958 *                          following the number. (Optional)
     2959 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     2960 *                          upper 24 bits are the max length to parse.  If the base
     2961 *                          is zero the function will look for known prefixes before
     2962 *                          defaulting to 10.  A max length of zero means no length
     2963 *                          restriction.
     2964 * @param   pu16            Where to store the converted number. (optional)
    29472965 */
    29482966RTDECL(int) RTStrToUInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint16_t *pu16);
     
    29903008 * @retval  VERR_NO_DIGITS
    29913009 *
    2992  * @param   pszValue    Pointer to the string value.
    2993  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    2994  * @param   uBase       The base of the representation used.
    2995  *                      If 0 the function will look for known prefixes before defaulting to 10.
    2996  * @param   pu8         Where to store the converted number. (optional)
     3010 * @param   pszValue        Pointer to the string value.
     3011 * @param   ppszNext        Where to store the pointer to the first char
     3012 *                          following the number. (Optional)
     3013 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     3014 *                          upper 24 bits are the max length to parse.  If the base
     3015 *                          is zero the function will look for known prefixes before
     3016 *                          defaulting to 10.  A max length of zero means no length
     3017 *                          restriction.
     3018 * @param   pu8             Where to store the converted number. (optional)
    29973019 */
    29983020RTDECL(int) RTStrToUInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint8_t *pu8);
     
    30113033 * @retval  VERR_TRAILING_CHARS
    30123034 *
    3013  * @param   pszValue    Pointer to the string value.
    3014  * @param   uBase       The base of the representation used.
    3015  *                      If 0 the function will look for known prefixes before defaulting to 10.
    3016  * @param   pu8         Where to store the converted number. (optional)
     3035 * @param   pszValue        Pointer to the string value.
     3036 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     3037 *                          upper 24 bits are the max length to parse.  If the base
     3038 *                          is zero the function will look for known prefixes before
     3039 *                          defaulting to 10.  A max length of zero means no length
     3040 *                          restriction.
     3041 * @param   pu8             Where to store the converted number. (optional)
    30173042 */
    30183043RTDECL(int) RTStrToUInt8Full(const char *pszValue, unsigned uBase, uint8_t *pu8);
  • trunk/src/VBox/Runtime/common/string/strtonum.cpp

    r93115 r96127  
    110110 * @retval  VERR_NO_DIGITS
    111111 *
    112  * @param   pszValue    Pointer to the string value.
    113  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    114  * @param   uBase       The base of the representation used.
    115  *                      If the function will look for known prefixes before defaulting to 10.
    116  * @param   pu64        Where to store the converted number. (optional)
    117  */
    118 RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint64_t *pu64)
     112 * @param   pszValue        Pointer to the string value.
     113 * @param   ppszNext        Where to store the pointer to the first char
     114 *                          following the number. (Optional)
     115 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     116 *                          upper 24 bits are the max length to parse.  If the base
     117 *                          is zero the function will look for known prefixes before
     118 *                          defaulting to 10.  A max length of zero means no length
     119 *                          restriction.
     120 * @param   pu64            Where to store the converted number. (optional)
     121 */
     122RTDECL(int) RTStrToUInt64Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndMaxLen, uint64_t *pu64)
    119123{
    120124    const char   *psz = pszValue;
     
    123127    uint64_t      u64;
    124128    unsigned char uch;
     129    bool          fPositive;
     130
     131    /*
     132     * Split the base and length limit (latter is chiefly for sscanf).
     133     */
     134    unsigned uBase  = uBaseAndMaxLen & 0xff;
     135    unsigned cchMax = uBaseAndMaxLen >> 8;
     136    if (cchMax == 0)
     137        cchMax = ~0U;
     138    AssertStmt(uBase < RT_ELEMENTS(g_auchShift), uBase = 0);
    125139
    126140    /*
    127141     * Positive/Negative stuff.
    128142     */
    129     bool fPositive = true;
    130     for (;; psz++)
     143    fPositive = true;
     144    while (cchMax > 0)
    131145    {
    132146        if (*psz == '+')
     
    136150        else
    137151            break;
     152        psz++;
     153        cchMax--;
    138154    }
    139155
     
    143159    if (!uBase)
    144160    {
    145         if (    psz[0] == '0'
    146             &&  (psz[1] == 'x' || psz[1] == 'X')
    147             &&  g_auchDigits[(unsigned char)psz[2]] < 16)
     161        uBase = 10;
     162        if (psz[0] == '0')
    148163        {
    149             uBase = 16;
    150             psz += 2;
     164            if (   psz[0] == '0'
     165                && cchMax > 1
     166                && (psz[1] == 'x' || psz[1] == 'X')
     167                && g_auchDigits[(unsigned char)psz[2]] < 16)
     168            {
     169                uBase     = 16;
     170                psz      += 2;
     171                cchMax   -= 2;
     172            }
     173            else if (   psz[0] == '0'
     174                     && g_auchDigits[(unsigned char)psz[1]] < 8)
     175                uBase = 8; /* don't skip the zero, in case it's alone. */
    151176        }
    152         else if (   psz[0] == '0'
    153                  && g_auchDigits[(unsigned char)psz[1]] < 8)
    154         {
    155             uBase = 8;
    156             psz++;
    157         }
    158         else
    159             uBase = 10;
    160177    }
    161178    else if (   uBase == 16
    162179             && psz[0] == '0'
     180             && cchMax > 1
    163181             && (psz[1] == 'x' || psz[1] == 'X')
    164182             && g_auchDigits[(unsigned char)psz[2]] < 16)
    165         psz += 2;
     183    {
     184        cchMax -= 2;
     185        psz    += 2;
     186    }
    166187
    167188    /*
     
    169190     * Note: We only support ascii digits at this time... :-)
    170191     */
    171     iShift = g_auchShift[uBase];
    172192    pszValue = psz; /* (Prefix and sign doesn't count in the digit counting.) */
    173     rc = VINF_SUCCESS;
    174     u64 = 0;
    175     while ((uch = (unsigned char)*psz) != 0)
     193    iShift   = g_auchShift[uBase];
     194    rc       = VINF_SUCCESS;
     195    u64      = 0;
     196    while (cchMax > 0 && (uch = (unsigned char)*psz) != 0)
    176197    {
    177198        unsigned char chDigit = g_auchDigits[uch];
     
    182203
    183204        u64Prev = u64;
    184         u64 *= uBase;
    185         u64 += chDigit;
     205        u64    *= uBase;
     206        u64    += chDigit;
    186207        if (u64Prev > u64 || (u64Prev >> iShift))
    187208            rc = VWRN_NUMBER_TOO_BIG;
    188209        psz++;
     210        cchMax--;
    189211    }
    190212
     
    208230     * Warn about trailing chars/spaces.
    209231     */
    210     if (    rc == VINF_SUCCESS
    211         &&  *psz)
    212     {
    213         while (*psz == ' ' || *psz == '\t')
    214             psz++;
    215         rc = *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
     232    if (   rc == VINF_SUCCESS
     233        && *psz
     234        && cchMax > 0)
     235    {
     236        while (cchMax > 0 && (*psz == ' ' || *psz == '\t'))
     237            psz++, cchMax--;
     238        rc = cchMax > 0 && *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
    216239    }
    217240
     
    234257 * @retval  VERR_TRAILING_CHARS
    235258 *
    236  * @param   pszValue    Pointer to the string value.
    237  * @param   uBase       The base of the representation used.
    238  *                      If the function will look for known prefixes before defaulting to 10.
    239  * @param   pu64        Where to store the converted number. (optional)
    240  */
    241 RTDECL(int) RTStrToUInt64Full(const char *pszValue, unsigned uBase, uint64_t *pu64)
     259 * @param   pszValue        Pointer to the string value.
     260 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     261 *                          upper 24 bits are the max length to parse.  If the base
     262 *                          is zero the function will look for known prefixes before
     263 *                          defaulting to 10.  A max length of zero means no length
     264 *                          restriction.
     265 * @param   pu64            Where to store the converted number. (optional)
     266 */
     267RTDECL(int) RTStrToUInt64Full(const char *pszValue, unsigned uBaseAndMaxLen, uint64_t *pu64)
    242268{
    243269    char *psz;
    244     int rc = RTStrToUInt64Ex(pszValue, &psz, uBase, pu64);
     270    int rc = RTStrToUInt64Ex(pszValue, &psz, uBaseAndMaxLen, pu64);
    245271    if (RT_SUCCESS(rc) && *psz)
    246272    {
    247273        if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
    248274            rc = -rc;
    249         else
     275        else if (rc != VINF_SUCCESS)
    250276        {
    251             while (*psz == ' ' || *psz == '\t')
    252                 psz++;
    253             rc = *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
     277            unsigned cchMax = uBaseAndMaxLen >> 8;
     278            if (!cchMax)
     279                cchMax  = ~0U;
     280            else
     281                cchMax -= (unsigned)(psz - pszValue);
     282            if (cchMax > 0)
     283            {
     284                while (cchMax > 0 && (*psz == ' ' || *psz == '\t'))
     285                    psz++, cchMax--;
     286                rc = cchMax > 0 && *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
     287            }
    254288        }
    255289    }
     
    290324 * @retval  VERR_NO_DIGITS
    291325 *
    292  * @param   pszValue    Pointer to the string value.
    293  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    294  * @param   uBase       The base of the representation used.
    295  *                      If the function will look for known prefixes before defaulting to 10.
    296  * @param   pu32        Where to store the converted number. (optional)
    297  */
    298 RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint32_t *pu32)
     326 * @param   pszValue        Pointer to the string value.
     327 * @param   ppszNext        Where to store the pointer to the first char
     328 *                          following the number. (Optional)
     329 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     330 *                          upper 24 bits are the max length to parse.  If the base
     331 *                          is zero the function will look for known prefixes before
     332 *                          defaulting to 10.  A max length of zero means no length
     333 *                          restriction.
     334 * @param   pu32            Where to store the converted number. (optional)
     335 */
     336RTDECL(int) RTStrToUInt32Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndMaxLen, uint32_t *pu32)
    299337{
    300338    uint64_t u64;
    301     int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
     339    int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBaseAndMaxLen, &u64);
    302340    if (RT_SUCCESS(rc))
    303341    {
     
    325363 * @retval  VERR_TRAILING_CHARS
    326364 *
    327  * @param   pszValue    Pointer to the string value.
    328  * @param   uBase       The base of the representation used.
    329  *                      If the function will look for known prefixes before defaulting to 10.
    330  * @param   pu32        Where to store the converted number. (optional)
    331  */
    332 RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBase, uint32_t *pu32)
     365 * @param   pszValue        Pointer to the string value.
     366 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     367 *                          upper 24 bits are the max length to parse.  If the base
     368 *                          is zero the function will look for known prefixes before
     369 *                          defaulting to 10.  A max length of zero means no length
     370 *                          restriction.
     371 * @param   pu32            Where to store the converted number. (optional)
     372 */
     373RTDECL(int) RTStrToUInt32Full(const char *pszValue, unsigned uBaseAndMaxLen, uint32_t *pu32)
    333374{
    334375    uint64_t u64;
    335     int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
     376    int rc = RTStrToUInt64Full(pszValue, uBaseAndMaxLen, &u64);
    336377    if (RT_SUCCESS(rc))
    337378    {
     
    377418 * @retval  VERR_NO_DIGITS
    378419 *
    379  * @param   pszValue    Pointer to the string value.
    380  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    381  * @param   uBase       The base of the representation used.
    382  *                      If the function will look for known prefixes before defaulting to 10.
    383  * @param   pu16        Where to store the converted number. (optional)
    384  */
    385 RTDECL(int) RTStrToUInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint16_t *pu16)
     420 * @param   pszValue        Pointer to the string value.
     421 * @param   ppszNext        Where to store the pointer to the first char
     422 *                          following the number. (Optional)
     423 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     424 *                          upper 24 bits are the max length to parse.  If the base
     425 *                          is zero the function will look for known prefixes before
     426 *                          defaulting to 10.  A max length of zero means no length
     427 *                          restriction.
     428 * @param   pu16            Where to store the converted number. (optional)
     429 */
     430RTDECL(int) RTStrToUInt16Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndMaxLen, uint16_t *pu16)
    386431{
    387432    uint64_t u64;
    388     int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
     433    int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBaseAndMaxLen, &u64);
    389434    if (RT_SUCCESS(rc))
    390435    {
     
    412457 * @retval  VERR_TRAILING_CHARS
    413458 *
    414  * @param   pszValue    Pointer to the string value.
    415  * @param   uBase       The base of the representation used.
    416  *                      If the function will look for known prefixes before defaulting to 10.
    417  * @param   pu16        Where to store the converted number. (optional)
    418  */
    419 RTDECL(int) RTStrToUInt16Full(const char *pszValue, unsigned uBase, uint16_t *pu16)
     459 * @param   pszValue        Pointer to the string value.
     460 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     461 *                          upper 24 bits are the max length to parse.  If the base
     462 *                          is zero the function will look for known prefixes before
     463 *                          defaulting to 10.  A max length of zero means no length
     464 *                          restriction.
     465 * @param   pu16            Where to store the converted number. (optional)
     466 */
     467RTDECL(int) RTStrToUInt16Full(const char *pszValue, unsigned uBaseAndMaxLen, uint16_t *pu16)
    420468{
    421469    uint64_t u64;
    422     int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
     470    int rc = RTStrToUInt64Full(pszValue, uBaseAndMaxLen, &u64);
    423471    if (RT_SUCCESS(rc))
    424472    {
     
    464512 * @retval  VERR_NO_DIGITS
    465513 *
    466  * @param   pszValue    Pointer to the string value.
    467  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    468  * @param   uBase       The base of the representation used.
    469  *                      If the function will look for known prefixes before defaulting to 10.
    470  * @param   pu8         Where to store the converted number. (optional)
    471  */
    472 RTDECL(int) RTStrToUInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, uint8_t *pu8)
     514 * @param   pszValue        Pointer to the string value.
     515 * @param   ppszNext        Where to store the pointer to the first char
     516 *                          following the number. (Optional)
     517 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     518 *                          upper 24 bits are the max length to parse.  If the base
     519 *                          is zero the function will look for known prefixes before
     520 *                          defaulting to 10.  A max length of zero means no length
     521 *                          restriction.
     522 * @param   pu8             Where to store the converted number. (optional)
     523 */
     524RTDECL(int) RTStrToUInt8Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndMaxLen, uint8_t *pu8)
    473525{
    474526    uint64_t u64;
    475     int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBase, &u64);
     527    int rc = RTStrToUInt64Ex(pszValue, ppszNext, uBaseAndMaxLen, &u64);
    476528    if (RT_SUCCESS(rc))
    477529    {
     
    499551 * @retval  VERR_TRAILING_CHARS
    500552 *
    501  * @param   pszValue    Pointer to the string value.
    502  * @param   uBase       The base of the representation used.
    503  *                      If the function will look for known prefixes before defaulting to 10.
    504  * @param   pu8         Where to store the converted number. (optional)
    505  */
    506 RTDECL(int) RTStrToUInt8Full(const char *pszValue, unsigned uBase, uint8_t *pu8)
     553 * @param   pszValue        Pointer to the string value.
     554 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     555 *                          upper 24 bits are the max length to parse.  If the base
     556 *                          is zero the function will look for known prefixes before
     557 *                          defaulting to 10.  A max length of zero means no length
     558 *                          restriction.
     559 * @param   pu8             Where to store the converted number. (optional)
     560 */
     561RTDECL(int) RTStrToUInt8Full(const char *pszValue, unsigned uBaseAndMaxLen, uint8_t *pu8)
    507562{
    508563    uint64_t u64;
    509     int rc = RTStrToUInt64Full(pszValue, uBase, &u64);
     564    int rc = RTStrToUInt64Full(pszValue, uBaseAndMaxLen, &u64);
    510565    if (RT_SUCCESS(rc))
    511566    {
     
    555610 * @retval  VERR_NO_DIGITS
    556611 *
    557  * @param   pszValue    Pointer to the string value.
    558  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    559  * @param   uBase       The base of the representation used.
    560  *                      If the function will look for known prefixes before defaulting to 10.
    561  * @param   pi64        Where to store the converted number. (optional)
    562  */
    563 RTDECL(int) RTStrToInt64Ex(const char *pszValue, char **ppszNext, unsigned uBase, int64_t *pi64)
     612 * @param   pszValue        Pointer to the string value.
     613 * @param   ppszNext        Where to store the pointer to the first char
     614 *                          following the number. (Optional)
     615 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     616 *                          upper 24 bits are the max length to parse.  If the base
     617 *                          is zero the function will look for known prefixes before
     618 *                          defaulting to 10.  A max length of zero means no length
     619 *                          restriction.
     620 * @param   pi64            Where to store the converted number. (optional)
     621 */
     622RTDECL(int) RTStrToInt64Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndMaxLen, int64_t *pi64)
    564623{
    565624    const char   *psz = pszValue;
     
    568627    uint64_t      u64;
    569628    unsigned char uch;
     629    bool          fPositive;
     630
     631    /*
     632     * Split the base and length limit (latter is chiefly for sscanf).
     633     */
     634    unsigned uBase  = uBaseAndMaxLen & 0xff;
     635    unsigned cchMax = uBaseAndMaxLen >> 8;
     636    if (cchMax == 0)
     637        cchMax = ~0U;
     638    AssertStmt(uBase < RT_ELEMENTS(g_auchShift), uBase = 0);
    570639
    571640    /*
    572641     * Positive/Negative stuff.
    573642     */
    574     bool fPositive = true;
    575     for (;; psz++)
     643    fPositive = true;
     644    while (cchMax > 0)
    576645    {
    577646        if (*psz == '+')
     
    581650        else
    582651            break;
     652        psz++;
     653        cchMax--;
    583654    }
    584655
     
    588659    if (!uBase)
    589660    {
    590         if (    *psz == '0'
    591             &&  (psz[1] == 'x' || psz[1] == 'X')
    592             &&  g_auchDigits[(unsigned char)psz[2]] < 16)
     661        uBase = 10;
     662        if (psz[0] == '0')
    593663        {
    594             uBase = 16;
    595             psz += 2;
     664            if (   psz[0] == '0'
     665                && cchMax > 1
     666                && (psz[1] == 'x' || psz[1] == 'X')
     667                && g_auchDigits[(unsigned char)psz[2]] < 16)
     668            {
     669                uBase     = 16;
     670                psz      += 2;
     671                cchMax   -= 2;
     672            }
     673            else if (   psz[0] == '0'
     674                     && g_auchDigits[(unsigned char)psz[1]] < 8)
     675                uBase = 8; /* don't skip the zero, in case it's alone. */
    596676        }
    597         else if (   *psz == '0'
    598                  && g_auchDigits[(unsigned char)psz[1]] < 8)
    599         {
    600             uBase = 8;
    601             psz++;
    602         }
    603         else
    604             uBase = 10;
    605677    }
    606678    else if (   uBase == 16
    607              && *psz == '0'
     679             && psz[0] == '0'
     680             && cchMax > 1
    608681             && (psz[1] == 'x' || psz[1] == 'X')
    609682             && g_auchDigits[(unsigned char)psz[2]] < 16)
    610         psz += 2;
     683    {
     684        cchMax -= 2;
     685        psz    += 2;
     686    }
    611687
    612688    /*
     
    614690     * Note: We only support ascii digits at this time... :-)
    615691     */
    616     iShift = g_auchShift[uBase];
    617692    pszValue = psz; /* (Prefix and sign doesn't count in the digit counting.) */
    618     rc = VINF_SUCCESS;
    619     u64 = 0;
    620     while ((uch = (unsigned char)*psz) != 0)
     693    iShift   = g_auchShift[uBase];
     694    rc       = VINF_SUCCESS;
     695    u64      = 0;
     696    while (cchMax > 0 && (uch = (unsigned char)*psz) != 0)
    621697    {
    622698        unsigned char chDigit = g_auchDigits[uch];
     
    627703
    628704        u64Prev = u64;
    629         u64 *= uBase;
    630         u64 += chDigit;
     705        u64    *= uBase;
     706        u64    += chDigit;
    631707        if (u64Prev > u64 || (u64Prev >> iShift))
    632708            rc = VWRN_NUMBER_TOO_BIG;
    633709        psz++;
     710        cchMax--;
    634711    }
    635712
     
    661738     * Warn about trailing chars/spaces.
    662739     */
    663     if (    rc == VINF_SUCCESS
    664         &&  *psz)
    665     {
    666         while (*psz == ' ' || *psz == '\t')
    667             psz++;
    668         rc = *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
     740    if (   rc == VINF_SUCCESS
     741        && cchMax > 0
     742        && *psz)
     743    {
     744        while (cchMax > 0 && (*psz == ' ' || *psz == '\t'))
     745            psz++, cchMax--;
     746        rc = cchMax > 0 && *psz ? VWRN_TRAILING_CHARS : VWRN_TRAILING_SPACES;
    669747    }
    670748
     
    686764 * @retval  VERR_NO_DIGITS
    687765 *
    688  * @param   pszValue    Pointer to the string value.
    689  * @param   uBase       The base of the representation used.
    690  *                      If the function will look for known prefixes before defaulting to 10.
    691  * @param   pi64        Where to store the converted number. (optional)
    692  */
    693 RTDECL(int) RTStrToInt64Full(const char *pszValue, unsigned uBase, int64_t *pi64)
     766 * @param   pszValue        Pointer to the string value.
     767 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     768 *                          upper 24 bits are the max length to parse.  If the base
     769 *                          is zero the function will look for known prefixes before
     770 *                          defaulting to 10.  A max length of zero means no length
     771 *                          restriction.
     772 * @param   pi64            Where to store the converted number. (optional)
     773 */
     774RTDECL(int) RTStrToInt64Full(const char *pszValue, unsigned uBaseAndMaxLen, int64_t *pi64)
    694775{
    695776    char *psz;
    696     int rc = RTStrToInt64Ex(pszValue, &psz, uBase, pi64);
     777    int rc = RTStrToInt64Ex(pszValue, &psz, uBaseAndMaxLen, pi64);
    697778    if (RT_SUCCESS(rc) && *psz)
    698779    {
    699780        if (rc == VWRN_TRAILING_CHARS || rc == VWRN_TRAILING_SPACES)
    700781            rc = -rc;
    701         else
     782        else if (rc != VINF_SUCCESS)
    702783        {
    703             while (*psz == ' ' || *psz == '\t')
    704                 psz++;
    705             rc = *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
     784            unsigned cchMax = uBaseAndMaxLen >> 8;
     785            if (!cchMax)
     786                cchMax  = ~0U;
     787            else
     788                cchMax -= (unsigned)(psz - pszValue);
     789            if (cchMax > 0)
     790            {
     791                while (cchMax > 0 && (*psz == ' ' || *psz == '\t'))
     792                    psz++, cchMax--;
     793                rc = cchMax > 0 && *psz ? VERR_TRAILING_CHARS : VERR_TRAILING_SPACES;
     794            }
    706795        }
    707796    }
     
    741830 * @retval  VERR_NO_DIGITS
    742831 *
    743  * @param   pszValue    Pointer to the string value.
    744  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    745  * @param   uBase       The base of the representation used.
    746  *                      If the function will look for known prefixes before defaulting to 10.
    747  * @param   pi32        Where to store the converted number. (optional)
    748  */
    749 RTDECL(int) RTStrToInt32Ex(const char *pszValue, char **ppszNext, unsigned uBase, int32_t *pi32)
     832 * @param   pszValue        Pointer to the string value.
     833 * @param   ppszNext        Where to store the pointer to the first char
     834 *                          following the number. (Optional)
     835 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     836 *                          upper 24 bits are the max length to parse.  If the base
     837 *                          is zero the function will look for known prefixes before
     838 *                          defaulting to 10.  A max length of zero means no length
     839 *                          restriction.
     840 * @param   pi32            Where to store the converted number. (optional)
     841 */
     842RTDECL(int) RTStrToInt32Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndMaxLen, int32_t *pi32)
    750843{
    751844    int64_t i64;
    752     int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
     845    int rc = RTStrToInt64Ex(pszValue, ppszNext, uBaseAndMaxLen, &i64);
    753846    if (RT_SUCCESS(rc))
    754847    {
     
    776869 * @retval  VERR_NO_DIGITS
    777870 *
    778  * @param   pszValue    Pointer to the string value.
    779  * @param   uBase       The base of the representation used.
    780  *                      If the function will look for known prefixes before defaulting to 10.
    781  * @param   pi32        Where to store the converted number. (optional)
    782  */
    783 RTDECL(int) RTStrToInt32Full(const char *pszValue, unsigned uBase, int32_t *pi32)
     871 * @param   pszValue        Pointer to the string value.
     872 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     873 *                          upper 24 bits are the max length to parse.  If the base
     874 *                          is zero the function will look for known prefixes before
     875 *                          defaulting to 10.  A max length of zero means no length
     876 *                          restriction.
     877 * @param   pi32            Where to store the converted number. (optional)
     878 */
     879RTDECL(int) RTStrToInt32Full(const char *pszValue, unsigned uBaseAndMaxLen, int32_t *pi32)
    784880{
    785881    int64_t i64;
    786     int rc = RTStrToInt64Full(pszValue, uBase, &i64);
     882    int rc = RTStrToInt64Full(pszValue, uBaseAndMaxLen, &i64);
    787883    if (RT_SUCCESS(rc))
    788884    {
     
    828924 * @retval  VERR_NO_DIGITS
    829925 *
    830  * @param   pszValue    Pointer to the string value.
    831  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    832  * @param   uBase       The base of the representation used.
    833  *                      If the function will look for known prefixes before defaulting to 10.
    834  * @param   pi16        Where to store the converted number. (optional)
    835  */
    836 RTDECL(int) RTStrToInt16Ex(const char *pszValue, char **ppszNext, unsigned uBase, int16_t *pi16)
     926 * @param   pszValue        Pointer to the string value.
     927 * @param   ppszNext        Where to store the pointer to the first char
     928 *                          following the number. (Optional)
     929 * @param   pszValue        Pointer to the string value.
     930 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     931 *                          upper 24 bits are the max length to parse.  If the base
     932 *                          is zero the function will look for known prefixes before
     933 *                          defaulting to 10.  A max length of zero means no length
     934 *                          restriction.
     935 * @param   pu8             Where to store the converted number. (optional)
     936 * @param   pi16            Where to store the converted number. (optional)
     937 */
     938RTDECL(int) RTStrToInt16Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndMaxLen, int16_t *pi16)
    837939{
    838940    int64_t i64;
    839     int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
     941    int rc = RTStrToInt64Ex(pszValue, ppszNext, uBaseAndMaxLen, &i64);
    840942    if (RT_SUCCESS(rc))
    841943    {
     
    863965 * @retval  VERR_NO_DIGITS
    864966 *
    865  * @param   pszValue    Pointer to the string value.
    866  * @param   uBase       The base of the representation used.
    867  *                      If the function will look for known prefixes before defaulting to 10.
    868  * @param   pi16        Where to store the converted number. (optional)
    869  */
    870 RTDECL(int) RTStrToInt16Full(const char *pszValue, unsigned uBase, int16_t *pi16)
     967 * @param   pszValue        Pointer to the string value.
     968 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     969 *                          upper 24 bits are the max length to parse.  If the base
     970 *                          is zero the function will look for known prefixes before
     971 *                          defaulting to 10.  A max length of zero means no length
     972 *                          restriction.
     973 * @param   pi16            Where to store the converted number. (optional)
     974 */
     975RTDECL(int) RTStrToInt16Full(const char *pszValue, unsigned uBaseAndMaxLen, int16_t *pi16)
    871976{
    872977    int64_t i64;
    873     int rc = RTStrToInt64Full(pszValue, uBase, &i64);
     978    int rc = RTStrToInt64Full(pszValue, uBaseAndMaxLen, &i64);
    874979    if (RT_SUCCESS(rc))
    875980    {
     
    9151020 * @retval  VERR_NO_DIGITS
    9161021 *
    917  * @param   pszValue    Pointer to the string value.
    918  * @param   ppszNext    Where to store the pointer to the first char following the number. (Optional)
    919  * @param   uBase       The base of the representation used.
    920  *                      If the function will look for known prefixes before defaulting to 10.
    921  * @param   pi8        Where to store the converted number. (optional)
    922  */
    923 RTDECL(int) RTStrToInt8Ex(const char *pszValue, char **ppszNext, unsigned uBase, int8_t *pi8)
     1022 * @param   pszValue        Pointer to the string value.
     1023 * @param   ppszNext        Where to store the pointer to the first char
     1024 *                          following the number. (Optional)
     1025 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     1026 *                          upper 24 bits are the max length to parse.  If the base
     1027 *                          is zero the function will look for known prefixes before
     1028 *                          defaulting to 10.  A max length of zero means no length
     1029 *                          restriction.
     1030 * @param   pi8             Where to store the converted number. (optional)
     1031 */
     1032RTDECL(int) RTStrToInt8Ex(const char *pszValue, char **ppszNext, unsigned uBaseAndMaxLen, int8_t *pi8)
    9241033{
    9251034    int64_t i64;
    926     int rc = RTStrToInt64Ex(pszValue, ppszNext, uBase, &i64);
     1035    int rc = RTStrToInt64Ex(pszValue, ppszNext, uBaseAndMaxLen, &i64);
    9271036    if (RT_SUCCESS(rc))
    9281037    {
     
    9501059 * @retval  VERR_NO_DIGITS
    9511060 *
    952  * @param   pszValue    Pointer to the string value.
    953  * @param   uBase       The base of the representation used.
    954  *                      If the function will look for known prefixes before defaulting to 10.
    955  * @param   pi8         Where to store the converted number. (optional)
    956  */
    957 RTDECL(int) RTStrToInt8Full(const char *pszValue, unsigned uBase, int8_t *pi8)
     1061 * @param   pszValue        Pointer to the string value.
     1062 * @param   uBaseAndMaxLen  The low byte is the base of the representation, the
     1063 *                          upper 24 bits are the max length to parse.  If the base
     1064 *                          is zero the function will look for known prefixes before
     1065 *                          defaulting to 10.  A max length of zero means no length
     1066 *                          restriction.
     1067 * @param   pi8             Where to store the converted number. (optional)
     1068 */
     1069RTDECL(int) RTStrToInt8Full(const char *pszValue, unsigned uBaseAndMaxLen, int8_t *pi8)
    9581070{
    9591071    int64_t i64;
    960     int rc = RTStrToInt64Full(pszValue, uBase, &i64);
     1072    int rc = RTStrToInt64Full(pszValue, uBaseAndMaxLen, &i64);
    9611073    if (RT_SUCCESS(rc))
    9621074    {
  • trunk/src/VBox/Runtime/testcase/tstStrToNum.cpp

    r93115 r96127  
    8888    } while (0)
    8989
     90#define FULL_TEST(Test, Type, Fmt, Fun, iTest) \
     91    do \
     92    { \
     93        Type Result; \
     94        int rc = Fun(Test.psz, Test.uBase, &Result); \
     95        if (Result != Test.Result) \
     96            RTTestIFailed("'%s' -> " Fmt " expected " Fmt ". (%s/%u)\n", Test.psz, Result, Test.Result, #Fun, iTest); \
     97        else if (rc != Test.rc) \
     98            RTTestIFailed("'%s' -> rc=%Rrc expected %Rrc. (%s/%u)\n", Test.psz, rc, Test.rc, #Fun, iTest); \
     99    } while (0)
     100
     101
     102#define RUN_FULL_TESTS(aTests, Type, Fmt, Fun) \
     103    do \
     104    { \
     105        for (unsigned iTest = 0; iTest < RT_ELEMENTS(aTests); iTest++) \
     106        { \
     107            FULL_TEST(aTests[iTest], Type, Fmt, Fun, iTest); \
     108        } \
     109    } while (0)
     110
    90111int main()
    91112{
     
    104125        { "0x0fffffffffffffff",     0,  VINF_SUCCESS,           0x0fffffffffffffffULL },
    105126        { "0x0ffffffffffffffffffffff",0,  VWRN_NUMBER_TOO_BIG,  0xffffffffffffffffULL },
     127        { "0x0ffffffffffffffffffffff", 10 << 8,  VINF_SUCCESS,  0x0fffffff },
    106128        { "asdfasdfasdf",           0,  VERR_NO_DIGITS,         0 },
    107129        { "0x111111111",            0,  VINF_SUCCESS,           0x111111111ULL },
     
    109131    };
    110132    RUN_TESTS(aTstU64, uint64_t, "%#llx", RTStrToUInt64Ex);
     133
     134    static const struct TstU64 aTstFullU64[] =
     135    {
     136        { "42",                         0,  VINF_SUCCESS,           42 },
     137        { "42 ",                        0,  VERR_TRAILING_SPACES,   42 },
     138        { "42! ",                       0,  VERR_TRAILING_CHARS,    42 },
     139        { "42 !",                       0,  VERR_TRAILING_CHARS,    42 },
     140        { "42 !",                    2<<8,  VINF_SUCCESS,           42 },
     141        { "42 !",                    3<<8,  VERR_TRAILING_SPACES,   42 },
     142        { "42 !",                    4<<8,  VERR_TRAILING_CHARS,    42 },
     143        { "-1",                         0,  VWRN_NEGATIVE_UNSIGNED, UINT64_MAX },
     144        { "-1 ",                        0,  VERR_TRAILING_SPACES,   UINT64_MAX },
     145        { "-1 ",                     2<<8,  VWRN_NEGATIVE_UNSIGNED, UINT64_MAX },
     146        { "-1 ",                     3<<8,  VERR_TRAILING_SPACES,   UINT64_MAX },
     147        { "0x0fffffffffffffff",         0,  VINF_SUCCESS,           0x0fffffffffffffffULL },
     148        { "0x0ffffffffffffffffffff",    0,  VWRN_NUMBER_TOO_BIG,    0xffffffffffffffffULL },
     149        { "0x0ffffffffffffffffffff ",   0,  VERR_TRAILING_SPACES,   0xffffffffffffffffULL },
     150        { "0x0ffffffffffffffffffff! ",  0,  VERR_TRAILING_CHARS,    0xffffffffffffffffULL },
     151        { "0x0ffffffffffffffffffff !",  0,  VERR_TRAILING_CHARS,    0xffffffffffffffffULL },
     152        { "0x0ffffffffffffffffffff",   10 << 8,  VINF_SUCCESS,      0x0fffffff },
     153    };
     154    RUN_FULL_TESTS(aTstFullU64, uint64_t, "%#llx", RTStrToUInt64Full);
    111155
    112156    static const struct TstI64 aTstI64[] =
     
    153197        { "0x07f7f7f7f7f7f7f7f7f7f7f",0,  VWRN_NUMBER_TOO_BIG,  0x7f7f7f7f7f7f7f7fULL },
    154198        { "0x0ffffffffffffffffffffff",0,  VWRN_NUMBER_TOO_BIG,  (int64_t)0xffffffffffffffffULL },
     199        { "0x0ffffffffffffffffffffff", 10 << 8, VINF_SUCCESS,   INT64_C(0x0fffffff) },
     200        { "0x0ffffffffffffffffffffff", 18 << 8, VINF_SUCCESS,   INT64_C(0x0fffffffffffffff) },
     201        { "0x0ffffffffffffffffffffff", 19 << 8, VWRN_NUMBER_TOO_BIG, -1 },
    155202        { "asdfasdfasdf",           0,  VERR_NO_DIGITS,         0 },
    156203        { "0x111111111",            0,  VINF_SUCCESS,           0x111111111ULL },
    157204    };
    158205    RUN_TESTS(aTstI64, int64_t, "%#lld", RTStrToInt64Ex);
     206
     207    static const struct TstI64 aTstI64Full[] =
     208    {
     209        { "1",                          0,  VINF_SUCCESS,           1 },
     210        { "1 ",                         0,  VERR_TRAILING_SPACES,   1 },
     211        { "1! ",                        0,  VERR_TRAILING_CHARS,    1 },
     212        { "1 !",                        0,  VERR_TRAILING_CHARS,    1 },
     213        { "1 !",                     1<<8,  VINF_SUCCESS,           1 },
     214        { "1 !",                     2<<8,  VERR_TRAILING_SPACES,   1 },
     215        { "1 !",                     3<<8,  VERR_TRAILING_CHARS,    1 },
     216        { "0xffffffffffffffff",         0,  VWRN_NUMBER_TOO_BIG,    -1 },
     217        { "0xffffffffffffffff ",        0,  VERR_TRAILING_SPACES,   -1 },
     218        { "0xffffffffffffffff!",        0,  VERR_TRAILING_CHARS,    -1 },
     219        { "0xffffffffffffffff !",   18<<8,  VWRN_NUMBER_TOO_BIG,    -1 },
     220        { "0xffffffffffffffff !",   19<<8,  VERR_TRAILING_SPACES,   -1 },
     221        { "0xffffffffffffffff !",   20<<8,  VERR_TRAILING_CHARS,    -1 },
     222    };
     223    RUN_FULL_TESTS(aTstI64Full, int64_t, "%#lld", RTStrToInt64Full);
    159224
    160225
     
    202267        { "0x01111111111111111111111",0,  VWRN_NUMBER_TOO_BIG,  0x11111111 },
    203268        { "0x0ffffffffffffffffffffff",0,  VWRN_NUMBER_TOO_BIG,  (int32_t)0xffffffff },
     269        { "0x0ffffffffffffffffffffff", 10 << 8, VINF_SUCCESS,   0x0fffffff },
     270        { "0x0ffffffffffffffffffffff", 11 << 8, VWRN_NUMBER_TOO_BIG, -1 },
    204271        { "asdfasdfasdf",           0,  VERR_NO_DIGITS,         0 },
    205272        { "0x1111111",              0,  VINF_SUCCESS,           0x01111111 },
     
    209276    static const struct TstU32 aTstU32[] =
    210277    {
    211         { "0",                      0,  VINF_SUCCESS,           0 },
    212         { "1",                      0,  VINF_SUCCESS,           1 },
    213         /// @todo { "-1",                     0,  VWRN_NEGATIVE_UNSIGNED, ~0 }, - no longer true. bad idea?
    214         { "-1",                     0,  VWRN_NUMBER_TOO_BIG,    ~0U },
    215         { "0x",                     0,  VWRN_TRAILING_CHARS,    0 },
    216         { "0x1",                    0,  VINF_SUCCESS,           1 },
    217         { "0x0fffffffffffffff",     0,  VWRN_NUMBER_TOO_BIG,    0xffffffffU },
    218         { "0x0ffffffffffffffffffffff",0,  VWRN_NUMBER_TOO_BIG,  0xffffffffU },
    219         { "asdfasdfasdf",           0,  VERR_NO_DIGITS,         0 },
    220         { "0x1111111",              0,  VINF_SUCCESS,           0x1111111 },
     278        { "0",                          0,  VINF_SUCCESS,           0 },
     279        { "1",                          0,  VINF_SUCCESS,           1 },
     280        /// @todo { "-1",                         0,  VWRN_NEGATIVE_UNSIGNED, ~0 }, - no longer true. bad idea?
     281        { "-1",                         0,  VWRN_NUMBER_TOO_BIG,    ~0U },
     282        { "0x",                         0,  VWRN_TRAILING_CHARS,    0 },
     283        { "0x1",                        0,  VINF_SUCCESS,           1 },
     284        { "0x1 ",                       0,  VWRN_TRAILING_SPACES,   1 },
     285        { "0x0fffffffffffffff",         0,  VWRN_NUMBER_TOO_BIG,    0xffffffffU },
     286        { "0x0ffffffffffffffffffffff",  0,  VWRN_NUMBER_TOO_BIG,    0xffffffffU },
     287        { "asdfasdfasdf",               0,  VERR_NO_DIGITS,         0 },
     288        { "0x1111111",                  0,  VINF_SUCCESS,           0x1111111 },
    221289    };
    222290    RUN_TESTS(aTstU32, uint32_t, "%#x", RTStrToUInt32Ex);
    223291
     292
     293    static const struct TstU32 aTstFullU32[] =
     294    {
     295        { "0",                          0,  VINF_SUCCESS,           0 },
     296        { "0x0fffffffffffffff",         0,  VWRN_NUMBER_TOO_BIG,    0xffffffffU },
     297        { "0x0fffffffffffffffffffff",   0,  VWRN_NUMBER_TOO_BIG,    0xffffffffU },
     298        { "asdfasdfasdf",               0,  VERR_NO_DIGITS,         0 },
     299        { "42 ",                        0,  VERR_TRAILING_SPACES,   42 },
     300        { "42 ",                     2<<8,  VINF_SUCCESS,           42 },
     301        { "42! ",                       0,  VERR_TRAILING_CHARS,    42 },
     302        { "42! ",                    2<<8,  VINF_SUCCESS,           42 },
     303        { "42 !",                       0,  VERR_TRAILING_CHARS,    42 },
     304        { "42 !",                    2<<8,  VINF_SUCCESS,           42 },
     305        { "42 !",                    3<<8,  VERR_TRAILING_SPACES,   42 },
     306        { "42 !",                    4<<8,  VERR_TRAILING_CHARS,    42 },
     307        { "0x0fffffffffffffffffffff ",  0,  VERR_TRAILING_SPACES,   0xffffffffU },
     308        { "0x0fffffffffffffffffffff !", 0,  VERR_TRAILING_CHARS,    0xffffffffU },
     309    };
     310    RUN_FULL_TESTS(aTstFullU32, uint32_t, "%#x", RTStrToUInt32Full);
    224311
    225312    /*
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