--- nono/lib/mystring.cpp 2026/04/29 17:05:15 1.1.1.7 +++ nono/lib/mystring.cpp 2026/04/29 17:05:56 1.1.1.10 @@ -9,6 +9,7 @@ // #include "mystring.h" +#include "ascii_ctype.h" #include std::string @@ -32,7 +33,7 @@ string_ltrim(const std::string& str) { auto it = str.begin(); for (; it != str.end(); it++) { - if (!isspace(*it)) + if (!is_ascii_space(*it)) break; } return std::string(it, str.end()); @@ -42,7 +43,7 @@ string_ltrim(const std::string& str) void string_rtrim(std::string& str) { - while (isspace(*str.rbegin())) { + while (is_ascii_space(*str.rbegin())) { str.pop_back(); } } @@ -52,7 +53,7 @@ void rtrim(char *str) { char *p = strchr(str, '\0'); - while (--p >= str && isspace((int)*p)) { + while (--p >= str && is_ascii_space(*p)) { *p = '\0'; } } @@ -65,11 +66,11 @@ string_trim(const std::string& str) int e = str.size(); for (; s < e; s++) { - if (!isspace(str[s])) + if (!is_ascii_space(str[s])) break; } for (e--; e >= s; e--) { - if (!isspace(str[e])) + if (!is_ascii_space(str[e])) break; } @@ -211,6 +212,101 @@ strhex(uint32 value, int width) return s; } +static constexpr bool FORMAT_TSEC = false; +static constexpr bool FORMAT_FULL = true; + +// TimeToStr() と SecToStr() の共通部分。 +template +static const std::string +TimeToStrF(uint64 t) +{ + char buf[32]; + char *p; + size_t len; + int n; + + uint ns = t % 1000; + t /= 1000; + uint us = t % 1000; + t /= 1000; + uint ms = t % 1000; + t /= 1000; + + uint s, m, h, d; + if (full_format) { + s = t % 60; + t /= 60; + m = t % 60; + t /= 60; + h = t % 24; + t /= 24; + d = t; + } else { + s = t; + m = 0; + h = 0; + d = 0; + } + + p = buf; + len = sizeof(buf); + if (d) { + n = snprintf(p, len, "%3ud %02u:%02u:%02u", d, h, m, s); + p += n; + len -= n; + } else if (h) { + n = snprintf(p, len, "%2u:%02u:%02u", h, m, s); + p += n; + len -= n; + } else if (m) { + n = snprintf(p, len, "%2u:%02u", m, s); + p += n; + len -= n; + } else { + n = snprintf(p, len, "%u", s); + p += n; + len -= n; + } + n = snprintf(p, len, ".%03u'%03u'%03u", ms, us, ns); + p += n; + len -= n; + + return std::string(buf, p - buf); +} + +// t [nsec] を文字列に整形して返す。 +// ex) 1 2 +// 01234567890123456789012345 +// "1.mmm'uuu'nnn" 10秒未満なら13桁 +// "59.mmm'uuu'nnn" 1分未満なら14桁 +// " 9:59.mmm'uuu'nnn" 1時間未満なら17桁 +// " 9:59:59.mmm'uuu'nnn" 24時間未満なら20桁 +// "999d 23:59:59.mmm'uuu'nnn" 1000日未満なら25桁 +// +// 1000日以上になると桁がずれるけど、それはもういいだろう。 +// 10秒未満の場合だけ %2u ではなく %u で1桁切り詰めているが、これは +// FORMAT_TSEC との互換性のため。その必要のない10分未満と10時間未満は +// どちらも %2u で表記し桁数を維持することに努める。 +const std::string +TimeToStr(uint64 t) +{ + return TimeToStrF(t); +} + +// t [nsec] を文字列にして返す。 +// 秒以上はすべて %u だけで表す。 +// 1桁秒以内 (10秒未満) なことが分かっている場合は 13桁。 +// 2桁秒以上になると伸びていく。前に余白等なし。 +// ex) +// "1.000'000'000" (10秒未満なら13桁) +// "10.000'000'000" +// "100.000'000'000" +const std::string +SecToStr(uint64 t) +{ + return TimeToStrF(t); +} + #if defined(SELFTEST) #include @@ -226,8 +322,8 @@ int main() return 0; } sw.Stop(); - uint64 t = sw.Elapsed(); - printf("%ld.%03ld msec\n", t / 1000 / 1000, (t / 1000) % 1000); + uint64 t = sw.Elapsed_nsec(); + printf("%.3f msec\n", (double)t / 1e9); return 0; } #endif