upload http
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / test / teststr.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "test_apr.h"
18
19 #include <assert.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 #include "apr_general.h"
25 #include "apr_strings.h"
26 #include "apr_errno.h"
27
28 /* I haven't bothered to check for APR_ENOTIMPL here, AFAIK, all string
29  * functions exist on all platforms.
30  */
31
32 static void test_strtok(CuTest *tc)
33 {
34     struct {
35         char *input;
36         char *sep;
37     }
38     cases[] = {
39         {
40             "",
41             "Z"
42         },
43         {
44             "      asdf jkl; 77889909            \r\n\1\2\3Z",
45             " \r\n\3\2\1"
46         },
47         {
48             NULL,  /* but who cares if apr_strtok() segfaults? */
49             " \t"
50         },
51 #if 0     /* don't do this... you deserve to segfault */
52         {
53             "a b c              ",
54             NULL
55         },
56 #endif
57         {
58             "   a       b        c   ",
59             ""
60         },
61         {
62             "a              b c         ",
63             " "
64         }
65     };
66     int curtc;
67
68     for (curtc = 0; curtc < sizeof cases / sizeof cases[0]; curtc++) {
69         char *retval1, *retval2;
70         char *str1, *str2;
71         char *state;
72
73         str1 = apr_pstrdup(p, cases[curtc].input);
74         str2 = apr_pstrdup(p, cases[curtc].input);
75
76         do {
77             retval1 = apr_strtok(str1, cases[curtc].sep, &state);
78             retval2 = strtok(str2, cases[curtc].sep);
79
80             if (!retval1) {
81                 CuAssertTrue(tc, retval2 == NULL);
82             }
83             else {
84                 CuAssertTrue(tc, retval2 != NULL);
85                 CuAssertStrEquals(tc, retval2, retval1);
86             }
87
88             str1 = str2 = NULL; /* make sure we pass NULL on subsequent calls */
89         } while (retval1);
90     }
91 }
92
93 static void snprintf_noNULL(CuTest *tc)
94 {
95     char buff[100];
96     char *testing = apr_palloc(p, 10);
97
98     testing[0] = 't';
99     testing[1] = 'e';
100     testing[2] = 's';
101     testing[3] = 't';
102     testing[4] = 'i';
103     testing[5] = 'n';
104     testing[6] = 'g';
105     
106     /* If this test fails, we are going to seg fault. */
107     apr_snprintf(buff, sizeof(buff), "%.*s", 7, testing);
108     CuAssertStrNEquals(tc, buff, testing, 7);
109 }
110
111 static void snprintf_0NULL(CuTest *tc)
112 {
113     int rv;
114
115     rv = apr_snprintf(NULL, 0, "%sBAR", "FOO");
116     CuAssertIntEquals(tc, 6, rv);
117 }
118
119 static void snprintf_0nonNULL(CuTest *tc)
120 {
121     int rv;
122     char *buff = "testing";
123
124     rv = apr_snprintf(buff, 0, "%sBAR", "FOO");
125     CuAssertIntEquals(tc, 6, rv);
126     CuAssert(tc, "buff unmangled", strcmp(buff, "FOOBAR") != 0);
127 }
128
129 static void snprintf_int64(CuTest *tc)
130 {
131     char buf[100];
132     apr_int64_t i = APR_INT64_C(-42);
133     apr_uint64_t ui = APR_INT64_C(42); /* no APR_UINT64_C */
134     apr_uint64_t big = APR_INT64_C(3141592653589793238);
135
136     apr_snprintf(buf, sizeof buf, "%" APR_INT64_T_FMT, i);
137     CuAssertStrEquals(tc, buf, "-42");
138
139     apr_snprintf(buf, sizeof buf, "%" APR_UINT64_T_FMT, ui);
140     CuAssertStrEquals(tc, buf, "42");
141
142     apr_snprintf(buf, sizeof buf, "%" APR_UINT64_T_FMT, big);
143     CuAssertStrEquals(tc, buf, "3141592653589793238");
144 }
145
146 static void snprintf_underflow(CuTest *tc)
147 {
148     char buf[20];
149     int rv;
150
151     rv = apr_snprintf(buf, sizeof buf, "%.2f", (double)0.0001);
152     CuAssertIntEquals(tc, 4, rv);
153     CuAssertStrEquals(tc, "0.00", buf);
154     
155     rv = apr_snprintf(buf, sizeof buf, "%.2f", (double)0.001);
156     CuAssertIntEquals(tc, 4, rv);
157     CuAssertStrEquals(tc, "0.00", buf);
158     
159     rv = apr_snprintf(buf, sizeof buf, "%.2f", (double)0.01);
160     CuAssertIntEquals(tc, 4, rv);
161     CuAssertStrEquals(tc, "0.01", buf);
162 }
163
164 static void string_error(CuTest *tc)
165 {
166      char buf[128], *rv;
167      apr_status_t n;
168
169      buf[0] = '\0';
170      rv = apr_strerror(APR_ENOENT, buf, sizeof buf);
171      CuAssertPtrEquals(tc, buf, rv);
172      CuAssertTrue(tc, strlen(buf) > 0);
173
174      rv = apr_strerror(APR_TIMEUP, buf, sizeof buf);
175      CuAssertPtrEquals(tc, buf, rv);
176      CuAssertStrEquals(tc, "The timeout specified has expired", buf);
177      
178      /* throw some randomish numbers at it to check for robustness */
179      for (n = 1; n < 1000000; n *= 2) {
180          apr_strerror(n, buf, sizeof buf);
181      }
182 }
183
184 #define SIZE 180000
185 static void string_long(CuTest *tc)
186 {
187     char s[SIZE + 1];
188
189     memset(s, 'A', SIZE);
190     s[SIZE] = '\0';
191
192     apr_psprintf(p, "%s", s);
193 }
194
195 /* ### FIXME: apr.h/apr_strings.h should provide these! */
196 #define MY_LLONG_MAX (APR_INT64_C(9223372036854775807))
197 #define MY_LLONG_MIN (-MY_LLONG_MAX - APR_INT64_C(1))
198
199 static void string_strtoi64(CuTest *tc)
200 {
201     static const struct {
202         int errnum, base;
203         const char *in, *end;
204         apr_int64_t result;
205     } ts[] = {
206         
207         /* base 10 tests */
208         { 0, 10, "123545", NULL, APR_INT64_C(123545) },
209         { 0, 10, "   123545", NULL, APR_INT64_C(123545) },
210         { 0, 10, "   +123545", NULL, APR_INT64_C(123545) },
211         { 0, 10, "-123545", NULL, APR_INT64_C(-123545) },
212         { 0, 10, "   00000123545", NULL, APR_INT64_C(123545) },
213         { 0, 10, "123545ZZZ", "ZZZ", APR_INT64_C(123545) },
214         { 0, 10, "   123545   ", "   ", APR_INT64_C(123545) },
215
216         /* base 16 tests */
217         { 0, 16, "1E299", NULL, APR_INT64_C(123545) },
218         { 0, 16, "1e299", NULL, APR_INT64_C(123545) },
219         { 0, 16, "0x1e299", NULL, APR_INT64_C(123545) },
220         { 0, 16, "0X1E299", NULL, APR_INT64_C(123545) },
221         { 0, 16, "+1e299", NULL, APR_INT64_C(123545) },
222         { 0, 16, "-1e299", NULL, APR_INT64_C(-123545) },
223         { 0, 16, "   -1e299", NULL, APR_INT64_C(-123545) },
224
225         /* automatic base detection tests */
226         { 0, 0, "123545", NULL, APR_INT64_C(123545) },
227         { 0, 0, "0x1e299", NULL, APR_INT64_C(123545) },
228         { 0, 0, "  0x1e299", NULL, APR_INT64_C(123545) },
229         { 0, 0, "+0x1e299", NULL, APR_INT64_C(123545) },
230         { 0, 0, "-0x1e299", NULL, APR_INT64_C(-123545) },
231
232         /* large number tests */
233         { 0, 10, "8589934605", NULL, APR_INT64_C(8589934605) },
234         { 0, 10, "-8589934605", NULL, APR_INT64_C(-8589934605) },
235         { 0, 16, "0x20000000D", NULL, APR_INT64_C(8589934605) },
236         { 0, 16, "-0x20000000D", NULL, APR_INT64_C(-8589934605) },
237         { 0, 16, "   0x20000000D", NULL, APR_INT64_C(8589934605) },
238         { 0, 16, "   0x20000000D", NULL, APR_INT64_C(8589934605) },
239
240         /* error cases */
241         { ERANGE, 10, "999999999999999999999999999999999", "", MY_LLONG_MAX },
242         { ERANGE, 10, "-999999999999999999999999999999999", "", MY_LLONG_MIN },
243
244 #if 0
245         /* C99 doesn't require EINVAL for an invalid range. */
246         { EINVAL, 99, "", (void *)-1 /* don't care */, 0 },
247 #endif
248
249         /* some strtoll implementations give EINVAL when no conversion
250          * is performed. */
251         { -1 /* don't care */, 10, "zzz", "zzz", APR_INT64_C(0) },
252         { -1 /* don't care */, 10, "", NULL, APR_INT64_C(0) }
253
254     };
255     int n;
256
257     for (n = 0; n < sizeof(ts)/sizeof(ts[0]); n++) {
258         char *end = "end ptr not changed";
259         apr_int64_t result;
260         int errnum;
261         
262         errno = 0;
263         result = apr_strtoi64(ts[n].in, &end, ts[n].base);
264         errnum = errno;
265
266         CuAssert(tc,
267                  apr_psprintf(p, "for '%s': result was %" APR_INT64_T_FMT 
268                               " not %" APR_INT64_T_FMT, ts[n].in,
269                               result, ts[n].result),
270                  result == ts[n].result);
271         
272         if (ts[n].errnum != -1) {
273             CuAssert(tc,
274                      apr_psprintf(p, "for '%s': errno was %d not %d", ts[n].in,
275                                   errnum, ts[n].errnum),
276                      ts[n].errnum == errnum);
277         }
278
279         if (ts[n].end == NULL) {
280             /* end must point to NUL terminator of .in */
281             CuAssertPtrEquals(tc, ts[n].in + strlen(ts[n].in), end);
282         } else if (ts[n].end != (void *)-1) {
283             CuAssert(tc,
284                      apr_psprintf(p, "for '%s', end was '%s' not '%s'",
285                                   ts[n].in, end, ts[n].end),
286                      strcmp(ts[n].end, end) == 0);
287         }
288     }
289 }
290
291 CuSuite *teststr(void)
292 {
293     CuSuite *suite = CuSuiteNew("Strings");
294
295     SUITE_ADD_TEST(suite, snprintf_0NULL);
296     SUITE_ADD_TEST(suite, snprintf_0nonNULL);
297     SUITE_ADD_TEST(suite, snprintf_noNULL);
298     SUITE_ADD_TEST(suite, snprintf_int64);
299     SUITE_ADD_TEST(suite, snprintf_underflow);
300     SUITE_ADD_TEST(suite, test_strtok);
301     SUITE_ADD_TEST(suite, string_error);
302     SUITE_ADD_TEST(suite, string_long);
303     SUITE_ADD_TEST(suite, string_strtoi64);
304
305     return suite;
306 }
307