Annotation of embedaddon/libxml2/testdict.c, revision 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>