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 <[email protected]>
---
 libbb/time.c | 49 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 11 deletions(-)

diff --git a/libbb/time.c b/libbb/time.c
index cf5f2e5c8..1a00953b2 100644
--- a/libbb/time.c
+++ b/libbb/time.c
@@ -8,16 +8,50 @@
  */
 #include "libbb.h"
 
+#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 */;
+#endif
+
 void FAST_FUNC parse_datestr(const char *date_str, struct tm *ptm)
 {
        char end = '\0';
+#if ENABLE_DESKTOP
+       struct tm save;
+       const char *fmt;
+       char *endp;
+
+       save = *ptm;
+       fmt = fmt_str;
+       while (*fmt) {
+               if ((endp = strptime(date_str, fmt, ptm)) != NULL && *endp == 
'\0')
+                       return;
+               *ptm = save;
+               while (*++fmt)
+                       ;
+               ++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 +84,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 +115,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))
-- 
2.31.1

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to