예제 #1
0
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();
}
예제 #2
0
파일: cfgi.c 프로젝트: jbop/configread
static int cfgi_create_object(const char *objtype, struct strmap_t *args,
		void *ctx) {
	struct cfgi_t *cih = (struct cfgi_t *) ctx;
	struct cfgi_type_t *cit = strmap_get(cih->types, objtype);
	struct cfgi_obj_t *obj = (struct cfgi_obj_t *) calloc(1,
			sizeof(struct cfgi_obj_t));

	const char *register_string = strmap_get(args, "register");
	const char *name = strmap_get(args, "name");

	obj->args = args;
	obj->type = cit;

	cfgi_object_update_use(obj);

	if (register_string == NULL) {
		obj->register_object = 1;
	} else {
		obj->register_object = (0 != atoi(register_string));
	}

	obj->next = cit->objlist;
	cit->objlist = obj;

	if (name != NULL) {
		strmap_add(&cit->templates, name, obj);
	}

	return 1; /* 1 means stealing the args resource */
}
예제 #3
0
static bool gather_undefines(const char *name,
			     struct cdump_type *t,
			     struct cdump_map *undefs)
{
	if (!type_defined(t))
		strmap_add(undefs, name, t);
	return true;
}
예제 #4
0
파일: cfgi.c 프로젝트: jbop/configread
int cfgi_register_handler(struct cfgi_t *cih, char *objtype,
		cfgi_callback_t callback) {
	struct cfgi_type_t *cit;

	cfg_parser_register_handler(cih->parser, objtype, cfgi_create_object);

	cit = cfgi_type_create(cih);
	cit->callback = callback;
	strmap_add(&cih->types, objtype, cit);
	/* FIXME: error handling */
	return 0;
}
예제 #5
0
파일: rir_strmap.c 프로젝트: refu-lang/refu
bool rirobj_strmap_add(
    struct rirobj_strmap *map,
    const struct RFstring *id,
    struct rir_object *obj
)
{
    bool ret = strmap_add(map, (struct RFstring*)id, obj);
    RF_ASSERT(
        ret || errno != EEXIST,
        "Tried to add an already existing RIR object to the map"
    );
    return ret;
}
예제 #6
0
파일: rir_strmap.c 프로젝트: refu-lang/refu
bool rirtype_strmap_add(
    struct rirtype_strmap *map,
    const struct RFstring *id,
    struct rir_type *t)
{
    struct RFstring *id_copy = rf_string_copy_out(id);
    if (!id_copy) {
        return false;
    }
    bool ret = strmap_add(map, id_copy, t);
    RF_ASSERT(
        ret || errno != EEXIST,
        "Tried to add an already existing RIR object to the map"
    );
    if (!ret) {
        rf_string_destroy(id_copy);
    }
    return ret;
}
예제 #7
0
/* May allocate a new type if not already found (steals @name) */
static struct cdump_type *get_type(struct cdump_definitions *defs,
				   enum cdump_type_kind kind,
				   const char *name)
{
	struct cdump_map *m;
	struct cdump_type *t;

	switch (kind) {
	case CDUMP_STRUCT:
		m = &defs->structs;
		break;
	case CDUMP_UNION:
		m = &defs->unions;
		break;
	case CDUMP_ENUM:
		m = &defs->enums;
		break;
	case CDUMP_UNKNOWN:
	case CDUMP_ARRAY:
	case CDUMP_POINTER:
		m = NULL;
	}

	/* Do we already have it? */
	if (m) {
		t = strmap_get(m, name);
		if (t)
			return t;
	}

	t = tal(defs, struct cdump_type);
	t->kind = kind;
	t->name = name ? tal_steal(t, name) : NULL;
	/* These are actually the same, but be thorough */
	t->u.members = NULL;
	t->u.enum_vals = NULL;
	if (m)
		strmap_add(m, t->name, t);

	return t;
}
예제 #8
0
파일: struct.c 프로젝트: ksandstr/muidl
LLVMValueRef get_struct_fn(
	struct llvm_ctx *ctx,
	IDL_tree ctyp,
	bool for_encode)
{
	const char *s_id = IDL_IDENT(IDL_TYPE_STRUCT(ctyp).ident).repo_id;
	char *lookup_name = talloc_asprintf(ctx, "%c%s",
		for_encode ? 'e' : 'd', s_id);
	LLVMValueRef fn = strmap_get(&ctx->struct_decoder_fns, lookup_name);
	if(fn != NULL) {
		talloc_free(lookup_name);
		return fn;
	}

	const struct packed_format *fmt = packed_format_of(ctyp);
	assert(fmt != NULL);	/* only sane for packable structs */
	int namelen = strlen(s_id);
	char flatname[namelen + 1];
	/* FIXME: make this proper, i.e. use a name mangler that works */
	for(int i=0; i < namelen; i++) {
		flatname[i] = isalnum(s_id[i]) ? s_id[i] : '_';
	}
	flatname[namelen] = '\0';
	T types[3], rettyp = LLVMVoidTypeInContext(ctx->ctx);
	types[0] = LLVMPointerType(llvm_rigid_type(ctx, ctyp), 0);
	int nparms;
	if(!for_encode) {
		/* decoder */
		types[1] = ctx->i32t;
		types[2] = ctx->i32t;
		nparms = fmt->num_bits < BITS_PER_WORD ? 3 : 2;
	} else if(fmt->num_bits < BITS_PER_WORD) {
		/* subword encoder */
		rettyp = ctx->wordt;
		types[1] = ctx->wordt;
		types[2] = ctx->i32t;
		nparms = 3;
	} else {
		/* non-subword encoder */
		types[1] = ctx->i32t;
		nparms = 2;
	}
	T fntype = LLVMFunctionType(rettyp, types, nparms, 0);
	char *fnname = g_strdup_printf("__muidl_idl_%scode__%s",
		for_encode ? "en" : "de", flatname);
	fn = LLVMAddFunction(ctx->module, fnname, fntype);
	LLVMSetLinkage(fn, LLVMExternalLinkage);
	V params[nparms];
	assert(LLVMCountParams(fn) == nparms);
	LLVMGetParams(fn, params);
	LLVMAddAttribute(params[0], LLVMNoAliasAttribute);
	LLVMAddAttribute(params[0], LLVMNoCaptureAttribute);
	for(int i=0; i<nparms; i++) {
		LLVMAddAttribute(params[i], LLVMInRegAttribute);
	}
	g_free(fnname);
	bool ok = strmap_add(&ctx->struct_decoder_fns, lookup_name, fn);
	assert(ok || errno != EEXIST);

	return fn;
}
예제 #9
0
파일: struct.c 프로젝트: ksandstr/muidl
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;
}
예제 #10
0
파일: run.c 프로젝트: amboar/ccan
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();
}