void type_write(type_t t, type_wr_ctx_t ctx) { fbuf_t *f = tree_write_file(ctx->tree_ctx); if (t == NULL) { write_u16(UINT16_C(0xffff), f); // Null marker return; } if (t->generation == ctx->generation) { // Already visited this type write_u16(UINT16_C(0xfffe), f); // Back reference marker write_u32(t->index, f); return; } t->generation = ctx->generation; t->index = (ctx->n_types)++; write_u16(t->kind, f); // Call type_ident here to generate an arbitrary name if needed ident_write(type_ident(t), ctx->ident_ctx); const uint32_t has = has_map[t->kind]; const int nitems = __builtin_popcount(has); uint32_t mask = 1; for (int n = 0; n < nitems; mask <<= 1) { if (has & mask) { if (ITEM_TYPE_ARRAY & mask) { type_array_t *a = &(t->items[n].type_array); write_u16(a->count, f); for (unsigned i = 0; i < a->count; i++) type_write(a->items[i], ctx); } else if (ITEM_TYPE & mask) type_write(t->items[n].type, ctx); else if (ITEM_TREE & mask) tree_write(t->items[n].tree, ctx->tree_ctx); else if (ITEM_TREE_ARRAY & mask) { tree_array_t *a = &(t->items[n].tree_array); write_u16(a->count, f); for (unsigned i = 0; i < a->count; i++) tree_write(a->items[i], ctx->tree_ctx); } else if (ITEM_RANGE_ARRAY & mask) { range_array_t *a = &(t->items[n].range_array); write_u16(a->count, f); for (unsigned i = 0; i < a->count; i++) { write_u8(a->items[i].kind, f); tree_write(a->items[i].left, ctx->tree_ctx); tree_write(a->items[i].right, ctx->tree_ctx); } } else item_without_type(mask); n++; } } }
END_TEST START_TEST(test_read_write) { ident_t i1, i2, i3; i1 = ident_new("goobar"); i2 = ident_new("foo"); i3 = ident_new("foo"); fbuf_t *f = fbuf_open("test.ident", FBUF_OUT); fail_if(f == NULL); ident_wr_ctx_t wctx = ident_write_begin(f); ident_write(i1, wctx); ident_write(i2, wctx); ident_write(i3, wctx); ident_write_end(wctx); fbuf_close(f); f = fbuf_open("test.ident", FBUF_IN); fail_if(f == NULL); ident_rd_ctx_t rctx = ident_read_begin(f); ident_t j1, j2, j3; j1 = ident_read(rctx); j2 = ident_read(rctx); j3 = ident_read(rctx); ident_read_end(rctx); fail_unless(i1 == j1); fail_unless(i2 == j2); fail_unless(i3 == j3); fail_unless(j2 == j3); fbuf_close(f); remove("test.ident"); }