static tb_char_t* tb_printf_string(tb_char_t* pb, tb_char_t* pe, tb_printf_entry_t e, tb_char_t const* s) { if (s) { tb_int_t n = tb_strnlen(s, e.precision); // fill space at left side, e.g. " abcd" if (!(e.flags & TB_PRINTF_FLAG_LEFT)) { while (n < e.width--) if (pb < pe) *pb++ = ' '; } // copy string tb_int_t i = 0; for (i = 0; i < n; ++i) if (pb < pe) *pb++ = *s++; // fill space at right side, e.g. "abcd " while (n < e.width--) if (pb < pe) *pb++ = ' '; } else { // null if (pb < pe) *pb++ = 'n'; if (pb < pe) *pb++ = 'u'; if (pb < pe) *pb++ = 'l'; if (pb < pe) *pb++ = 'l'; } return pb; }
/* ////////////////////////////////////////////////////////////////////////////////////// * interfaces */ tb_size_t tb_strlen(tb_char_t const* s) { // check #ifdef __tb_debug__ { // overflow? tb_size_t size = tb_pool_data_size(s); if (size) { // no '\0'? tb_size_t real = tb_strnlen(s, size); if (s[real]) { tb_trace_i("[strlen]: [overflow]: [%p, %lu]", s, size); tb_backtrace_dump("[strlen]: [overflow]: ", tb_null, 10); tb_pool_data_dump(s, tb_true, "\t[malloc]: [from]: "); tb_abort(); } } } #endif // done return tb_strlen_impl(s); }
static tb_void_t tb_test_strnlen(tb_char_t const* s, tb_size_t size) { __tb_volatile__ tb_long_t n = 1000000; __tb_volatile__ tb_long_t r = 0; tb_hong_t t = tb_mclock(); while (n--) { r = tb_strnlen(s, size); } t = tb_mclock() - t; tb_printf("%lld ms, tb_test_strnlen(%s, %u) = %ld\n", t, s, size, r); }
tb_char_t* tb_strndup(tb_char_t const* s, tb_size_t n) { // check tb_assert_and_check_return_val(s, tb_null); // done n = tb_strnlen(s, n); __tb_register__ tb_char_t* p = tb_malloc_cstr(n + 1); if (p) { tb_memcpy(p, s, n); p[n] = '\0'; } return p; }