[git commit] libbb: code shrink parse_datestr

Denys Vlasenko vda.linux at googlemail.com
Wed Sep 15 06:09:45 UTC 2021


commit: https://git.busybox.net/busybox/commit/?id=3512ef801839feeb20d178776fff999e1da532fd
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 <rmy at pobox.com>
Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 libbb/time.c | 47 ++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 36 insertions(+), 11 deletions(-)

diff --git a/libbb/time.c b/libbb/time.c
index cf5f2e5c8..365b1df02 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))


More information about the busybox-cvs mailing list