| 1004 | and omit any trailing tabs. */ |
| 1005 | |
| 1006 | static bool |
| 1007 | istrftime(char *buf, ptrdiff_t size, char const *time_fmt, |
| 1008 | struct tm const *tm, time_t t, char const *ab, char const *zone_name) |
| 1009 | { |
| 1010 | char *b = buf; |
| 1011 | ptrdiff_t s = size; |
| 1012 | char const *f = time_fmt, *p; |
| 1013 | |
| 1014 | for (p = f; ; p++) |
| 1015 | if (*p == '%' && p[1] == '%') |
| 1016 | p++; |
| 1017 | else if (!*p |
| 1018 | || (*p == '%' |
| 1019 | && (p[1] == 'f' || p[1] == 'L' || p[1] == 'Q'))) { |
| 1020 | ptrdiff_t formatted_len; |
| 1021 | ptrdiff_t f_prefix_len = p - f; |
| 1022 | ptrdiff_t f_prefix_copy_size = sumsize(f_prefix_len, 2); |
| 1023 | char fbuf[100]; |
| 1024 | bool oversized = sizeof fbuf <= f_prefix_copy_size; |
| 1025 | char *f_prefix_copy = oversized ? xmalloc(f_prefix_copy_size) : fbuf; |
| 1026 | char *cp = f_prefix_copy; |
| 1027 | cp = mempcpy(cp, f, f_prefix_len); |
| 1028 | strcpy(cp, "X"); |
| 1029 | formatted_len = strftime(b, s, f_prefix_copy, tm); |
| 1030 | if (oversized) |
| 1031 | free(f_prefix_copy); |
| 1032 | if (formatted_len == 0) |
| 1033 | return false; |
| 1034 | formatted_len--; |
| 1035 | b += formatted_len, s -= formatted_len; |
| 1036 | if (!*p++) |
| 1037 | break; |
| 1038 | switch (*p) { |
| 1039 | case 'f': |
| 1040 | formatted_len = format_quoted_string(b, s, zone_name); |
| 1041 | break; |
| 1042 | case 'L': |
| 1043 | formatted_len = format_local_time(b, s, tm); |
| 1044 | break; |
| 1045 | case 'Q': |
| 1046 | { |
| 1047 | bool show_abbr; |
| 1048 | int offlen = format_utc_offset(b, s, tm, t); |
| 1049 | if (! (0 <= offlen && offlen < s)) |
| 1050 | return false; |
| 1051 | show_abbr = strcmp(b, ab) != 0; |
| 1052 | b += offlen, s -= offlen; |
| 1053 | if (show_abbr) { |
| 1054 | char const *abp; |
| 1055 | ptrdiff_t len; |
| 1056 | if (s <= 1) |
| 1057 | return false; |
| 1058 | *b++ = '\t', s--; |
| 1059 | for (abp = ab; is_alpha(*abp); abp++) |
| 1060 | continue; |
| 1061 | len = (!*abp && *ab |
| 1062 | ? snprintf(b, s, "%s", ab) |
| 1063 | : format_quoted_string(b, s, ab)); |
no test coverage detected