/* Simple LL(1) parser, inspired by Tridge's genstruct.pl. */ struct cdump_definitions *cdump_extract(const tal_t *ctx, const char *code, char **complaints) { struct parse_state ps; const struct token *toks; ps.defs = tal(ctx, struct cdump_definitions); ps.complaints = tal_strdup(ctx, ""); ps.code = code; strmap_init(&ps.defs->enums); strmap_init(&ps.defs->structs); strmap_init(&ps.defs->unions); tal_add_destructor(ps.defs, destroy_definitions); toks = ps.toks = tokenize(ps.defs, code); while (tok_peek(&ps.toks)) { if (tok_take_if(&ps.toks, "struct")) { if (!tok_take_conglom(&ps, CDUMP_STRUCT)) goto fail; } else if (tok_take_if(&ps.toks, "union")) { if (!tok_take_conglom(&ps, CDUMP_UNION)) goto fail; } else if (tok_take_if(&ps.toks, "enum")) { if (!tok_take_enum(&ps)) goto fail; } else tok_take_unknown_statement(&ps); } /* Now, remove any undefined types! */ remove_undefined(&ps.defs->enums); remove_undefined(&ps.defs->structs); remove_undefined(&ps.defs->unions); tal_free(toks); out: if (streq(ps.complaints, "")) ps.complaints = tal_free(ps.complaints); if (complaints) *complaints = ps.complaints; else tal_free(ps.complaints); return ps.defs; fail: ps.defs = tal_free(ps.defs); goto out; }
int main(void) { STRMAP(char *) map; unsigned int i; char *str[NUM]; bool dump_ok; plan_tests(1 + NUM * 4 + 3 * NUM); strmap_init(&map); for (i = 0; i < NUM; i++) { char template[10];
static void remove_undefined(struct cdump_map *map) { struct cdump_map undefs; /* We can't delete inside iterator, so gather all the undefs * then remove them. */ strmap_init(&undefs); strmap_iterate(map, gather_undefines, &undefs); strmap_iterate(&undefs, remove_from_map, map); strmap_clear(&undefs); }
void init_factoids() { char line[512]; strmap_init(&factoids); factoid_file = fopen("factoids", "r"); if (factoid_file == NULL) return; while (fgets(line, 512, factoid_file)) { strmap_insert(&factoids, line, line + strlen(line) + 1); } fclose(factoid_file); }
int main(void) { STRMAP(char *) map; plan_tests(3); strmap_init(&map); ok1(strmap_add(&map, "hello", "hello")); ok1(strmap_add(&map, "world", "world")); strmap_iterate(&map, find_string, (const char *)"hello"); ok1(found); strmap_clear(&map); /* This exits depending on whether all tests passed */ return exit_status(); }
const struct packed_format *packed_format_of(IDL_tree stype) { static bool first = true; if(first) { first = false; strmap_init(&packed_cache); } const char *s_id = sdecl_name(stype); struct packed_format *ret = strmap_get(&packed_cache, s_id); if(ret != NULL) return ret; struct member_item *items = expand_member_list( IDL_TYPE_STRUCT(stype).member_list); int num_items = 0; while(items[num_items].type != NULL) num_items++; qsort(items, num_items, sizeof(struct member_item), &item_by_bitsize_cmp); /* packing of small (sub-word) items */ GList *items_by_size[BITS_PER_WORD - 1]; for(int i=0; i < (BITS_PER_WORD - 1); i++) { items_by_size[i] = NULL; } int num_small = 0; for(int i=0; i<num_items; i++) { struct member_item *item = &items[i]; /* TODO: produce N items for arrays where bits_each < BITS_PER_WORD, so * that smaller items can be packed after e.g. an array member that * leaves 11 bits unused in each word. */ int bits = MEMBER_BITS(item); if(bits >= BITS_PER_WORD) break; items_by_size[bits] = g_list_prepend(items_by_size[bits], item); num_small++; } for(int i=0; i < (BITS_PER_WORD - 1); i++) { items_by_size[i] = g_list_reverse(items_by_size[i]); } GPtrArray *packed = g_ptr_array_new(); int num_words = pack_items(packed, items_by_size, num_small, NULL, 0, 64); if(num_words > 63) { warn_once("structure `%s' can't be bit-packed\n", s_id); return NULL; } assert(num_words < 64); for(int i=0; i < (BITS_PER_WORD - 1); i++) { g_list_free(items_by_size[i]); } #if 0 printf("%s: packed %d/%d small items into %d words from `%s'\n", __func__, (int)packed->len, num_small, num_words, s_id); #endif /* packing of word-length, and longer, items */ for(int i=0; i<num_items; i++) { struct member_item *item = &items[i]; int nbits = MEMBER_BITS(item); if(nbits < BITS_PER_WORD) continue; g_ptr_array_add(packed, new_packed_item(num_words, 0, nbits, item)); int words = (nbits + BITS_PER_WORD - 1) / BITS_PER_WORD; #if 0 printf("%s: packing item `%s' of %d words (%d bits) as-is\n", __func__, item->name, words, nbits); #endif num_words += words; } #if 0 printf("%s: packed %d items into %d words from `%s'\n", __func__, items->len, num_words, s_id); for(int i=0; i<packed->len; i++) { const struct packed_item *pi = packed->pdata[i]; printf("... `%s' -> word %d, bit %d\n", pi->name, pi->word, pi->bit); } #endif assert(packed->len == num_items); g_free(items); items = NULL; ret = g_malloc(sizeof(struct packed_format) + sizeof(struct packed_item *) * packed->len); ret->num_words = num_words; ret->num_items = packed->len; memcpy(ret->items, &g_ptr_array_index(packed, 0), packed->len * sizeof(void *)); g_ptr_array_free(packed, TRUE); ret->num_bits = 0; for(int i=0; i<ret->num_items; i++) { ret->num_bits += ret->items[i]->len; } bool ok = strmap_add(&packed_cache, s_id, ret); assert(ok || errno != EEXIST); return ret; }
int main(void) { STRMAP(char *) map; const char str[] = "hello"; const char val[] = "there"; const char none[] = ""; char *dup = strdup(str); char *v; /* This is how many tests you plan to run */ plan_tests(42); strmap_init(&map); ok1(!strmap_get(&map, str)); ok1(errno == ENOENT); ok1(!strmap_get(&map, none)); ok1(errno == ENOENT); ok1(!strmap_del(&map, str, NULL)); ok1(errno == ENOENT); ok1(!strmap_del(&map, none, NULL)); ok1(errno == ENOENT); ok1(strmap_add(&map, str, val)); ok1(strmap_get(&map, str) == val); /* We compare the string, not the pointer. */ ok1(strmap_get(&map, dup) == val); ok1(!strmap_get(&map, none)); ok1(errno == ENOENT); /* Add a duplicate should fail. */ ok1(!strmap_add(&map, dup, val)); ok1(errno == EEXIST); ok1(strmap_get(&map, dup) == val); /* Delete should return original string. */ ok1(strmap_del(&map, dup, &v) == str); ok1(v == val); ok1(!strmap_get(&map, str)); ok1(errno == ENOENT); ok1(!strmap_get(&map, none)); ok1(errno == ENOENT); /* Try insert and delete of empty string. */ ok1(strmap_add(&map, none, none)); ok1(strmap_get(&map, none) == none); ok1(!strmap_get(&map, str)); ok1(errno == ENOENT); /* Delete should return original string. */ ok1(strmap_del(&map, "", &v) == none); ok1(v == none); ok1(!strmap_get(&map, str)); ok1(errno == ENOENT); ok1(!strmap_get(&map, none)); ok1(errno == ENOENT); /* Both at once... */ ok1(strmap_add(&map, none, none)); ok1(strmap_add(&map, str, val)); ok1(strmap_get(&map, str) == val); ok1(strmap_get(&map, none) == none); ok1(strmap_del(&map, "does not exist", NULL) == NULL); ok1(strmap_del(&map, "", NULL) == none); ok1(strmap_get(&map, str) == val); ok1(strmap_del(&map, dup, &v) == str); ok1(v == val); ok1(strmap_empty(&map)); free(dup); /* This exits depending on whether all tests passed */ return exit_status(); }