diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-04 18:19:15 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-04 18:19:15 +0200 |
commit | 6c2406ac861f42536acb76606c90412324a0e733 (patch) | |
tree | e5a06a205f1590eadb267a78bb3a706f359243d3 | |
parent | 8878c24c7d15fe0d4df73aa8477251c6583f5157 (diff) | |
download | busybox-w32-6c2406ac861f42536acb76606c90412324a0e733.tar.gz busybox-w32-6c2406ac861f42536acb76606c90412324a0e733.tar.bz2 busybox-w32-6c2406ac861f42536acb76606c90412324a0e733.zip |
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>
-rw-r--r-- | coreutils/Config.in | 7 | ||||
-rw-r--r-- | coreutils/date.c | 59 |
2 files changed, 60 insertions, 6 deletions
diff --git a/coreutils/Config.in b/coreutils/Config.in index ead632a31..37e885c1c 100644 --- a/coreutils/Config.in +++ b/coreutils/Config.in | |||
@@ -115,6 +115,13 @@ config FEATURE_DATE_ISOFMT | |||
115 | Enable option (-I) to output an ISO-8601 compliant | 115 | Enable option (-I) to output an ISO-8601 compliant |
116 | date/time string. | 116 | date/time string. |
117 | 117 | ||
118 | config FEATURE_DATE_NANO | ||
119 | bool "Support %[num]N nanosecond format specifier" | ||
120 | default y | ||
121 | depends on DATE | ||
122 | help | ||
123 | Support %[num]N format specifier. Adds ~250 bytes of code. | ||
124 | |||
118 | config FEATURE_DATE_COMPAT | 125 | config FEATURE_DATE_COMPAT |
119 | bool "Support weird 'date MMDDhhmm[[YY]YY][.ss]' format" | 126 | bool "Support weird 'date MMDDhhmm[[YY]YY][.ss]' format" |
120 | default y | 127 | default y |
diff --git a/coreutils/date.c b/coreutils/date.c index 4e5b3b0b8..c1390be76 100644 --- a/coreutils/date.c +++ b/coreutils/date.c | |||
@@ -84,9 +84,9 @@ static const char date_longopts[] ALIGN1 = | |||
84 | int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 84 | int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
85 | int date_main(int argc UNUSED_PARAM, char **argv) | 85 | int date_main(int argc UNUSED_PARAM, char **argv) |
86 | { | 86 | { |
87 | struct timespec ts; | ||
87 | struct tm tm_time; | 88 | struct tm tm_time; |
88 | char buf_fmt_dt2str[64]; | 89 | char buf_fmt_dt2str[64]; |
89 | time_t tm; | ||
90 | unsigned opt; | 90 | unsigned opt; |
91 | int ifmt = -1; | 91 | int ifmt = -1; |
92 | char *date_str; | 92 | char *date_str; |
@@ -161,11 +161,18 @@ int date_main(int argc UNUSED_PARAM, char **argv) | |||
161 | if (opt & OPT_REFERENCE) { | 161 | if (opt & OPT_REFERENCE) { |
162 | struct stat statbuf; | 162 | struct stat statbuf; |
163 | xstat(filename, &statbuf); | 163 | xstat(filename, &statbuf); |
164 | tm = statbuf.st_mtime; | 164 | ts.tv_sec = statbuf.st_mtime; |
165 | #if ENABLE_FEATURE_DATE_NANO | ||
166 | ts.tv_nsec = statbuf.st_mtimensec; //or st_atim.tv_nsec? | ||
167 | #endif | ||
165 | } else { | 168 | } else { |
166 | time(&tm); | 169 | #if ENABLE_FEATURE_DATE_NANO |
170 | clock_gettime(CLOCK_REALTIME, &ts); | ||
171 | #else | ||
172 | time(&ts.tv_nsec); | ||
173 | #endif | ||
167 | } | 174 | } |
168 | localtime_r(&tm, &tm_time); | 175 | localtime_r(&ts.tv_sec, &tm_time); |
169 | 176 | ||
170 | /* If date string is given, update tm_time, and maybe set date */ | 177 | /* If date string is given, update tm_time, and maybe set date */ |
171 | if (date_str != NULL) { | 178 | if (date_str != NULL) { |
@@ -184,12 +191,12 @@ int date_main(int argc UNUSED_PARAM, char **argv) | |||
184 | 191 | ||
185 | /* Correct any day of week and day of year etc. fields */ | 192 | /* Correct any day of week and day of year etc. fields */ |
186 | tm_time.tm_isdst = -1; /* Be sure to recheck dst */ | 193 | tm_time.tm_isdst = -1; /* Be sure to recheck dst */ |
187 | tm = validate_tm_time(date_str, &tm_time); | 194 | ts.tv_sec = validate_tm_time(date_str, &tm_time); |
188 | 195 | ||
189 | maybe_set_utc(opt); | 196 | maybe_set_utc(opt); |
190 | 197 | ||
191 | /* if setting time, set it */ | 198 | /* if setting time, set it */ |
192 | if ((opt & OPT_SET) && stime(&tm) < 0) { | 199 | if ((opt & OPT_SET) && stime(&ts.tv_sec) < 0) { |
193 | bb_perror_msg("can't set date"); | 200 | bb_perror_msg("can't set date"); |
194 | } | 201 | } |
195 | } | 202 | } |
@@ -222,6 +229,46 @@ int date_main(int argc UNUSED_PARAM, char **argv) | |||
222 | fmt_dt2str = (char*)"%a %b %e %H:%M:%S %Z %Y"; | 229 | fmt_dt2str = (char*)"%a %b %e %H:%M:%S %Z %Y"; |
223 | } | 230 | } |
224 | } | 231 | } |
232 | #if ENABLE_FEATURE_DATE_NANO | ||
233 | else { | ||
234 | /* User-specified fmt_dt2str */ | ||
235 | /* Search for and process "%N" */ | ||
236 | char *p = fmt_dt2str; | ||
237 | while ((p = strchr(p, '%')) != NULL) { | ||
238 | int n, m; | ||
239 | unsigned pres, scale; | ||
240 | |||
241 | p++; | ||
242 | if (*p == '%') { | ||
243 | p++; | ||
244 | continue; | ||
245 | } | ||
246 | n = strspn(p, "0123456789"); | ||
247 | if (p[n] != 'N') { | ||
248 | p += n; | ||
249 | continue; | ||
250 | } | ||
251 | /* We have "%[nnn]N" */ | ||
252 | p[-1] = '\0'; | ||
253 | p[n] = '\0'; | ||
254 | scale = 1; | ||
255 | pres = 9; | ||
256 | if (n) { | ||
257 | pres = xatoi_u(p); | ||
258 | if (pres == 0) | ||
259 | pres = 9; | ||
260 | m = 9 - pres; | ||
261 | while (--m >= 0) | ||
262 | scale *= 10; | ||
263 | } | ||
264 | |||
265 | m = p - fmt_dt2str; | ||
266 | p += n + 1; | ||
267 | fmt_dt2str = xasprintf("%s%0*u%s", fmt_dt2str, pres, (unsigned)ts.tv_nsec / scale, p); | ||
268 | p = fmt_dt2str + m; | ||
269 | } | ||
270 | } | ||
271 | #endif | ||
225 | 272 | ||
226 | #define date_buf bb_common_bufsiz1 | 273 | #define date_buf bb_common_bufsiz1 |
227 | if (*fmt_dt2str == '\0') { | 274 | if (*fmt_dt2str == '\0') { |