Annotation of embedaddon/libxml2/testdict.c, revision 1.1.1.1
1.1 misho 1: #include <string.h>
2: #include <libxml/parser.h>
3: #include <libxml/dict.h>
4:
5: /* #define WITH_PRINT */
6:
7: static const char *seeds1[] = {
8: "a", "b", "c",
9: "d", "e", "f",
10: "g", "h", "i",
11: "j", "k", "l",
12:
13: NULL
14: };
15:
16: static const char *seeds2[] = {
17: "m", "n", "o",
18: "p", "q", "r",
19: "s", "t", "u",
20: "v", "w", "x",
21:
22: NULL
23: };
24:
25: #define NB_STRINGS_NS 100
26: #define NB_STRINGS_MAX 10000
27: #define NB_STRINGS_MIN 10
28:
29: static xmlChar *strings1[NB_STRINGS_MAX];
30: static xmlChar *strings2[NB_STRINGS_MAX];
31: static const xmlChar *test1[NB_STRINGS_MAX];
32: static const xmlChar *test2[NB_STRINGS_MAX];
33: static int nbErrors = 0;
34:
35: static void fill_strings(void) {
36: int i, j, k;
37:
38: /*
39: * That's a bit nasty but the output is fine and it doesn't take hours
40: * there is a small but sufficient number of duplicates, and we have
41: * ":xxx" and full QNames in the last NB_STRINGS_NS values
42: */
43: for (i = 0; seeds1[i] != NULL; i++) {
44: strings1[i] = xmlStrdup((const xmlChar *) seeds1[i]);
45: if (strings1[i] == NULL) {
46: fprintf(stderr, "Out of memory while generating strings1\n");
47: exit(1);
48: }
49: }
50: for (j = 0, k = 0;i < NB_STRINGS_MAX - NB_STRINGS_NS;i++,j++) {
51: strings1[i] = xmlStrncatNew(strings1[j], strings1[k], -1);
52: if (strings1[i] == NULL) {
53: fprintf(stderr, "Out of memory while generating strings1\n");
54: exit(1);
55: }
56: if (j >= 50) {
57: j = 0;
58: k++;
59: }
60: }
61: for (j = 0; (j < 50) && (i < NB_STRINGS_MAX); i++, j+=2) {
62: strings1[i] = xmlStrncatNew(strings1[j], (const xmlChar *) ":", -1);
63: if (strings1[i] == NULL) {
64: fprintf(stderr, "Out of memory while generating strings1\n");
65: exit(1);
66: }
67: }
68: for (j = NB_STRINGS_MAX - NB_STRINGS_NS, k = 0;
69: i < NB_STRINGS_MAX;i++,j++) {
70: strings1[i] = xmlStrncatNew(strings1[j], strings1[k], -1);
71: if (strings1[i] == NULL) {
72: fprintf(stderr, "Out of memory while generating strings1\n");
73: exit(1);
74: }
75: k += 3;
76: if (k >= 50) k = 0;
77: }
78:
79: /*
80: * Now do the same with the second pool of strings
81: */
82: for (i = 0; seeds2[i] != NULL; i++) {
83: strings2[i] = xmlStrdup((const xmlChar *) seeds2[i]);
84: if (strings2[i] == NULL) {
85: fprintf(stderr, "Out of memory while generating strings2\n");
86: exit(1);
87: }
88: }
89: for (j = 0, k = 0;i < NB_STRINGS_MAX - NB_STRINGS_NS;i++,j++) {
90: strings2[i] = xmlStrncatNew(strings2[j], strings2[k], -1);
91: if (strings2[i] == NULL) {
92: fprintf(stderr, "Out of memory while generating strings2\n");
93: exit(1);
94: }
95: if (j >= 50) {
96: j = 0;
97: k++;
98: }
99: }
100: for (j = 0; (j < 50) && (i < NB_STRINGS_MAX); i++, j+=2) {
101: strings2[i] = xmlStrncatNew(strings2[j], (const xmlChar *) ":", -1);
102: if (strings2[i] == NULL) {
103: fprintf(stderr, "Out of memory while generating strings2\n");
104: exit(1);
105: }
106: }
107: for (j = NB_STRINGS_MAX - NB_STRINGS_NS, k = 0;
108: i < NB_STRINGS_MAX;i++,j++) {
109: strings2[i] = xmlStrncatNew(strings2[j], strings2[k], -1);
110: if (strings2[i] == NULL) {
111: fprintf(stderr, "Out of memory while generating strings2\n");
112: exit(1);
113: }
114: k += 3;
115: if (k >= 50) k = 0;
116: }
117:
118: }
119:
120: #ifdef WITH_PRINT
121: static void print_strings(void) {
122: int i;
123:
124: for (i = 0; i < NB_STRINGS_MAX;i++) {
125: printf("%s\n", strings1[i]);
126: }
127: for (i = 0; i < NB_STRINGS_MAX;i++) {
128: printf("%s\n", strings2[i]);
129: }
130: }
131: #endif
132:
133: static void clean_strings(void) {
134: int i;
135:
136: for (i = 0; i < NB_STRINGS_MAX; i++) {
137: if (strings1[i] != NULL) /* really should not happen */
138: xmlFree(strings1[i]);
139: }
140: for (i = 0; i < NB_STRINGS_MAX; i++) {
141: if (strings2[i] != NULL) /* really should not happen */
142: xmlFree(strings2[i]);
143: }
144: }
145:
146: /*
147: * This tests the sub-dictionary support
148: */
149: static int run_test2(xmlDictPtr parent) {
150: int i, j;
151: xmlDictPtr dict;
152: int ret = 0;
153: xmlChar prefix[40];
154: xmlChar *cur, *pref;
155: const xmlChar *tmp;
156:
157: dict = xmlDictCreateSub(parent);
158: if (dict == NULL) {
159: fprintf(stderr, "Out of memory while creating sub-dictionary\n");
160: exit(1);
161: }
162: memset(test2, 0, sizeof(test2));
163:
164: /*
165: * Fill in NB_STRINGS_MIN, at this point the dictionary should not grow
166: * and we allocate all those doing the fast key computations
167: * All the strings are based on a different seeds subset so we know
168: * they are allocated in the main dictionary, not coming from the parent
169: */
170: for (i = 0;i < NB_STRINGS_MIN;i++) {
171: test2[i] = xmlDictLookup(dict, strings2[i], -1);
172: if (test2[i] == NULL) {
173: fprintf(stderr, "Failed lookup for '%s'\n", strings2[i]);
174: ret = 1;
175: nbErrors++;
176: }
177: }
178: j = NB_STRINGS_MAX - NB_STRINGS_NS;
179: /* ":foo" like strings2 */
180: for (i = 0;i < NB_STRINGS_MIN;i++, j++) {
181: test2[j] = xmlDictLookup(dict, strings2[j], xmlStrlen(strings2[j]));
182: if (test2[j] == NULL) {
183: fprintf(stderr, "Failed lookup for '%s'\n", strings2[j]);
184: ret = 1;
185: nbErrors++;
186: }
187: }
188: /* "a:foo" like strings2 */
189: j = NB_STRINGS_MAX - NB_STRINGS_MIN;
190: for (i = 0;i < NB_STRINGS_MIN;i++, j++) {
191: test2[j] = xmlDictLookup(dict, strings2[j], xmlStrlen(strings2[j]));
192: if (test2[j] == NULL) {
193: fprintf(stderr, "Failed lookup for '%s'\n", strings2[j]);
194: ret = 1;
195: nbErrors++;
196: }
197: }
198:
199: /*
200: * At this point allocate all the strings
201: * the dictionary will grow in the process, reallocate more string tables
202: * and switch to the better key generator
203: */
204: for (i = 0;i < NB_STRINGS_MAX;i++) {
205: if (test2[i] != NULL)
206: continue;
207: test2[i] = xmlDictLookup(dict, strings2[i], -1);
208: if (test2[i] == NULL) {
209: fprintf(stderr, "Failed lookup for '%s'\n", strings2[i]);
210: ret = 1;
211: nbErrors++;
212: }
213: }
214:
215: /*
216: * Now we can start to test things, first that all strings2 belongs to
217: * the dict, and that none of them was actually allocated in the parent
218: */
219: for (i = 0;i < NB_STRINGS_MAX;i++) {
220: if (!xmlDictOwns(dict, test2[i])) {
221: fprintf(stderr, "Failed ownership failure for '%s'\n",
222: strings2[i]);
223: ret = 1;
224: nbErrors++;
225: }
226: if (xmlDictOwns(parent, test2[i])) {
227: fprintf(stderr, "Failed parent ownership failure for '%s'\n",
228: strings2[i]);
229: ret = 1;
230: nbErrors++;
231: }
232: }
233:
234: /*
235: * Also verify that all strings from the parent are seen from the subdict
236: */
237: for (i = 0;i < NB_STRINGS_MAX;i++) {
238: if (!xmlDictOwns(dict, test1[i])) {
239: fprintf(stderr, "Failed sub-ownership failure for '%s'\n",
240: strings1[i]);
241: ret = 1;
242: nbErrors++;
243: }
244: }
245:
246: /*
247: * Then that another lookup to the string in sub will return the same
248: */
249: for (i = 0;i < NB_STRINGS_MAX;i++) {
250: if (xmlDictLookup(dict, strings2[i], -1) != test2[i]) {
251: fprintf(stderr, "Failed re-lookup check for %d, '%s'\n",
252: i, strings2[i]);
253: ret = 1;
254: nbErrors++;
255: }
256: }
257: /*
258: * But also that any lookup for a string in the parent will be provided
259: * as in the parent
260: */
261: for (i = 0;i < NB_STRINGS_MAX;i++) {
262: if (xmlDictLookup(dict, strings1[i], -1) != test1[i]) {
263: fprintf(stderr, "Failed parent string lookup check for %d, '%s'\n",
264: i, strings1[i]);
265: ret = 1;
266: nbErrors++;
267: }
268: }
269:
270: /*
271: * check the QName lookups
272: */
273: for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) {
274: cur = strings2[i];
275: pref = &prefix[0];
276: while (*cur != ':') *pref++ = *cur++;
277: cur++;
278: *pref = 0;
279: tmp = xmlDictQLookup(dict, &prefix[0], cur);
280: if (xmlDictQLookup(dict, &prefix[0], cur) != test2[i]) {
281: fprintf(stderr, "Failed lookup check for '%s':'%s'\n",
282: &prefix[0], cur);
283: ret = 1;
284: nbErrors++;
285: }
286: }
287: /*
288: * check the QName lookups for strings from the parent
289: */
290: for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) {
291: cur = strings1[i];
292: pref = &prefix[0];
293: while (*cur != ':') *pref++ = *cur++;
294: cur++;
295: *pref = 0;
296: tmp = xmlDictQLookup(dict, &prefix[0], cur);
297: if (xmlDictQLookup(dict, &prefix[0], cur) != test1[i]) {
298: fprintf(stderr, "Failed parent lookup check for '%s':'%s'\n",
299: &prefix[0], cur);
300: ret = 1;
301: nbErrors++;
302: }
303: }
304:
305: xmlDictFree(dict);
306: return(ret);
307: }
308:
309: /*
310: * Test a single dictionary
311: */
312: static int run_test1(void) {
313: int i, j;
314: xmlDictPtr dict;
315: int ret = 0;
316: xmlChar prefix[40];
317: xmlChar *cur, *pref;
318: const xmlChar *tmp;
319:
320: dict = xmlDictCreate();
321: if (dict == NULL) {
322: fprintf(stderr, "Out of memory while creating dictionary\n");
323: exit(1);
324: }
325: memset(test1, 0, sizeof(test1));
326:
327: /*
328: * Fill in NB_STRINGS_MIN, at this point the dictionary should not grow
329: * and we allocate all those doing the fast key computations
330: */
331: for (i = 0;i < NB_STRINGS_MIN;i++) {
332: test1[i] = xmlDictLookup(dict, strings1[i], -1);
333: if (test1[i] == NULL) {
334: fprintf(stderr, "Failed lookup for '%s'\n", strings1[i]);
335: ret = 1;
336: nbErrors++;
337: }
338: }
339: j = NB_STRINGS_MAX - NB_STRINGS_NS;
340: /* ":foo" like strings1 */
341: for (i = 0;i < NB_STRINGS_MIN;i++, j++) {
342: test1[j] = xmlDictLookup(dict, strings1[j], xmlStrlen(strings1[j]));
343: if (test1[j] == NULL) {
344: fprintf(stderr, "Failed lookup for '%s'\n", strings1[j]);
345: ret = 1;
346: nbErrors++;
347: }
348: }
349: /* "a:foo" like strings1 */
350: j = NB_STRINGS_MAX - NB_STRINGS_MIN;
351: for (i = 0;i < NB_STRINGS_MIN;i++, j++) {
352: test1[j] = xmlDictLookup(dict, strings1[j], xmlStrlen(strings1[j]));
353: if (test1[j] == NULL) {
354: fprintf(stderr, "Failed lookup for '%s'\n", strings1[j]);
355: ret = 1;
356: nbErrors++;
357: }
358: }
359:
360: /*
361: * At this point allocate all the strings
362: * the dictionary will grow in the process, reallocate more string tables
363: * and switch to the better key generator
364: */
365: for (i = 0;i < NB_STRINGS_MAX;i++) {
366: if (test1[i] != NULL)
367: continue;
368: test1[i] = xmlDictLookup(dict, strings1[i], -1);
369: if (test1[i] == NULL) {
370: fprintf(stderr, "Failed lookup for '%s'\n", strings1[i]);
371: ret = 1;
372: nbErrors++;
373: }
374: }
375:
376: /*
377: * Now we can start to test things, first that all strings1 belongs to
378: * the dict
379: */
380: for (i = 0;i < NB_STRINGS_MAX;i++) {
381: if (!xmlDictOwns(dict, test1[i])) {
382: fprintf(stderr, "Failed ownership failure for '%s'\n",
383: strings1[i]);
384: ret = 1;
385: nbErrors++;
386: }
387: }
388:
389: /*
390: * Then that another lookup to the string will return the same
391: */
392: for (i = 0;i < NB_STRINGS_MAX;i++) {
393: if (xmlDictLookup(dict, strings1[i], -1) != test1[i]) {
394: fprintf(stderr, "Failed re-lookup check for %d, '%s'\n",
395: i, strings1[i]);
396: ret = 1;
397: nbErrors++;
398: }
399: }
400:
401: /*
402: * More complex, check the QName lookups
403: */
404: for (i = NB_STRINGS_MAX - NB_STRINGS_NS;i < NB_STRINGS_MAX;i++) {
405: cur = strings1[i];
406: pref = &prefix[0];
407: while (*cur != ':') *pref++ = *cur++;
408: cur++;
409: *pref = 0;
410: tmp = xmlDictQLookup(dict, &prefix[0], cur);
411: if (xmlDictQLookup(dict, &prefix[0], cur) != test1[i]) {
412: fprintf(stderr, "Failed lookup check for '%s':'%s'\n",
413: &prefix[0], cur);
414: ret = 1;
415: nbErrors++;
416: }
417: }
418:
419: run_test2(dict);
420:
421: xmlDictFree(dict);
422: return(ret);
423: }
424:
425: int main(void)
426: {
427: int ret;
428:
429: LIBXML_TEST_VERSION
430: fill_strings();
431: #ifdef WITH_PRINT
432: print_strings();
433: #endif
434: ret = run_test1();
435: if (ret == 0) {
436: printf("dictionary tests succeeded %d strings\n", 2 * NB_STRINGS_MAX);
437: } else {
438: printf("dictionary tests failed with %d errors\n", nbErrors);
439: }
440: clean_strings();
441: xmlCleanupParser();
442: xmlMemoryDump();
443: return(ret);
444: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>