ph_result_t ph_sockaddr_print(ph_sockaddr_t *sa, ph_string_t *str, bool want_port) { int ret; char buf[128]; char pbuf[32]; switch (sa->family) { case AF_UNIX: return ph_string_append_cstr(str, sa->sa.nix.sun_path); case AF_INET: case AF_INET6: ret = getnameinfo(&sa->sa.sa, ph_sockaddr_socklen(sa), buf, sizeof(buf), pbuf, sizeof(pbuf), NI_NUMERICHOST|NI_NUMERICSERV); if (ret) { return PH_ERR; } if (want_port) { ph_string_printf(str, "[%s]:%s", buf, pbuf); return PH_OK; } return ph_string_append_cstr(str, buf); } return PH_ERR; }
static void stack_tests(void) { PH_STRING_DECLARE_STACK(stack1, 10); PH_STRING_DECLARE_GROW(stack2, 10, mt_misc); // Expect this to succeed; we silently truncate is(ph_string_append_cstr(&stack1, "12345678901"), PH_OK); // Ensure length is good is(10, ph_string_len(&stack1)); is(ph_string_append_cstr(&stack2, "12345678901234567890"), PH_OK); is(20, ph_string_len(&stack2)); ph_string_delref(&stack2); }
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); } }
bool ph_vprintf_register(const char *name, void *formatter_arg, ph_vprintf_named_formatter_func func) { struct formatter *f; bool res; ph_string_t *kptr; pthread_once(&once_init, init_vprintf); f = malloc(sizeof(*f)); if (!f) { return false; } ph_string_init_claim(&f->namestr, PH_STRING_STATIC, f->name, 0, sizeof(f->name)); f->func = func; f->farg = formatter_arg; ph_string_append_cstr(&f->namestr, name); kptr = &f->namestr; pthread_rwlock_wrlock(&formatter_lock); res = (ph_ht_replace(&formatters, &kptr, &f) == PH_OK); pthread_rwlock_unlock(&formatter_lock); if (res) { return true; } free(f); return false; }
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(); }