Example #1
0
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");
}
Example #2
0
type_t type_read(type_rd_ctx_t ctx)
{
   fbuf_t *f = tree_read_file(ctx->tree_ctx);

   uint16_t marker = read_u16(f);
   if (marker == UINT16_C(0xffff))
      return NULL;   // Null marker
   else if (marker == UINT16_C(0xfffe)) {
      // Back reference marker
      unsigned index = read_u32(f);
      assert(index < ctx->n_types);
      return ctx->store[index];
   }

   assert(marker < T_LAST_TYPE_KIND);

   type_t t = type_new((type_kind_t)marker);
   t->ident = ident_read(ctx->ident_ctx);

   // Stash pointer for later back references
   // This must be done early as a child node of this type may
   // reference upwards
   if (ctx->n_types == ctx->store_sz) {
      ctx->store_sz *= 2;
      ctx->store = xrealloc(ctx->store, ctx->store_sz * sizeof(type_t));
   }
   ctx->store[ctx->n_types++] = t;

   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);
            type_array_resize(a, read_u16(f), NULL);

            for (unsigned i = 0; i < a->count; i++)
               a->items[i] = type_read(ctx);
         }
         else if (ITEM_TYPE & mask)
            t->items[n].type = type_read(ctx);
         else if (ITEM_TREE & mask)
            t->items[n].tree = tree_read(ctx->tree_ctx);
         else if (ITEM_TREE_ARRAY & mask) {
            tree_array_t *a = &(t->items[n].tree_array);
            tree_array_resize(a, read_u16(f), NULL);

            for (unsigned i = 0; i < a->count; i++)
               a->items[i] = tree_read(ctx->tree_ctx);
         }
         else if (ITEM_RANGE_ARRAY & mask) {
            range_array_t *a = &(t->items[n].range_array);
            range_t dummy = { NULL, NULL, 0 };
            range_array_resize(a, read_u16(f), dummy);

            for (unsigned i = 0; i < a->count; i++) {
               a->items[i].kind  = read_u8(f);
               a->items[i].left  = tree_read(ctx->tree_ctx);
               a->items[i].right = tree_read(ctx->tree_ctx);
            }
         }
         else
            item_without_type(mask);
         n++;
      }
   }

   return t;
}