Index: bin/ls/print.c =================================================================== --- bin/ls/print.c +++ bin/ls/print.c @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -105,6 +106,11 @@ } colors[C_NUMCOLORS]; #endif +#define MAX_ABMON_WIDTH 5 +/* static list of month */ +static char abbreviated_months[12][ MAX_ABMON_WIDTH * 2 * MB_LEN_MAX ]; +static int max_width_month = 0; + void printscol(const DISPLAY *dp) { @@ -138,6 +144,54 @@ return rc; } +static int +pad_to_col(char *str, int maxcols, char c) +{ + int cols, i; + size_t len, pos; + + len = strlen(str); + cols = 0; + for (pos = 0; pos < len; pos++) { + if (str[pos] == '\0' || cols >= maxcols) + break; + if ((str[pos] & 0x80) == 0) { + cols++; + } else if ((str[pos] & 0xE0) == 0xC0) { + cols++; + pos++; + } else if ((str[pos] & 0xF0) == 0xE0) { + cols++; + pos+=2; + } else if ((str[pos] & 0xF8) == 0xF0) { + cols++; + pos+=3; + } + } + for (i = 0; i + cols <= maxcols; i++) + str[pos + i] = c; + return (cols); +} + +static void +populate_abbreviated_month(void) +{ + int i, cols; + + for (i = 0; i < 12; i++) { + strlcpy(abbreviated_months[i], nl_langinfo(ABMON_1 + i), + sizeof(abbreviated_months[i])); + cols = pad_to_col(abbreviated_months[i], MAX_ABMON_WIDTH, + ' '); + if (max_width_month < cols) + max_width_month = cols; + } + + for (i = 0; i < 12; i++) { + pad_to_col(abbreviated_months[i], max_width_month, '\0'); + } +} + /* * print name in current style */ @@ -425,6 +479,22 @@ xo_emit("{:device/%#*jx} ", (u_int)width, (uintmax_t)dev); } +static size_t +ls_strftime(char *str, size_t len, const char *fmt, const struct tm *tm) +{ + char *posb, nfmt[BUFSIZ]; + const char *format = fmt; + size_t ret; + + if (max_width_month > 0 && (posb = strstr(fmt, "%b")) != NULL) { + snprintf(nfmt, sizeof(nfmt), "%.*s%s%s", (int)(posb - fmt), + fmt, abbreviated_months[tm->tm_mon], posb + 2); + format = nfmt; + } + ret = strftime(str, len, format, tm); + return (ret); +} + static void printtime(const char *field, time_t ftime) { @@ -439,6 +509,9 @@ if (now == 0) now = time(NULL); + if (max_width_month == 0) + populate_abbreviated_month(); + #define SIXMONTHS ((365 / 2) * 86400) if (f_timeformat) /* user specified format */ format = f_timeformat; @@ -451,7 +524,7 @@ else /* mmm dd yyyy || dd mmm yyyy */ format = d_first ? "%e %b %Y" : "%b %e %Y"; - strftime(longstring, sizeof(longstring), format, localtime(&ftime)); + ls_strftime(longstring, sizeof(longstring), format, localtime(&ftime)); snprintf(fmt, sizeof(fmt), "{d:%s/%%hs} ", field); xo_attr("value", "%ld", (long) ftime);