static void string_stream_tests(void) { ph_string_t *str; ph_stream_t *stm; char buf[5]; uint64_t r; str = ph_string_make_empty(mt_misc, 16); stm = ph_stm_string_open(str); ok(stm, "made a stream"); ph_stm_printf(stm, "hello world"); ok(ph_string_equal_cstr(str, "hello world"), "see printf"); ok(ph_stm_seek(stm, 0, SEEK_SET, NULL), "rewound"); ok(ph_stm_read(stm, buf, sizeof(buf), &r), "read data"); is(r, sizeof(buf)); is(memcmp(buf, "hello", 5), 0); ph_stm_printf(stm, " kitty and append!"); ok(ph_string_equal_cstr(str, "hello kitty and append!"), "see printf"); ok(ph_stm_seek(stm, 6, SEEK_SET, NULL), "rewound"); ok(ph_stm_read(stm, buf, sizeof(buf), &r), "read data"); is(r, sizeof(buf)); is(memcmp(buf, "kitty", 5), 0); ok(ph_stm_seek(stm, -5, SEEK_END, NULL), "rewound"); ok(ph_stm_read(stm, buf, sizeof(buf), &r), "read data"); is(r, sizeof(buf)); is(memcmp(buf, "pend!", 5), 0); ph_stm_close(stm); ph_string_delref(str); }
/* { * "base": 0, // base core number; is added to "selector" * "selector": "tid", // use tid * "selector": "wid", // use thr->is_worker id * "selector": [1,2,3], // use 1+base, 2+base, 3+base * "selector": 1, // use 1+base * "selector": "none" // don't specify affinity * } */ bool ph_thread_set_affinity_policy(ph_thread_t *me, ph_variant_t *policy) { ph_cpu_set_t set; uint32_t cores = ph_num_cores(); CPU_ZERO(&set); if (!policy) { ph_cpu_set(me->tid % cores, &set); } else { int base = 0; ph_var_err_t err; ph_variant_t *sel = NULL; ph_var_unpack(policy, &err, 0, "{si, so}", "base", &base, "selector", &sel); if (sel && ph_var_is_array(sel)) { uint32_t i; for (i = 0; i < ph_var_array_size(sel); i++) { int cpu = ph_var_int_val(ph_var_array_get(sel, i)); ph_cpu_set((base + cpu) % cores, &set); } } else if (sel && ph_var_is_string(sel)) { ph_string_t *s = ph_var_string_val(sel); if (ph_string_equal_cstr(s, "tid")) { ph_cpu_set((base + me->tid) % cores, &set); } else if (ph_string_equal_cstr(s, "wid")) { ph_cpu_set((base + me->is_worker - 1) % cores, &set); } else if (ph_string_equal_cstr(s, "none")) { return true; } else { ph_log(PH_LOG_ERR, "Unknown thread affinity selector `Ps%p", (void*)s); } } else if (sel && ph_var_is_int(sel)) { ph_cpu_set((base + ph_var_int_val(sel)) % cores, &set); } else { ph_cpu_set((base + me->tid) % cores, &set); } } return apply_affinity(&set, me); }
static void utf16_tests(void) { uint32_t i, len, n, off; int32_t cp; PH_STRING_DECLARE_STACK(str, 64); for (i = 0; i < sizeof(unicode_strings)/sizeof(unicode_strings[0]); i++) { ph_string_reset(&str); is(ph_string_append_cstr(&str, unicode_strings[i].input), PH_OK); is(ph_string_is_valid_utf8(&str), unicode_strings[i].valid); } for (i = 0; i < sizeof(utf16_strings)/sizeof(utf16_strings[0]); i++) { len = strlen(utf16_strings[i].output); ph_string_reset(&str); is(ph_string_append_utf16_as_utf8(&str, &utf16_strings[i].cp, 1, &n), PH_OK); is(n, len); ok(ph_string_equal_cstr(&str, utf16_strings[i].output), "matches"); // Iterate the codepoints; we should get out what we put in off = 0; is(ph_string_iterate_utf8_as_utf16(&str, &off, &cp), PH_OK); diag("expect %" PRIx32 " got %" PRIx32, utf16_strings[i].cp, cp); is(cp, utf16_strings[i].cp); // Round-trip; put in the output and expect to iterate and get the input cp ph_string_reset(&str); is(ph_string_append_cstr(&str, utf16_strings[i].output), PH_OK); ok(ph_string_is_valid_utf8(&str), "valid utf-8"); off = 0; is(ph_string_iterate_utf8_as_utf16(&str, &off, &cp), PH_OK); diag("round-trip: expect %" PRIx32 " got %" PRIx32, utf16_strings[i].cp, cp); is(cp, utf16_strings[i].cp); } for (i = 0; i < sizeof(surrogates)/sizeof(surrogates[0]); i++) { ph_string_reset(&str); is(ph_string_append_utf16_as_utf8(&str, surrogates[i].points, 2, &n), PH_OK); is(n, strlen(surrogates[i].encoded)); off = 0; // We don't do any magical transformation of surrogates, and we don't // consider them valid utf8 strings is(ph_string_iterate_utf8_as_utf16(&str, &off, &cp), PH_ERR); } }
int main(int argc, char **argv) { ph_string_t *str, *str2; ph_unused_parameter(argc); ph_unused_parameter(argv); ph_library_init(); plan_tests(102); mt_misc = ph_memtype_register(&mt_def); stack_tests(); // Tests reallocation str = ph_string_make_empty(mt_misc, 16); is(ph_string_append_cstr(str, "1234567890"), PH_OK); is(10, ph_string_len(str)); is(ph_string_append_cstr(str, "1234567890"), PH_OK); is(20, ph_string_len(str)); is(memcmp(str->buf, "12345678901234567890", 20), 0); ph_string_delref(str); // Tests reallocation and string formatting str = ph_string_make_empty(mt_misc, 4); is(ph_string_printf(str, "Hello %s", "world"), 11); is(ph_string_len(str), 11); str2 = ph_string_make_empty(mt_misc, 10); is(ph_string_printf(str2, "copy `Ps%p", (void*)str), 16); diag(":%.*s:", str2->len, str2->buf); is(ph_string_len(str2), 16); is(memcmp(str2->buf, "copy Hello world", 16), 0); ph_string_delref(str2); str2 = ph_string_make_empty(mt_misc, 10); is(ph_string_printf(str2, "copy `Ps%d%p", 5, (void*)str), 10); is(memcmp(str2->buf, "copy Hello", 10), 0); ok(!ph_string_equal(str, str2), "not same"); ph_string_delref(str2); str2 = ph_string_make_empty(mt_misc, 10); ph_string_append_buf(str2, str->buf, str->len); ok(ph_string_equal(str, str2), "same"); is(ph_string_compare(str, str2), 0); ph_string_delref(str); ph_string_delref(str2); str = ph_string_make_cstr(mt_misc, "abc"); str2 = ph_string_make_cstr(mt_misc, "bbc"); ok(ph_string_compare(str, str2) < 0, "abc < bbc"); ok(ph_string_compare(str2, str) > 0, "abc < bbc"); ph_string_delref(str2); str2 = ph_string_make_cstr(mt_misc, "abca"); ok(ph_string_compare(str, str2) < 0, "abc < abca"); ok(ph_string_compare(str2, str) > 0, "abc < abca"); ph_string_delref(str2); str2 = ph_string_make_cstr(mt_misc, "ab"); ok(ph_string_compare(str, str2) > 0, "abc > ab"); ok(ph_string_compare(str2, str) < 0, "abc > ab"); ph_string_delref(str2); ph_string_delref(str); str = ph_string_make_printf(mt_misc, 16, "Hello %d", 42); ok(ph_string_equal_cstr(str, "Hello 42"), "same"); ph_string_delref(str); utf16_tests(); string_stream_tests(); return exit_status(); }