2 #include <libxml/parser.h>
3 #include <libxml/dict.h>
5 /* #define WITH_PRINT */
7 static const char *seeds1
[] = {
16 static const char *seeds2
[] = {
25 #define NB_STRINGS_NS 100
26 #define NB_STRINGS_MAX 10000
27 #define NB_STRINGS_MIN 10
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;
35 static void fill_strings(void) {
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
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");
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");
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");
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");
80 * Now do the same with the second pool of strings
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");
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");
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");
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");
121 static void print_strings(void) {
124 for (i
= 0; i
< NB_STRINGS_MAX
;i
++) {
125 printf("%s\n", strings1
[i
]);
127 for (i
= 0; i
< NB_STRINGS_MAX
;i
++) {
128 printf("%s\n", strings2
[i
]);
133 static void clean_strings(void) {
136 for (i
= 0; i
< NB_STRINGS_MAX
; i
++) {
137 if (strings1
[i
] != NULL
) /* really should not happen */
138 xmlFree(strings1
[i
]);
140 for (i
= 0; i
< NB_STRINGS_MAX
; i
++) {
141 if (strings2
[i
] != NULL
) /* really should not happen */
142 xmlFree(strings2
[i
]);
147 * This tests the sub-dictionary support
149 static int run_test2(xmlDictPtr parent
) {
157 dict
= xmlDictCreateSub(parent
);
159 fprintf(stderr
, "Out of memory while creating sub-dictionary\n");
162 memset(test2
, 0, sizeof(test2
));
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
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
]);
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
]);
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
]);
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
204 for (i
= 0;i
< NB_STRINGS_MAX
;i
++) {
205 if (test2
[i
] != NULL
)
207 test2
[i
] = xmlDictLookup(dict
, strings2
[i
], -1);
208 if (test2
[i
] == NULL
) {
209 fprintf(stderr
, "Failed lookup for '%s'\n", strings2
[i
]);
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
219 for (i
= 0;i
< NB_STRINGS_MAX
;i
++) {
220 if (!xmlDictOwns(dict
, test2
[i
])) {
221 fprintf(stderr
, "Failed ownership failure for '%s'\n",
226 if (xmlDictOwns(parent
, test2
[i
])) {
227 fprintf(stderr
, "Failed parent ownership failure for '%s'\n",
235 * Also verify that all strings from the parent are seen from the subdict
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",
247 * Then that another lookup to the string in sub will return the same
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",
258 * But also that any lookup for a string in the parent will be provided
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",
271 * check the QName lookups
273 for (i
= NB_STRINGS_MAX
- NB_STRINGS_NS
;i
< NB_STRINGS_MAX
;i
++) {
276 while (*cur
!= ':') *pref
++ = *cur
++;
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",
288 * check the QName lookups for strings from the parent
290 for (i
= NB_STRINGS_MAX
- NB_STRINGS_NS
;i
< NB_STRINGS_MAX
;i
++) {
293 while (*cur
!= ':') *pref
++ = *cur
++;
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",
310 * Test a single dictionary
312 static int run_test1(void) {
320 dict
= xmlDictCreate();
322 fprintf(stderr
, "Out of memory while creating dictionary\n");
325 memset(test1
, 0, sizeof(test1
));
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
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
]);
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
]);
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
]);
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
365 for (i
= 0;i
< NB_STRINGS_MAX
;i
++) {
366 if (test1
[i
] != NULL
)
368 test1
[i
] = xmlDictLookup(dict
, strings1
[i
], -1);
369 if (test1
[i
] == NULL
) {
370 fprintf(stderr
, "Failed lookup for '%s'\n", strings1
[i
]);
377 * Now we can start to test things, first that all strings1 belongs to
380 for (i
= 0;i
< NB_STRINGS_MAX
;i
++) {
381 if (!xmlDictOwns(dict
, test1
[i
])) {
382 fprintf(stderr
, "Failed ownership failure for '%s'\n",
390 * Then that another lookup to the string will return the same
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",
402 * More complex, check the QName lookups
404 for (i
= NB_STRINGS_MAX
- NB_STRINGS_NS
;i
< NB_STRINGS_MAX
;i
++) {
407 while (*cur
!= ':') *pref
++ = *cur
++;
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",
436 printf("dictionary tests succeeded %d strings\n", 2 * NB_STRINGS_MAX
);
438 printf("dictionary tests failed with %d errors\n", nbErrors
);