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 */ }
/* returns pointer to value string if found, NULL otherwise, * key can use printf formatting */ const char* strmap_getf(strmap* map, const char* format, ...) { va_list args; char* str = NULL; /* check that we have a format string */ if (format == NULL) { return strmap_get(map, NULL); } /* compute the size of the string we need to allocate */ va_start(args, format); int size = vsnprintf(NULL, 0, format, args) + 1; va_end(args); /* allocate and print the string */ if (size > 0) { str = (char*) BAYER_MALLOC((size_t)size); va_start(args, format); vsnprintf(str, (size_t)size, format, args); va_end(args); /* if we have a key and value, insert into map */ const char* val; val = strmap_get(map, str); bayer_free(&str); return val; } return strmap_get(map, NULL); }
struct rir_object *rir_map_getobj(struct rir_common *c, const struct RFstring *id) { struct rir_object *ret = strmap_get(rir_common_curr_map(c), id); if (!ret) { ret = strmap_get(&c->rir->map, id); } return ret; }
/** Return the latest downloaded consensus networkstatus in encoded, signed, * optionally compressed format, suitable for sending to clients. */ cached_dir_t * dirserv_get_consensus(const char *flavor_name) { if (!cached_consensuses) return NULL; return strmap_get(cached_consensuses, flavor_name); }
const char *cfgi_get_string(struct cfgi_obj_t *obj, const char *name) { const char *value; struct cfgi_obj_t *use; char **use_ptr; value = strmap_get(obj->args, name); use_ptr = obj->use_list; for (use_ptr = obj->use_list; !value && use_ptr && *use_ptr; use_ptr++) { use = strmap_get(obj->type->templates, *use_ptr); if (use) { value = cfgi_get_string(use, name); } else { /* FIXME: error handling, unknown template */ } } return value; }
static uint32_t get_seq_idx(seqenc_t* E, const str_t* seqname) { uint32_t n = strmap_size(E->seq_index); uint32_t idx = strmap_get(E->seq_index, seqname); if (idx >= n) { E->d_ext_pos = realloc_or_die(E->d_ext_pos, (n + 1) * sizeof(cond_dist256_t)); cond_dist256_init(&E->d_ext_pos[n], 9 * 256); } return idx; }
int main(void) { struct cdump_definitions *defs; const struct cdump_type *t, *t2; char *ctx = tal(NULL, char), *problems; /* This is how many tests you plan to run */ plan_tests(16); defs = cdump_extract(ctx, "struct foo { struct bar *bar; };\n" "struct bar { int x; };", &problems); ok1(defs); ok1(tal_parent(defs) == ctx); ok1(!problems); t = strmap_get(&defs->structs, "foo"); ok1(t); t2 = strmap_get(&defs->structs, "bar"); ok1(t2); ok1(t2->kind == CDUMP_STRUCT); ok1(streq(t2->name, "bar")); ok1(tal_count(t2->u.members) == 1); ok1(t2->u.members[0].type->kind == CDUMP_UNKNOWN); ok1(streq(t2->u.members[0].type->name, "int")); ok1(t->kind == CDUMP_STRUCT); ok1(streq(t->name, "foo")); ok1(tal_count(t->u.members) == 1); ok1(streq(t->u.members[0].name, "bar")); ok1(t->u.members[0].type->kind == CDUMP_POINTER); ok1(t->u.members[0].type->u.ptr == t2); tal_free(ctx); /* This exits depending on whether all tests passed */ return exit_status(); }
/* DOCDOC */ static int prot_strings_helper(strmap_t *locations, char **pr_mem_next_p, size_t *pr_mem_left_p, char **value_p) { char *param_val; size_t param_size; void *location; if (*value_p == 0) return 0; param_val = (char*) *value_p; param_size = strlen(param_val) + 1; location = strmap_get(locations, param_val); if (location) { // We already interned this string. tor_free(param_val); *value_p = location; return 0; } else if (*pr_mem_left_p >= param_size) { // copy to protected location = *pr_mem_next_p; memcpy(location, param_val, param_size); // re-point el parameter to protected tor_free(param_val); *value_p = location; strmap_set(locations, location, location); /* good real estate advice */ // move next available protected memory *pr_mem_next_p += param_size; *pr_mem_left_p -= param_size; return 0; } else { log_err(LD_BUG,"(Sandbox) insufficient protected memory!"); return -1; } }
/** Free storage held by a virtaddress_entry_t* entry in <b>ent</b>. */ static void addressmap_virtaddress_remove(const char *address, addressmap_entry_t *ent) { if (ent && ent->new_address && address_is_in_virtual_range(ent->new_address)) { virtaddress_entry_t *ve = strmap_get(virtaddress_reversemap, ent->new_address); /*log_fn(LOG_NOTICE,"remove reverse mapping for %s",ent->new_address);*/ if (ve) { if (!strcmp(address, ve->ipv4_address)) tor_free(ve->ipv4_address); if (!strcmp(address, ve->hostname_address)) tor_free(ve->hostname_address); if (!ve->ipv4_address && !ve->hostname_address) { tor_free(ve); strmap_remove(virtaddress_reversemap, ent->new_address); } } } }
/* 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; }
/** Run unit tests for string-to-void* map functions */ static void test_container_strmap(void) { strmap_t *map; strmap_iter_t *iter; const char *k; void *v; char *visited = NULL; smartlist_t *found_keys = NULL; map = strmap_new(); test_assert(map); test_eq(strmap_size(map), 0); test_assert(strmap_isempty(map)); v = strmap_set(map, "K1", (void*)99); test_eq_ptr(v, NULL); test_assert(!strmap_isempty(map)); v = strmap_set(map, "K2", (void*)101); test_eq_ptr(v, NULL); v = strmap_set(map, "K1", (void*)100); test_eq_ptr(v, (void*)99); test_eq_ptr(strmap_get(map,"K1"), (void*)100); test_eq_ptr(strmap_get(map,"K2"), (void*)101); test_eq_ptr(strmap_get(map,"K-not-there"), NULL); strmap_assert_ok(map); v = strmap_remove(map,"K2"); strmap_assert_ok(map); test_eq_ptr(v, (void*)101); test_eq_ptr(strmap_get(map,"K2"), NULL); test_eq_ptr(strmap_remove(map,"K2"), NULL); strmap_set(map, "K2", (void*)101); strmap_set(map, "K3", (void*)102); strmap_set(map, "K4", (void*)103); test_eq(strmap_size(map), 4); strmap_assert_ok(map); strmap_set(map, "K5", (void*)104); strmap_set(map, "K6", (void*)105); strmap_assert_ok(map); /* Test iterator. */ iter = strmap_iter_init(map); found_keys = smartlist_new(); while (!strmap_iter_done(iter)) { strmap_iter_get(iter,&k,&v); smartlist_add(found_keys, tor_strdup(k)); test_eq_ptr(v, strmap_get(map, k)); if (!strcmp(k, "K2")) { iter = strmap_iter_next_rmv(map,iter); } else { iter = strmap_iter_next(map,iter); } } /* Make sure we removed K2, but not the others. */ test_eq_ptr(strmap_get(map, "K2"), NULL); test_eq_ptr(strmap_get(map, "K5"), (void*)104); /* Make sure we visited everyone once */ smartlist_sort_strings(found_keys); visited = smartlist_join_strings(found_keys, ":", 0, NULL); test_streq(visited, "K1:K2:K3:K4:K5:K6"); strmap_assert_ok(map); /* Clean up after ourselves. */ strmap_free(map, NULL); map = NULL; /* Now try some lc functions. */ map = strmap_new(); strmap_set_lc(map,"Ab.C", (void*)1); test_eq_ptr(strmap_get(map,"ab.c"), (void*)1); strmap_assert_ok(map); test_eq_ptr(strmap_get_lc(map,"AB.C"), (void*)1); test_eq_ptr(strmap_get(map,"AB.C"), NULL); test_eq_ptr(strmap_remove_lc(map,"aB.C"), (void*)1); strmap_assert_ok(map); test_eq_ptr(strmap_get_lc(map,"AB.C"), NULL); done: if (map) strmap_free(map,NULL); if (found_keys) { SMARTLIST_FOREACH(found_keys, char *, cp, tor_free(cp)); smartlist_free(found_keys); } tor_free(visited); }
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(); }
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; }
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; }
int main(void) { struct cdump_definitions *defs; const struct cdump_type *t, *p; char *ctx = tal(NULL, char), *problems; /* This is how many tests you plan to run */ plan_tests(111); defs = cdump_extract(ctx, "enum foo CDUMP(foo note) { BAR CDUMP(bar note) };", NULL); ok1(defs); ok1(tal_parent(defs) == ctx); ok1(strmap_empty(&defs->structs)); ok1(strmap_empty(&defs->unions)); t = strmap_get(&defs->enums, "foo"); ok1(t); ok1(t->kind == CDUMP_ENUM); ok1(streq(t->note, "foo note")); ok1(streq(t->name, "foo")); ok1(tal_count(t->u.enum_vals) == 1); ok1(streq(t->u.enum_vals[0].name, "BAR")); ok1(!t->u.enum_vals[0].value); ok1(streq(t->u.enum_vals[0].note, "bar note")); defs = cdump_extract(ctx, "enum foo { BAR CDUMP(bar note) = 7 };", &problems); ok1(defs); ok1(tal_parent(defs) == ctx); ok1(!problems); ok1(strmap_empty(&defs->structs)); ok1(strmap_empty(&defs->unions)); t = strmap_get(&defs->enums, "foo"); ok1(t); ok1(t->kind == CDUMP_ENUM); ok1(streq(t->name, "foo")); ok1(tal_count(t->u.enum_vals) == 1); ok1(streq(t->u.enum_vals[0].name, "BAR")); ok1(streq(t->u.enum_vals[0].value, "7")); ok1(streq(t->u.enum_vals[0].note, "bar note")); defs = cdump_extract(ctx, "enum foo {\n" "BAR CDUMP(bar note) = 7,\n" "BAZ CDUMP(baz note),\n" "FUZZ CDUMP(fuzz note) };", &problems); ok1(defs); ok1(tal_parent(defs) == ctx); ok1(!problems); ok1(strmap_empty(&defs->structs)); ok1(strmap_empty(&defs->unions)); t = strmap_get(&defs->enums, "foo"); ok1(t); ok1(t->kind == CDUMP_ENUM); ok1(streq(t->name, "foo")); ok1(t->note == NULL); ok1(tal_count(t->u.enum_vals) == 3); ok1(streq(t->u.enum_vals[0].name, "BAR")); ok1(streq(t->u.enum_vals[0].value, "7")); ok1(streq(t->u.enum_vals[0].note, "bar note")); ok1(streq(t->u.enum_vals[1].name, "BAZ")); ok1(streq(t->u.enum_vals[1].note, "baz note")); ok1(!t->u.enum_vals[1].value); ok1(streq(t->u.enum_vals[2].name, "FUZZ")); ok1(streq(t->u.enum_vals[2].note, "fuzz note")); ok1(!t->u.enum_vals[2].value); defs = cdump_extract(ctx, "struct foo CDUMP(foo note) { int x CDUMP(x note); };", &problems); ok1(defs); ok1(tal_parent(defs) == ctx); ok1(!problems); ok1(strmap_empty(&defs->enums)); ok1(strmap_empty(&defs->unions)); t = strmap_get(&defs->structs, "foo"); ok1(t); ok1(t->kind == CDUMP_STRUCT); ok1(streq(t->name, "foo")); ok1(streq(t->note, "foo note")); ok1(tal_count(t->u.members) == 1); ok1(streq(t->u.members[0].name, "x")); ok1(streq(t->u.members[0].note, "x note")); ok1(t->u.members[0].type->kind == CDUMP_UNKNOWN); ok1(streq(t->u.members[0].type->name, "int")); defs = cdump_extract(ctx, "struct foo { int x[5<< 1] CDUMP(x note); struct foo *next CDUMP(next note); struct unknown **ptrs[10] CDUMP(ptrs note); };", &problems); ok1(defs); ok1(tal_parent(defs) == ctx); ok1(!problems); ok1(strmap_empty(&defs->enums)); ok1(strmap_empty(&defs->unions)); t = strmap_get(&defs->structs, "foo"); ok1(t); ok1(t->kind == CDUMP_STRUCT); ok1(streq(t->name, "foo")); ok1(tal_count(t->u.members) == 3); ok1(streq(t->u.members[0].name, "x")); ok1(streq(t->u.members[0].note, "x note")); ok1(t->u.members[0].type->kind == CDUMP_ARRAY); ok1(streq(t->u.members[0].type->u.arr.size, "5<< 1")); ok1(t->u.members[0].type->u.arr.type->kind == CDUMP_UNKNOWN); ok1(streq(t->u.members[0].type->u.arr.type->name, "int")); ok1(streq(t->u.members[1].name, "next")); ok1(streq(t->u.members[1].note, "next note")); ok1(t->u.members[1].type->kind == CDUMP_POINTER); ok1(t->u.members[1].type->u.ptr == t); ok1(streq(t->u.members[2].name, "ptrs")); ok1(streq(t->u.members[2].note, "ptrs note")); p = t->u.members[2].type; ok1(p->kind == CDUMP_ARRAY); ok1(streq(p->u.arr.size, "10")); p = p->u.arr.type; ok1(p->kind == CDUMP_POINTER); p = p->u.ptr; ok1(p->kind == CDUMP_POINTER); p = p->u.ptr; ok1(p->kind == CDUMP_STRUCT); ok1(streq(p->name, "unknown")); ok1(p->u.members == NULL); /* We don't put undefined structs into definition maps. */ ok1(!strmap_get(&defs->structs, "unknown")); /* unions and comments. */ defs = cdump_extract(ctx, "#if 0\n" "/* Normal comment */\n" "struct foo { int x[5 * 7/* Comment */]CDUMP(x note/*nocomment*/); };\n" "// One-line comment\n" "union bar CDUMP(bar note) { enum sometype x CDUMP(x note// Comment\n" "); union yun// Comment\n" "y;};\n" "#endif", &problems); ok1(defs); ok1(tal_parent(defs) == ctx); ok1(!problems); t = strmap_get(&defs->structs, "foo"); ok1(t); ok1(t->note == NULL); ok1(tal_count(t->u.members) == 1); ok1(streq(t->u.members[0].name, "x")); ok1(streq(t->u.members[0].note, "x note")); ok1(t->u.members[0].type->kind == CDUMP_ARRAY); ok1(streq(t->u.members[0].type->u.arr.size, "5 * 7")); ok1(t->u.members[0].type->u.arr.type->kind == CDUMP_UNKNOWN); ok1(streq(t->u.members[0].type->u.arr.type->name, "int")); t = strmap_get(&defs->unions, "bar"); ok1(t); ok1(streq(t->note, "bar note")); ok1(tal_count(t->u.members) == 2); ok1(streq(t->u.members[0].name, "x")); ok1(streq(t->u.members[0].note, "x note")); ok1(t->u.members[0].type->kind == CDUMP_ENUM); ok1(streq(t->u.members[0].type->name, "sometype")); ok1(!t->u.members[0].type->u.enum_vals); ok1(streq(t->u.members[1].name, "y")); ok1(t->u.members[1].note == NULL); ok1(t->u.members[1].type->kind == CDUMP_UNION); ok1(streq(t->u.members[1].type->name, "yun")); ok1(!t->u.members[1].type->u.members); /* This exits depending on whether all tests passed */ return exit_status(); }
/** Run unit tests for threading logic. */ static void test_threads_basic(void *arg) { char *s1 = NULL, *s2 = NULL; int done = 0, timedout = 0; time_t started; #ifndef _WIN32 struct timeval tv; tv.tv_sec=0; tv.tv_usec=100*1000; #endif (void) arg; set_main_thread(); thread_test_mutex_ = tor_mutex_new(); thread_test_start1_ = tor_mutex_new(); thread_test_start2_ = tor_mutex_new(); thread_test_strmap_ = strmap_new(); s1 = tor_strdup("thread 1"); s2 = tor_strdup("thread 2"); tor_mutex_acquire(thread_test_start1_); tor_mutex_acquire(thread_test_start2_); spawn_func(thread_test_func_, s1); spawn_func(thread_test_func_, s2); tor_mutex_release(thread_test_start2_); tor_mutex_release(thread_test_start1_); started = time(NULL); while (!done) { tor_mutex_acquire(thread_test_mutex_); strmap_assert_ok(thread_test_strmap_); if (strmap_get(thread_test_strmap_, "thread 1") && strmap_get(thread_test_strmap_, "thread 2")) { done = 1; } else if (time(NULL) > started + 150) { timedout = done = 1; } tor_mutex_release(thread_test_mutex_); #ifndef _WIN32 /* Prevent the main thread from starving the worker threads. */ select(0, NULL, NULL, NULL, &tv); #endif } tor_mutex_acquire(thread_test_start1_); tor_mutex_release(thread_test_start1_); tor_mutex_acquire(thread_test_start2_); tor_mutex_release(thread_test_start2_); tor_mutex_free(thread_test_mutex_); if (timedout) { printf("\nTimed out: %d %d", t1_count, t2_count); tt_assert(strmap_get(thread_test_strmap_, "thread 1")); tt_assert(strmap_get(thread_test_strmap_, "thread 2")); tt_assert(!timedout); } /* different thread IDs. */ tt_assert(strcmp(strmap_get(thread_test_strmap_, "thread 1"), strmap_get(thread_test_strmap_, "thread 2"))); tt_assert(!strcmp(strmap_get(thread_test_strmap_, "thread 1"), strmap_get(thread_test_strmap_, "last to run")) || !strcmp(strmap_get(thread_test_strmap_, "thread 2"), strmap_get(thread_test_strmap_, "last to run"))); tt_int_op(thread_fns_failed, ==, 0); tt_int_op(thread_fn_tid1, !=, thread_fn_tid2); done: tor_free(s1); tor_free(s2); tor_free(thread1_name_); tor_free(thread2_name_); if (thread_test_strmap_) strmap_free(thread_test_strmap_, NULL); if (thread_test_start1_) tor_mutex_free(thread_test_start1_); if (thread_test_start2_) tor_mutex_free(thread_test_start2_); }
/** Parse the content of a client_key file in <b>ckstr</b> and add * rend_authorized_client_t's for each parsed client to * <b>parsed_clients</b>. Return the number of parsed clients as result * or -1 for failure. */ int rend_parse_client_keys(strmap_t *parsed_clients, const char *ckstr) { int result = -1; smartlist_t *tokens; directory_token_t *tok; const char *current_entry = NULL; memarea_t *area = NULL; char *err_msg = NULL; if (!ckstr || strlen(ckstr) == 0) return -1; tokens = smartlist_new(); /* Begin parsing with first entry, skipping comments or whitespace at the * beginning. */ area = memarea_new(); current_entry = eat_whitespace(ckstr); while (!strcmpstart(current_entry, "client-name ")) { rend_authorized_client_t *parsed_entry; /* Determine end of string. */ const char *eos = strstr(current_entry, "\nclient-name "); if (!eos) eos = current_entry + strlen(current_entry); else eos = eos + 1; /* Free tokens and clear token list. */ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); smartlist_clear(tokens); memarea_clear(area); /* Tokenize string. */ if (tokenize_string(area, current_entry, eos, tokens, client_keys_token_table, 0)) { log_warn(LD_REND, "Error tokenizing client keys file."); goto err; } /* Advance to next entry, if available. */ current_entry = eos; /* Check minimum allowed length of token list. */ if (smartlist_len(tokens) < 2) { log_warn(LD_REND, "Impossibly short client key entry."); goto err; } /* Parse client name. */ tok = find_by_keyword(tokens, C_CLIENT_NAME); tor_assert(tok == smartlist_get(tokens, 0)); tor_assert(tok->n_args == 1); if (!rend_valid_client_name(tok->args[0])) { log_warn(LD_CONFIG, "Illegal client name: %s. (Length must be " "between 1 and %d, and valid characters are " "[A-Za-z0-9+-_].)", tok->args[0], REND_CLIENTNAME_MAX_LEN); goto err; } /* Check if client name is duplicate. */ if (strmap_get(parsed_clients, tok->args[0])) { log_warn(LD_CONFIG, "HiddenServiceAuthorizeClient contains a " "duplicate client name: '%s'. Ignoring.", tok->args[0]); goto err; } parsed_entry = tor_malloc_zero(sizeof(rend_authorized_client_t)); parsed_entry->client_name = tor_strdup(tok->args[0]); strmap_set(parsed_clients, parsed_entry->client_name, parsed_entry); /* Parse client key. */ tok = find_opt_by_keyword(tokens, C_CLIENT_KEY); if (tok) { parsed_entry->client_key = tok->key; tok->key = NULL; /* Prevent free */ } /* Parse descriptor cookie. */ tok = find_by_keyword(tokens, C_DESCRIPTOR_COOKIE); tor_assert(tok->n_args == 1); if (rend_auth_decode_cookie(tok->args[0], parsed_entry->descriptor_cookie, NULL, &err_msg) < 0) { tor_assert(err_msg); log_warn(LD_REND, "%s", err_msg); tor_free(err_msg); goto err; } } result = strmap_size(parsed_clients); goto done; err: result = -1; done: /* Free tokens and clear token list. */ SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_clear(t)); smartlist_free(tokens); if (area) memarea_drop_all(area); return result; }
struct rir_type *rirtype_strmap_get(struct rirtype_strmap *map, const struct RFstring *id) { return strmap_get(map, id); }
static void cfgi_object_update_use(struct cfgi_obj_t *obj) { char *use; char *tmp; char *last_char; size_t use_len; size_t use_ptr; use = strmap_get(obj->args, "use"); if (!use) { return; } obj->use_store = strdup(use); use_len = 1; for (tmp = obj->use_store; *tmp; tmp++) { if (*tmp == ',') { use_len++; } } obj->use_list = calloc(use_len + 1, sizeof(char **)); use_ptr = use_len - 1; tmp = obj->use_store; obj->use_list[use_ptr--] = tmp; while (*tmp) { if (*tmp == ',') { *tmp = '\0'; obj->use_list[use_ptr--] = tmp + 1; } tmp++; } printf("use_len = %lu\n", use_len); for (use_ptr = 0; obj->use_list[use_ptr]; use_ptr++) { printf("Use string: '%s'\n", obj->use_list[use_ptr]); } for (use_ptr = 0; obj->use_list[use_ptr]; use_ptr++) { /* Trim start */ tmp = obj->use_list[use_ptr]; while (*tmp) { if (*tmp == ' ' || *tmp == '\t') { tmp++; } else { break; } } obj->use_list[use_ptr] = tmp; /* Trim end */ last_char = tmp; while (*tmp) { if (*tmp != ' ' && *tmp != '\t') { last_char = tmp; } tmp++; } if (*last_char) { *(last_char + 1) = '\0'; } } for (use_ptr = 0; obj->use_list[use_ptr]; use_ptr++) { printf("Trimmed: '%s'\n", obj->use_list[use_ptr]); } }