From 3512ef801839feeb20d178776fff999e1da532fd Mon Sep 17 00:00:00 2001 From: Ron Yorston Date: Tue, 14 Sep 2021 08:52:49 +0100 Subject: libbb: code shrink parse_datestr The default build uses strptime() in parse_datestr() to support the 'month_name d HH:MM:SS YYYY' format of GNU date. If we've linked with strptime() there's an advantage is using it for other formats too. There's no change to the non-default, non-DESKTOP build. function old new delta fmt_str - 106 +106 .rodata 99216 99145 -71 parse_datestr 948 624 -324 ------------------------------------------------------------------------------ (add/remove: 1/0 grow/shrink: 0/2 up/down: 106/-395) Total: -289 bytes Signed-off-by: Ron Yorston Signed-off-by: Denys Vlasenko --- libbb/time.c | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/libbb/time.c b/libbb/time.c index cf5f2e5..365b1df 100644 --- a/libbb/time.c +++ b/libbb/time.c @@ -11,13 +11,45 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) { char end = '\0'; +#if ENABLE_DESKTOP +/* + * strptime is BIG: ~1k in uclibc, ~10k in glibc + * We need it for 'month_name d HH:MM:SS YYYY', supported by GNU date, + * but if we've linked it we might as well use it for everything. + */ + static const char fmt_str[] ALIGN1 = + "%R" "\0" /* HH:MM */ + "%T" "\0" /* HH:MM:SS */ + "%m.%d-%R" "\0" /* mm.dd-HH:MM */ + "%m.%d-%T" "\0" /* mm.dd-HH:MM:SS */ + "%Y.%m.%d-%R" "\0" /* yyyy.mm.dd-HH:MM */ + "%Y.%m.%d-%T" "\0" /* yyyy.mm.dd-HH:MM:SS */ + "%b %d %T %Y" "\0" /* month_name d HH:MM:SS YYYY */ + "%Y-%m-%d %R" "\0" /* yyyy-mm-dd HH:MM */ + "%Y-%m-%d %T" "\0" /* yyyy-mm-dd HH:MM:SS */ + "%Y-%m-%d %H" "\0" /* yyyy-mm-dd HH */ + "%Y-%m-%d" "\0" /* yyyy-mm-dd */ + /* extra NUL */; + struct tm save; + const char *fmt; + char *endp; + + save = *ptm; + fmt = fmt_str; + while (*fmt) { + endp = strptime(date_str, fmt, ptm); + if (endp && *endp == '\0') + return; + *ptm = save; + while (*++fmt) + continue; + ++fmt; + } +#else const char *last_colon = strrchr(date_str, ':'); if (last_colon != NULL) { /* Parse input and assign appropriately to ptm */ -#if ENABLE_DESKTOP - const char *endp; -#endif /* HH:MM */ if (sscanf(date_str, "%u:%u%c", @@ -50,14 +82,6 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) ptm->tm_year -= 1900; /* Adjust years */ ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ } else -#if ENABLE_DESKTOP /* strptime is BIG: ~1k in uclibc, ~10k in glibc */ - /* month_name d HH:MM:SS YYYY. Supported by GNU date */ - if ((endp = strptime(date_str, "%b %d %T %Y", ptm)) != NULL - && *endp == '\0' - ) { - return; /* don't fall through to end == ":" check */ - } else -#endif { bb_error_msg_and_die(bb_msg_invalid_date, date_str); } @@ -89,6 +113,7 @@ void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm) ptm->tm_year -= 1900; /* Adjust years */ ptm->tm_mon -= 1; /* Adjust month from 1-12 to 0-11 */ } else +#endif /* ENABLE_DESKTOP */ if (date_str[0] == '@') { time_t t; if (sizeof(t) <= sizeof(long)) -- cgit v1.1