date: optional support for %N. Closes bug 1861.
function old new delta date_main 862 1090 +228 clock_gettime - 41 +41 ------------------------------------------------------------------------------ (add/remove: 2/0 grow/shrink: 1/0 up/down: 269/0) Total: 269 bytes Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
8878c24c7d
commit
6c2406ac86
@ -115,6 +115,13 @@ config FEATURE_DATE_ISOFMT
|
||||
Enable option (-I) to output an ISO-8601 compliant
|
||||
date/time string.
|
||||
|
||||
config FEATURE_DATE_NANO
|
||||
bool "Support %[num]N nanosecond format specifier"
|
||||
default y
|
||||
depends on DATE
|
||||
help
|
||||
Support %[num]N format specifier. Adds ~250 bytes of code.
|
||||
|
||||
config FEATURE_DATE_COMPAT
|
||||
bool "Support weird 'date MMDDhhmm[[YY]YY][.ss]' format"
|
||||
default y
|
||||
|
@ -84,9 +84,9 @@ static const char date_longopts[] ALIGN1 =
|
||||
int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
||||
int date_main(int argc UNUSED_PARAM, char **argv)
|
||||
{
|
||||
struct timespec ts;
|
||||
struct tm tm_time;
|
||||
char buf_fmt_dt2str[64];
|
||||
time_t tm;
|
||||
unsigned opt;
|
||||
int ifmt = -1;
|
||||
char *date_str;
|
||||
@ -161,11 +161,18 @@ int date_main(int argc UNUSED_PARAM, char **argv)
|
||||
if (opt & OPT_REFERENCE) {
|
||||
struct stat statbuf;
|
||||
xstat(filename, &statbuf);
|
||||
tm = statbuf.st_mtime;
|
||||
ts.tv_sec = statbuf.st_mtime;
|
||||
#if ENABLE_FEATURE_DATE_NANO
|
||||
ts.tv_nsec = statbuf.st_mtimensec; //or st_atim.tv_nsec?
|
||||
#endif
|
||||
} else {
|
||||
time(&tm);
|
||||
#if ENABLE_FEATURE_DATE_NANO
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
#else
|
||||
time(&ts.tv_nsec);
|
||||
#endif
|
||||
}
|
||||
localtime_r(&tm, &tm_time);
|
||||
localtime_r(&ts.tv_sec, &tm_time);
|
||||
|
||||
/* If date string is given, update tm_time, and maybe set date */
|
||||
if (date_str != NULL) {
|
||||
@ -184,12 +191,12 @@ int date_main(int argc UNUSED_PARAM, char **argv)
|
||||
|
||||
/* Correct any day of week and day of year etc. fields */
|
||||
tm_time.tm_isdst = -1; /* Be sure to recheck dst */
|
||||
tm = validate_tm_time(date_str, &tm_time);
|
||||
ts.tv_sec = validate_tm_time(date_str, &tm_time);
|
||||
|
||||
maybe_set_utc(opt);
|
||||
|
||||
/* if setting time, set it */
|
||||
if ((opt & OPT_SET) && stime(&tm) < 0) {
|
||||
if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) {
|
||||
bb_perror_msg("can't set date");
|
||||
}
|
||||
}
|
||||
@ -222,6 +229,46 @@ int date_main(int argc UNUSED_PARAM, char **argv)
|
||||
fmt_dt2str = (char*)"%a %b %e %H:%M:%S %Z %Y";
|
||||
}
|
||||
}
|
||||
#if ENABLE_FEATURE_DATE_NANO
|
||||
else {
|
||||
/* User-specified fmt_dt2str */
|
||||
/* Search for and process "%N" */
|
||||
char *p = fmt_dt2str;
|
||||
while ((p = strchr(p, '%')) != NULL) {
|
||||
int n, m;
|
||||
unsigned pres, scale;
|
||||
|
||||
p++;
|
||||
if (*p == '%') {
|
||||
p++;
|
||||
continue;
|
||||
}
|
||||
n = strspn(p, "0123456789");
|
||||
if (p[n] != 'N') {
|
||||
p += n;
|
||||
continue;
|
||||
}
|
||||
/* We have "%[nnn]N" */
|
||||
p[-1] = '\0';
|
||||
p[n] = '\0';
|
||||
scale = 1;
|
||||
pres = 9;
|
||||
if (n) {
|
||||
pres = xatoi_u(p);
|
||||
if (pres == 0)
|
||||
pres = 9;
|
||||
m = 9 - pres;
|
||||
while (--m >= 0)
|
||||
scale *= 10;
|
||||
}
|
||||
|
||||
m = p - fmt_dt2str;
|
||||
p += n + 1;
|
||||
fmt_dt2str = xasprintf("%s%0*u%s", fmt_dt2str, pres, (unsigned)ts.tv_nsec / scale, p);
|
||||
p = fmt_dt2str + m;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define date_buf bb_common_bufsiz1
|
||||
if (*fmt_dt2str == '\0') {
|
||||
|
Loading…
Reference in New Issue
Block a user