apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jor...@apache.org
Subject cvs commit: apr/test teststr.c
Date Sun, 04 Apr 2004 14:54:17 GMT
jorton      2004/04/04 07:54:17

  Modified:    strings  apr_strings.c
               test     teststr.c
  Log:
  * strings/apr_strings.c (apr_strtoi64): Fix handling of negative
  integers on platforms without strtoll.
  
  * test/teststr.c (string_strtoi64): New function.
  
  Revision  Changes    Path
  1.44      +2 -2      apr/strings/apr_strings.c
  
  Index: apr_strings.c
  ===================================================================
  RCS file: /home/cvs/apr/strings/apr_strings.c,v
  retrieving revision 1.43
  retrieving revision 1.44
  diff -w -d -u -r1.43 -r1.44
  --- apr_strings.c	13 Feb 2004 09:38:34 -0000	1.43
  +++ apr_strings.c	4 Apr 2004 14:54:17 -0000	1.44
  @@ -278,7 +278,7 @@
       }
   
       /* The classic bsd implementation requires div/mod operators
  -     * to compute a cutoff.  Benchmarking proves that iss very, very
  +     * to compute a cutoff.  Benchmarking proves that is very, very
        * evil to some 32 bit processors.  Instead, look for underflow
        * in both the mult and add/sub operation.  Unlike the bsd impl,
        * we also work strictly in a signed int64 word as we haven't
  @@ -319,7 +319,7 @@
   	val *= base;
           if ( (any < 0)	/* already noted an over/under flow - short circuit */
              || (neg && (val > acc || (val -= c) > acc)) /* underflow */
  -           || (val < acc || (val += c) < acc)) {       /* overflow */
  +           || (!neg && (val < acc || (val += c) < acc))) {       /* overflow
*/
               any = -1;	/* once noted, over/underflows never go away */
   #ifdef APR_STRTOI64_OVERFLOW_IS_BAD_CHAR
               break;
  
  
  
  1.19      +97 -0     apr/test/teststr.c
  
  Index: teststr.c
  ===================================================================
  RCS file: /home/cvs/apr/test/teststr.c,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -w -d -u -r1.18 -r1.19
  --- teststr.c	13 Feb 2004 09:38:34 -0000	1.18
  +++ teststr.c	4 Apr 2004 14:54:17 -0000	1.19
  @@ -150,6 +150,102 @@
       apr_psprintf(p, "%s", s);
   }
   
  +/* ### FIXME: apr.h/apr_strings.h should provide these! */
  +#define MY_LLONG_MAX (APR_INT64_C(9223372036854775807))
  +#define MY_LLONG_MIN (-MY_LLONG_MAX - APR_INT64_C(1))
  +
  +static void string_strtoi64(CuTest *tc)
  +{
  +    static const struct {
  +        int errnum, base;
  +        const char *in, *end;
  +        apr_int64_t result;
  +    } ts[] = {
  +        
  +        /* base 10 tests */
  +        { 0, 10, "123545", NULL, APR_INT64_C(123545) },
  +        { 0, 10, "   123545", NULL, APR_INT64_C(123545) },
  +        { 0, 10, "   +123545", NULL, APR_INT64_C(123545) },
  +        { 0, 10, "-123545", NULL, APR_INT64_C(-123545) },
  +        { 0, 10, "   00000123545", NULL, APR_INT64_C(123545) },
  +        { 0, 10, "123545ZZZ", "ZZZ", APR_INT64_C(123545) },
  +        { 0, 10, "   123545   ", "   ", APR_INT64_C(123545) },
  +
  +        /* base 16 tests */
  +        { 0, 16, "1E299", NULL, APR_INT64_C(123545) },
  +        { 0, 16, "1e299", NULL, APR_INT64_C(123545) },
  +        { 0, 16, "0x1e299", NULL, APR_INT64_C(123545) },
  +        { 0, 16, "0X1E299", NULL, APR_INT64_C(123545) },
  +        { 0, 16, "+1e299", NULL, APR_INT64_C(123545) },
  +        { 0, 16, "-1e299", NULL, APR_INT64_C(-123545) },
  +        { 0, 16, "   -1e299", NULL, APR_INT64_C(-123545) },
  +
  +        /* automatic base detection tests */
  +        { 0, 0, "123545", NULL, APR_INT64_C(123545) },
  +        { 0, 0, "0x1e299", NULL, APR_INT64_C(123545) },
  +        { 0, 0, "  0x1e299", NULL, APR_INT64_C(123545) },
  +        { 0, 0, "+0x1e299", NULL, APR_INT64_C(123545) },
  +        { 0, 0, "-0x1e299", NULL, APR_INT64_C(-123545) },
  +
  +        /* large number tests */
  +        { 0, 10, "8589934605", NULL, APR_INT64_C(8589934605) },
  +        { 0, 10, "-8589934605", NULL, APR_INT64_C(-8589934605) },
  +        { 0, 16, "0x20000000D", NULL, APR_INT64_C(8589934605) },
  +        { 0, 16, "-0x20000000D", NULL, APR_INT64_C(-8589934605) },
  +        { 0, 16, "   0x20000000D", NULL, APR_INT64_C(8589934605) },
  +        { 0, 16, "   0x20000000D", NULL, APR_INT64_C(8589934605) },
  +
  +        /* error cases */
  +        { ERANGE, 10, "999999999999999999999999999999999", "", MY_LLONG_MAX },
  +        { ERANGE, 10, "-999999999999999999999999999999999", "", MY_LLONG_MIN },
  +
  +#if 0
  +        /* C99 doesn't require EINVAL for an invalid range. */
  +        { EINVAL, 99, "", (void *)-1 /* don't care */, 0 },
  +#endif
  +
  +        /* some strtoll implementations give EINVAL when no conversion
  +         * is performed. */
  +        { -1 /* don't care */, 10, "zzz", "zzz", APR_INT64_C(0) },
  +        { -1 /* don't care */, 10, "", NULL, APR_INT64_C(0) }
  +
  +    };
  +    int n;
  +
  +    for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) {
  +        char *end = "end ptr not changed";
  +        apr_int64_t result;
  +        int errnum;
  +        
  +        errno = 0;
  +        result = apr_strtoi64(ts[n].in, &end, ts[n].base);
  +        errnum = errno;
  +
  +        CuAssert(tc,
  +                 apr_psprintf(p, "for '%s': result was %" APR_INT64_T_FMT 
  +                              " not %" APR_INT64_T_FMT, ts[n].in,
  +                              result, ts[n].result),
  +                 result == ts[n].result);
  +        
  +        if (ts[n].errnum != -1) {
  +            CuAssert(tc,
  +                     apr_psprintf(p, "for '%s': errno was %d not %d", ts[n].in,
  +                                  errnum, ts[n].errnum),
  +                     ts[n].errnum == errnum);
  +        }
  +
  +        if (ts[n].end == NULL) {
  +            /* end must point to NUL terminator of .in */
  +            CuAssertPtrEquals(tc, ts[n].in + strlen(ts[n].in), end);
  +        } else if (ts[n].end != (void *)-1) {
  +            CuAssert(tc,
  +                     apr_psprintf(p, "for '%s', end was '%s' not '%s'",
  +                                  ts[n].in, end, ts[n].end),
  +                     strcmp(ts[n].end, end) == 0);
  +        }
  +    }
  +}
  +
   CuSuite *teststr(void)
   {
       CuSuite *suite = CuSuiteNew("Strings");
  @@ -160,6 +256,7 @@
       SUITE_ADD_TEST(suite, test_strtok);
       SUITE_ADD_TEST(suite, string_error);
       SUITE_ADD_TEST(suite, string_long);
  +    SUITE_ADD_TEST(suite, string_strtoi64);
   
       return suite;
   }
  
  
  

Mime
View raw message