blob: fd94b03c18655e23e2f623361b599565988c0263 [file] [log] [blame]
Benny Prijono5dcb38d2005-11-21 01:55:47 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#include <pj/string.h>
20#include <pj/pool.h>
21#include <pj/log.h>
Benny Prijonoa7944bb2005-11-21 17:01:50 +000022#include <pj/os.h>
Benny Prijono5dcb38d2005-11-21 01:55:47 +000023#include "test.h"
24
25/**
26 * \page page_pjlib_string_test Test: String
27 *
28 * This file provides implementation of \b string_test(). It tests the
29 * functionality of the string API.
30 *
31 * \section sleep_test_sec Scope of the Test
32 *
33 * API tested:
34 * - pj_str()
35 * - pj_strcmp()
36 * - pj_strcmp2()
37 * - pj_stricmp()
38 * - pj_strlen()
39 * - pj_strncmp()
40 * - pj_strnicmp()
41 * - pj_strchr()
42 * - pj_strdup()
43 * - pj_strdup2()
44 * - pj_strcpy()
45 * - pj_strcat()
46 * - pj_strtrim()
47 * - pj_utoa()
48 * - pj_strtoul()
49 * - pj_create_random_string()
50 *
51 *
52 * This file is <b>pjlib-test/string.c</b>
53 *
54 * \include pjlib-test/string.c
55 */
56
57#if INCLUDE_STRING_TEST
58
59#ifdef _MSC_VER
60# pragma warning(disable: 4204)
61#endif
62
63#define HELLO_WORLD "Hello World"
64#define JUST_HELLO "Hello"
65#define UL_VALUE 3456789012UL
66
Benny Prijonoa7944bb2005-11-21 17:01:50 +000067static int stricmp_test(void)
68{
69#define STRTEST(res,S1,S2,code) \
70 do { \
71 s1.ptr=S1; s1.slen=len; \
72 s2.ptr=S2; s2.slen=len; \
73 pj_get_timestamp(&t1); \
74 if (pj_stricmp(&s1,&s2)!=res) return code; \
75 pj_get_timestamp(&t2); \
76 pj_sub_timestamp(&t2, &t1); \
77 pj_add_timestamp(&e1, &t2); \
78 pj_get_timestamp(&t1); \
79 if (pj_stricmp_alnum(&s1,&s2)!=res) return code-1; \
80 pj_get_timestamp(&t2); \
81 pj_sub_timestamp(&t2, &t1); \
82 pj_add_timestamp(&e2, &t2); \
83 } while (0)
84
85 char *buf;
86 pj_str_t s1, s2;
87 pj_timestamp t1, t2, e1, e2, zero;
88 pj_uint32_t c1, c2;
89 int len;
90
91 e1.u32.hi = e1.u32.lo = e2.u32.hi = e2.u32.lo = 0;
92
93 pj_thread_sleep(0);
94
95 /* Compare empty strings. */
96 len=0;
97 STRTEST( 0, "","",-500);
98
99 /* equal, length=1
100 * use buffer to simulate non-aligned string.
101 */
102 buf = "a""A";
103 len=1;
104 STRTEST( 0, "a",buf+0,-510);
105 STRTEST( 0, "a",buf+1,-512);
106
107 /* equal, length=2
108 * use buffer to simulate non-aligned string.
109 */
110 buf = "aa""Aa""aA""AA";
111 len=2;
112 STRTEST( 0, "aa",buf+0,-520);
113 STRTEST( 0, "aa",buf+2,-522);
114 STRTEST( 0, "aa",buf+4,-524);
115 STRTEST( 0, "aa",buf+6,-524);
116
117 /* equal, length=3
118 * use buffer to simulate non-aligned string.
119 */
120 buf = "aaa""Aaa""aAa""aaA""AAa""aAA""AaA""AAA";
121 len=3;
122 STRTEST( 0, "aaa",buf+0,-530);
123 STRTEST( 0, "aaa",buf+3,-532);
124 STRTEST( 0, "aaa",buf+6,-534);
125 STRTEST( 0, "aaa",buf+9,-536);
126 STRTEST( 0, "aaa",buf+12,-538);
127 STRTEST( 0, "aaa",buf+15,-540);
128 STRTEST( 0, "aaa",buf+18,-542);
129 STRTEST( 0, "aaa",buf+21,-534);
130
131 /* equal, length=4 */
132 len=4;
133 STRTEST( 0, "aaaa","aaaa",-540);
134 STRTEST( 0, "aaaa","Aaaa",-542);
135 STRTEST( 0, "aaaa","aAaa",-544);
136 STRTEST( 0, "aaaa","aaAa",-546);
137 STRTEST( 0, "aaaa","aaaA",-548);
138 STRTEST( 0, "aaaa","AAaa",-550);
139 STRTEST( 0, "aaaa","aAAa",-552);
140 STRTEST( 0, "aaaa","aaAA",-554);
141 STRTEST( 0, "aaaa","AaAa",-556);
142 STRTEST( 0, "aaaa","aAaA",-558);
143 STRTEST( 0, "aaaa","AaaA",-560);
144 STRTEST( 0, "aaaa","AAAa",-562);
145 STRTEST( 0, "aaaa","aAAA",-564);
146 STRTEST( 0, "aaaa","AAaA",-566);
147 STRTEST( 0, "aaaa","AaAA",-568);
148 STRTEST( 0, "aaaa","AAAA",-570);
149
150 /* equal, length=5 */
151 buf = "aaaAa""AaaaA""AaAaA""AAAAA";
152 len=5;
153 STRTEST( 0, "aaaaa",buf+0,-580);
154 STRTEST( 0, "aaaaa",buf+5,-582);
155 STRTEST( 0, "aaaaa",buf+10,-584);
156 STRTEST( 0, "aaaaa",buf+15,-586);
157
158 /* not equal, length=1 */
159 len=1;
160 STRTEST( -1, "a", "b", -600);
161
162 /* not equal, length=2 */
163 buf = "ab""ba";
164 len=2;
165 STRTEST( -1, "aa", buf+0, -610);
166 STRTEST( -1, "aa", buf+2, -612);
167
168 /* not equal, length=3 */
169 buf = "aab""aba""baa";
170 len=3;
171 STRTEST( -1, "aaa", buf+0, -620);
172 STRTEST( -1, "aaa", buf+3, -622);
173 STRTEST( -1, "aaa", buf+6, -624);
174
175 /* not equal, length=4 */
176 buf = "aaab""aaba""abaa""baaa";
177 len=4;
178 STRTEST( -1, "aaaa", buf+0, -630);
179 STRTEST( -1, "aaaa", buf+4, -632);
180 STRTEST( -1, "aaaa", buf+8, -634);
181 STRTEST( -1, "aaaa", buf+12, -636);
182
183 /* not equal, length=5 */
184 buf="aaaab""aaaba""aabaa""abaaa""baaaa";
185 len=5;
186 STRTEST( -1, "aaaaa", buf+0, -640);
187 STRTEST( -1, "aaaaa", buf+5, -642);
188 STRTEST( -1, "aaaaa", buf+10, -644);
189 STRTEST( -1, "aaaaa", buf+15, -646);
190 STRTEST( -1, "aaaaa", buf+20, -648);
191
192 zero.u32.hi = zero.u32.lo = 0;
193 c1 = pj_elapsed_cycle(&zero, &e1);
194 c2 = pj_elapsed_cycle(&zero, &e2);
195
196 if (c1 < c2) {
197 PJ_LOG(3,("", " error: pj_stricmp_alnum is slower than pj_stricmp!"));
198 return -700;
199 }
200
201 PJ_LOG(3, ("", " time: stricmp=%u, stricmp_alnum=%u (speedup=%d.%02dx)",
202 c1, c2,
203 (c1 * 100 / c2) / 100,
204 (c1 * 100 / c2) % 100));
205 return 0;
206#undef STRTEST
207}
208
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000209int string_test(void)
210{
211 const pj_str_t hello_world = { HELLO_WORLD, strlen(HELLO_WORLD) };
212 const pj_str_t just_hello = { JUST_HELLO, strlen(JUST_HELLO) };
213 pj_str_t s1, s2, s3, s4, s5;
214 enum { RCOUNT = 10, RLEN = 16 };
215 pj_str_t random[RCOUNT];
216 pj_pool_t *pool;
217 int i;
218
219 pool = pj_pool_create(mem, NULL, 4096, 0, NULL);
220 if (!pool) return -5;
221
222 /*
223 * pj_str(), pj_strcmp(), pj_stricmp(), pj_strlen(),
224 * pj_strncmp(), pj_strchr()
225 */
226 s1 = pj_str(HELLO_WORLD);
227 if (pj_strcmp(&s1, &hello_world) != 0)
228 return -10;
229 if (pj_stricmp(&s1, &hello_world) != 0)
230 return -20;
231 if (pj_strcmp(&s1, &just_hello) <= 0)
232 return -30;
233 if (pj_stricmp(&s1, &just_hello) <= 0)
234 return -40;
235 if (pj_strlen(&s1) != strlen(HELLO_WORLD))
236 return -50;
237 if (pj_strncmp(&s1, &hello_world, 5) != 0)
238 return -60;
239 if (pj_strnicmp(&s1, &hello_world, 5) != 0)
240 return -70;
241 if (pj_strchr(&s1, HELLO_WORLD[1]) != s1.ptr+1)
242 return -80;
243
244 /*
245 * pj_strdup()
246 */
247 if (!pj_strdup(pool, &s2, &s1))
248 return -100;
249 if (pj_strcmp(&s1, &s2) != 0)
250 return -110;
251
252 /*
253 * pj_strcpy(), pj_strcat()
254 */
255 s3.ptr = pj_pool_alloc(pool, 256);
256 if (!s3.ptr)
257 return -200;
258 pj_strcpy(&s3, &s2);
259 pj_strcat(&s3, &just_hello);
260
261 if (pj_strcmp2(&s3, HELLO_WORLD JUST_HELLO) != 0)
262 return -210;
263
264 /*
265 * pj_strdup2(), pj_strtrim().
266 */
267 pj_strdup2(pool, &s4, " " HELLO_WORLD "\t ");
268 pj_strtrim(&s4);
269 if (pj_strcmp2(&s4, HELLO_WORLD) != 0)
270 return -250;
271
272 /*
273 * pj_utoa()
274 */
275 s5.ptr = pj_pool_alloc(pool, 16);
276 if (!s5.ptr)
277 return -270;
278 s5.slen = pj_utoa(UL_VALUE, s5.ptr);
279
280 /*
281 * pj_strtoul()
282 */
283 if (pj_strtoul(&s5) != UL_VALUE)
284 return -280;
285
286 /*
287 * pj_create_random_string()
288 * Check that no duplicate strings are returned.
289 */
290 for (i=0; i<RCOUNT; ++i) {
291 int j;
292
293 random[i].ptr = pj_pool_alloc(pool, RLEN);
294 if (!random[i].ptr)
295 return -320;
296
297 random[i].slen = RLEN;
298 pj_create_random_string(random[i].ptr, RLEN);
299
300 for (j=0; j<i; ++j) {
301 if (pj_strcmp(&random[i], &random[j])==0)
302 return -330;
303 }
304 }
305
306 /* Done. */
307 pj_pool_release(pool);
Benny Prijonoa7944bb2005-11-21 17:01:50 +0000308
309 return stricmp_test();
Benny Prijono5dcb38d2005-11-21 01:55:47 +0000310}
311
312#else
313/* To prevent warning about "translation unit is empty"
314 * when this test is disabled.
315 */
316int dummy_string_test;
317#endif /* INCLUDE_STRING_TEST */
318