struct mobject * marray_append_d(struct mobject *array) { struct mobject *tmp; if ((tmp = mdict_new()) == NULL) return NULL; if (marray_append(array, tmp) == -1) { mobject_free(tmp); return NULL; } return tmp; }
struct mobject * marray_set_d(struct mobject *array, size_t ndx) { struct mobject *tmp; if ((tmp = mdict_new()) == NULL) return NULL; if (marray_set(array, ndx, tmp) == -1) { mobject_free(tmp); return NULL; } return tmp; }
struct mobject * mdict_replace_sd(struct mobject *dict, const char *key) { struct mobject *tmp; if ((tmp = mdict_new()) == NULL) return NULL; if (mdict_replace_s(dict, key, tmp) == NULL) { mobject_free(tmp); return NULL; } return tmp; }
static void test_mdict(void *p) { struct MDict *d; struct MBuf buf; const char *s; d = mdict_new(NULL); str_check(xget(d, "key"), "NULL"); int_check(mdict_put(d, "key", "val"), 1); int_check(mdict_put(d, "key2", "foo"), 1); int_check(mdict_put(d, "key2", ""), 1); int_check(mdict_put(d, "key3", NULL), 1); int_check(mdict_put(d, "key4", "v1"), 1); int_check(mdict_del(d, "key4"), 1); str_check(xget(d, "key"), "val"); str_check(xget(d, "key2"), ""); str_check(xget(d, "key3"), "NULL"); str_check(xget(d, "key4"), "NULL"); str_check(xget(d, "key5"), "NULL"); int_check(mdict_del(d, "key5"), 0); mbuf_init_dynamic(&buf); int_check(mdict_urlencode(d, &buf), 1); int_check(mbuf_write_byte(&buf, 0), 1); str_check(mbuf_data(&buf), "key=val&key2=&key3"); mbuf_free(&buf); mdict_free(d); d = mdict_new(NULL); s = "key=val&key2=&key3"; int_check(mdict_urldecode(d, s, strlen(s)), 1); str_check(xget(d, "key"), "val"); str_check(xget(d, "key2"), ""); str_check(xget(d, "key3"), "NULL"); mdict_free(d); end:; }
int main(int argc, char **argv) { struct mobject *ns, *xd, *xd2; struct mobject *xa, *xa2; struct mobject *xi; u_int i; char ebuf[8192], nbuf[8192]; struct mobject *xo; struct mobject *hello, *there, *there42, *z24, *z10_1, *z10_2_wow; /* Turn on all malloc debugging on OpenBSD */ setenv("MALLOC_OPTIONS", "AFGJPRX", 1); setvbuf(stdout, NULL, _IONBF, 0); printf("mobject_t1:"); /* Prepare an namespace */ assert((ns = xd = mdict_new()) != NULL); assert((xd2 = mdict_new()) != NULL); hello = xd2; assert(mdict_insert_s(xd, "hello", xd2) != NULL); assert((xa = marray_new()) != NULL); there = xa; assert(mdict_insert_s(xd2, "there", xa) != NULL); for (i = 0; i < 43; i++) { assert((xd2 = mdict_new()) != NULL); assert(marray_append(xa, xd2) == 0); } there42 = xd2; assert((xd = mdict_new()) != NULL); assert(mdict_insert_s(xd2, "x", xd) != NULL); assert((xd2 = mdict_new()) != NULL); assert(mdict_insert_s(xd, "y", xd2) != NULL); assert((xa = marray_new()) != NULL); assert(mdict_insert_s(xd2, "z", xa) != NULL); for (i = 0; i < 30; i++) { if (i == 10) { assert((xa2 = marray_new()) != NULL); assert(marray_append(xa, xa2) == 0); assert((xi = mint_new(1234)) != NULL); assert(marray_append(xa2, xi) == 0); assert((xi = mint_new(5678)) != NULL); assert(marray_append(xa2, xi) == 0); z10_1 = xi; assert((xd = mdict_new()) != NULL); assert(marray_append(xa2, xd) == 0); assert(mdict_insert_ss(xd, "wow", "indeed") != NULL); assert((z10_2_wow = mdict_item_s(xd, "wow")) != NULL); continue; } assert((xi = mint_new(i)) != NULL); assert(marray_append(xa, xi) == 0); if (i == 24) z24 = xi; } /* Case 1: Lookup null at root*/ assert(mnamespace_lookup(ns, "", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Empty location specified") == 0); printf("."); /* Case 2: Lookup one level down */ assert(mnamespace_lookup(ns, "hello", &xo, ebuf, sizeof(ebuf)) == 0); assert(xo == hello); printf("."); /* Case 3: Lookup empty one level down */ assert(mnamespace_lookup(ns, "hello.", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Empty name at \"hello.\"") == 0); printf("."); /* Case 4: lookup under second-level dict */ assert(mnamespace_lookup(ns, "hello.there", &xo, ebuf, sizeof(ebuf)) == 0); assert(xo == there); printf("."); /* Case 5: lookup array entry */ assert(mnamespace_lookup(ns, "hello.there[42]", &xo, ebuf, sizeof(ebuf)) == 0); assert(xo == there42); printf("."); /* Case 6: Deep lookups */ assert(mnamespace_lookup(ns, "hello.there[42].x", &xo, ebuf, sizeof(ebuf)) == 0); assert(mnamespace_lookup(ns, "hello.there[42].x.y", &xo, ebuf, sizeof(ebuf)) == 0); assert(mnamespace_lookup(ns, "hello.there[42].x.y.z", &xo, ebuf, sizeof(ebuf)) == 0); assert(mnamespace_lookup(ns, "hello.there[42].x.y.z[24]", &xo, ebuf, sizeof(ebuf)) == 0); assert(xo == z24); printf("."); /* Case 7: Bad name at root */ assert(mnamespace_lookup(ns, "xhello", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Name \"xhello\" not found") == 0); assert(mnamespace_lookup(ns, "xhello.there[42].x.y.z[24]", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Name \"xhello\" not found") == 0); printf("."); /* Case 8: Bad name one down */ assert(mnamespace_lookup(ns, "hello.therex", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Name \"therex\" not found at \"hello.\"") == 0); assert(mnamespace_lookup(ns, "hello.therex[42].x.y.z[24]", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Name \"therex\" not found at \"hello.\"") == 0); printf("."); /* Case 9: Array index out of bounds */ assert(mnamespace_lookup(ns, "hello.there[43].x.y.z[24]", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Array index is out of bounds at \"hello.there[43]\"") == 0); printf("."); /* Case 10: Negative array index */ assert(mnamespace_lookup(ns, "hello.there[-1].x.y.z[24]", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Array index is out of bounds at \"hello.there[-1]\"") == 0); printf("."); /* Case 11: Non numeric array index */ assert(mnamespace_lookup(ns, "hello.there[blah].x.y.z[24]", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Array index is not a number at \"hello.there[blah]\"") == 0); printf("."); /* Case 12: Unterminated array index */ assert(mnamespace_lookup(ns, "hello.there[123", &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Array index is not terminated at \"hello.there[123\"") == 0); printf("."); /* Case 13: Identifier too long */ snprintf(nbuf, sizeof(nbuf), "hello."); strlcat(nbuf, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", sizeof(nbuf)); /* 32*/ strlcat(nbuf, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", sizeof(nbuf)); /* 64*/ strlcat(nbuf, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", sizeof(nbuf)); /* 96*/ strlcat(nbuf, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", sizeof(nbuf)); /*128*/ strlcat(nbuf, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", sizeof(nbuf)); /*160*/ strlcat(nbuf, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", sizeof(nbuf)); /*192*/ strlcat(nbuf, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", sizeof(nbuf)); /*256*/ strlcat(nbuf, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX", sizeof(nbuf)); /*288*/ assert(mnamespace_lookup(ns, nbuf, &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Name \"XXXXXXXX...\" too long at \"hello.\"") == 0); printf("."); /* Case 13: Array index too long */ snprintf(nbuf, sizeof(nbuf), "hello.there["); strlcat(nbuf, "99999999999999999999999999999999", sizeof(nbuf)); /* 32*/ strlcat(nbuf, "99999999999999999999999999999999", sizeof(nbuf)); /* 64*/ strlcat(nbuf, "99999999999999999999999999999999", sizeof(nbuf)); /* 96*/ strlcat(nbuf, "99999999999999999999999999999999", sizeof(nbuf)); /*128*/ strlcat(nbuf, "99999999999999999999999999999999", sizeof(nbuf)); /*160*/ strlcat(nbuf, "99999999999999999999999999999999", sizeof(nbuf)); /*192*/ strlcat(nbuf, "99999999999999999999999999999999", sizeof(nbuf)); /*256*/ strlcat(nbuf, "99999999999999999999999999999999", sizeof(nbuf)); /*288*/ strlcat(nbuf, "]", sizeof(nbuf)); /*280*/ assert(mnamespace_lookup(ns, nbuf, &xo, ebuf, sizeof(ebuf)) == -1); assert(strcmp(ebuf, "Array index is too long at \"hello.there[\"") == 0); printf("."); /* Case 14: Array then array */ assert(mnamespace_lookup(ns, "hello.there[42].x.y.z[10][1]", &xo, ebuf, sizeof(ebuf)) == 0); assert(xo == z10_1); printf("."); /* Case 14: Array then array then dict! */ assert(mnamespace_lookup(ns, "hello.there[42].x.y.z[10][2].wow", &xo, ebuf, sizeof(ebuf)) == 0); assert(xo == z10_2_wow); printf("."); mobject_free(ns); printf("\n"); return 0; }