Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/time A going-over with the optimiser, save over 500...



details:   https://anonhg.NetBSD.org/src/rev/f31e0a76c023
branches:  trunk
changeset: 574568:f31e0a76c023
user:      dsl <dsl%NetBSD.org@localhost>
date:      Fri Mar 04 21:41:42 2005 +0000

description:
A going-over with the optimiser, save over 500 bytes.
I think this is enough to get rescue_tiny to fit again.
While there fix some bugs:
- %y failed to subtract 1900 from tm_year
- %p (am/pm) only worked at the end of the string
- %E% was treated at %% (ie match a % character)
regression test being added....

diffstat:

 lib/libc/time/strptime.c |  292 +++++++++++++++++++---------------------------
 1 files changed, 124 insertions(+), 168 deletions(-)

diffs (truncated from 479 to 300 lines):

diff -r 7d9d5eb65656 -r f31e0a76c023 lib/libc/time/strptime.c
--- a/lib/libc/time/strptime.c  Fri Mar 04 21:16:10 2005 +0000
+++ b/lib/libc/time/strptime.c  Fri Mar 04 21:41:42 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: strptime.c,v 1.22 2000/12/20 20:56:34 christos Exp $   */
+/*     $NetBSD: strptime.c,v 1.23 2005/03/04 21:41:42 dsl Exp $        */
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: strptime.c,v 1.22 2000/12/20 20:56:34 christos Exp $");
+__RCSID("$NetBSD: strptime.c,v 1.23 2005/03/04 21:41:42 dsl Exp $");
 #endif
 
 #include "namespace.h"
@@ -60,27 +60,28 @@
  */
 #define ALT_E                  0x01
 #define ALT_O                  0x02
-#define        LEGAL_ALT(x)            { if (alt_format & ~(x)) return (0); }
+#define        LEGAL_ALT(x)            { if (alt_format & ~(x)) return 0; }
 
 
-static int conv_num __P((const unsigned char **, int *, int, int));
+static const u_char *conv_num(const unsigned char *, int *, int, int);
+static const u_char *find_string(const u_char *, int *, const char * const *,
+       const char * const *, int);
 
 
 char *
-strptime(buf, fmt, tm)
-       const char *buf, *fmt;
-       struct tm *tm;
+strptime(const char *buf, const char *fmt, struct tm *tm)
 {
        unsigned char c;
        const unsigned char *bp;
-       size_t len = 0;
        int alt_format, i, split_year = 0;
+       const char *new_fmt;
 
        bp = (const u_char *)buf;
 
-       while ((c = *fmt) != '\0') {
+       while (bp != NULL && (c = *fmt) != '\0') {
                /* Clear `alternate' modifier prior to new conversion. */
                alt_format = 0;
+               i = 0;
 
                /* Eat up white-space. */
                if (isspace(c)) {
@@ -90,7 +91,7 @@
                        fmt++;
                        continue;
                }
-                               
+
                if ((c = *fmt++) != '%')
                        goto literal;
 
@@ -99,8 +100,9 @@
                case '%':       /* "%%" is converted to "%". */
 literal:
                        if (c != *bp++)
-                               return (0);
-                       break;
+                               return 0;
+                       LEGAL_ALT(0);
+                       continue;
 
                /*
                 * "Alternative" modifiers. Just set the appropriate flag
@@ -115,117 +117,68 @@
                        LEGAL_ALT(0);
                        alt_format |= ALT_O;
                        goto again;
-                       
+
                /*
                 * "Complex" conversion rules, implemented through recursion.
                 */
                case 'c':       /* Date and time, using the locale's format. */
-                       LEGAL_ALT(ALT_E);
-                       if (!(bp = (const u_char *)strptime((const char *)bp,
-                           _ctloc(d_t_fmt), tm)))
-                               return (0);
-                       break;
+                       new_fmt = _ctloc(d_t_fmt);
+                       goto recurse;
 
                case 'D':       /* The date as "%m/%d/%y". */
+                       new_fmt = "%m/%d/%y";
                        LEGAL_ALT(0);
-                       if (!(bp = (const u_char *) strptime((const char *)bp,
-                           "%m/%d/%y", tm)))
-                               return (0);
-                       break;
+                       goto recurse;
 
                case 'R':       /* The time as "%H:%M". */
+                       new_fmt = "%H:%M";
                        LEGAL_ALT(0);
-                       if (!(bp = (const u_char *)strptime((const char *)bp,
-                           "%H:%M", tm)))
-                               return (0);
-                       break;
+                       goto recurse;
 
                case 'r':       /* The time in 12-hour clock representation. */
+                       new_fmt =_ctloc(t_fmt_ampm);
                        LEGAL_ALT(0);
-                       if (!(bp = (const u_char *)strptime((const char *)bp,
-                           _ctloc(t_fmt_ampm), tm)))
-                               return (0);
-                       break;
+                       goto recurse;
 
                case 'T':       /* The time as "%H:%M:%S". */
+                       new_fmt = "%H:%M:%S";
                        LEGAL_ALT(0);
-                       if (!(bp = (const u_char *)strptime((const char *)bp,
-                           "%H:%M:%S", tm)))
-                               return (0);
-                       break;
+                       goto recurse;
 
                case 'X':       /* The time, using the locale's format. */
-                       LEGAL_ALT(ALT_E);
-                       if (!(bp = (const u_char *)strptime((const char *)bp,
-                           _ctloc(t_fmt), tm)))
-                               return (0);
-                       break;
+                       new_fmt =_ctloc(t_fmt);
+                       goto recurse;
 
                case 'x':       /* The date, using the locale's format. */
+                       new_fmt =_ctloc(d_fmt);
+                   recurse:
+                       bp = (const u_char *)strptime((const char *)bp,
+                                                           new_fmt, tm);
                        LEGAL_ALT(ALT_E);
-                       if (!(bp = (const u_char *)strptime((const char *)bp,
-                           _ctloc(d_fmt), tm)))
-                               return (0);
-                       break;
+                       continue;
 
                /*
                 * "Elementary" conversion rules.
                 */
                case 'A':       /* The day of week, using the locale's form. */
                case 'a':
+                       bp = find_string(bp, &tm->tm_wday, _ctloc(day),
+                                       _ctloc(abday), 7);
                        LEGAL_ALT(0);
-                       for (i = 0; i < 7; i++) {
-                               /* Full name. */
-                               len = strlen(_ctloc(day[i]));
-                               if (strncasecmp(_ctloc(day[i]),
-                                   (const char *)bp, len) == 0)
-                                       break;
-
-                               /* Abbreviated name. */
-                               len = strlen(_ctloc(abday[i]));
-                               if (strncasecmp(_ctloc(abday[i]),
-                                   (const char *)bp, len) == 0)
-                                       break;
-                       }
-
-                       /* Nothing matched. */
-                       if (i == 7)
-                               return (0);
-
-                       tm->tm_wday = i;
-                       bp += len;
-                       break;
+                       continue;
 
                case 'B':       /* The month, using the locale's form. */
                case 'b':
                case 'h':
+                       bp = find_string(bp, &tm->tm_mon, _ctloc(mon),
+                                       _ctloc(abmon), 12);
                        LEGAL_ALT(0);
-                       for (i = 0; i < 12; i++) {
-                               /* Full name. */
-                               len = strlen(_ctloc(mon[i]));
-                               if (strncasecmp(_ctloc(mon[i]),
-                                   (const char *)bp, len) == 0)
-                                       break;
-
-                               /* Abbreviated name. */
-                               len = strlen(_ctloc(abmon[i]));
-                               if (strncasecmp(_ctloc(abmon[i]),
-                                   (const char *)bp, len) == 0)
-                                       break;
-                       }
-
-                       /* Nothing matched. */
-                       if (i == 12)
-                               return (0);
-
-                       tm->tm_mon = i;
-                       bp += len;
-                       break;
+                       continue;
 
                case 'C':       /* The century number. */
-                       LEGAL_ALT(ALT_E);
-                       if (!(conv_num(&bp, &i, 0, 99)))
-                               return (0);
+                       bp = conv_num(bp, &i, 0, 99);
+                       if (bp == NULL)
+                               return NULL;
 
                        if (split_year) {
                                tm->tm_year = (tm->tm_year % 100) + (i * 100);
@@ -233,175 +186,178 @@
                                tm->tm_year = i * 100;
                                split_year = 1;
                        }
-                       break;
+                       tm->tm_year -= TM_YEAR_BASE;
+                       LEGAL_ALT(ALT_E);
+                       continue;
 
                case 'd':       /* The day of month. */
                case 'e':
+                       bp = conv_num(bp, &tm->tm_mday, 1, 31);
                        LEGAL_ALT(ALT_O);
-                       if (!(conv_num(&bp, &tm->tm_mday, 1, 31)))
-                               return (0);
-                       break;
+                       continue;
 
                case 'k':       /* The hour (24-hour clock representation). */
                        LEGAL_ALT(0);
                        /* FALLTHROUGH */
                case 'H':
+                       bp = conv_num(bp, &tm->tm_hour, 0, 23);
                        LEGAL_ALT(ALT_O);
-                       if (!(conv_num(&bp, &tm->tm_hour, 0, 23)))
-                               return (0);
-                       break;
+                       continue;
 
                case 'l':       /* The hour (12-hour clock representation). */
                        LEGAL_ALT(0);
                        /* FALLTHROUGH */
                case 'I':
-                       LEGAL_ALT(ALT_O);
-                       if (!(conv_num(&bp, &tm->tm_hour, 1, 12)))
-                               return (0);
+                       bp = conv_num(bp, &tm->tm_hour, 1, 12);
                        if (tm->tm_hour == 12)
                                tm->tm_hour = 0;
-                       break;
+                       LEGAL_ALT(ALT_O);
+                       continue;
 
                case 'j':       /* The day of year. */
+                       i = 1;
+                       bp = conv_num(bp, &i, 1, 366);
+                       tm->tm_yday = i - 1;
                        LEGAL_ALT(0);
-                       if (!(conv_num(&bp, &i, 1, 366)))
-                               return (0);
-                       tm->tm_yday = i - 1;
-                       break;
+                       continue;
 
                case 'M':       /* The minute. */
+                       bp = conv_num(bp, &tm->tm_min, 0, 59);
                        LEGAL_ALT(ALT_O);
-                       if (!(conv_num(&bp, &tm->tm_min, 0, 59)))
-                               return (0);
-                       break;
+                       continue;
 
                case 'm':       /* The month. */
+                       i = 1;
+                       bp = conv_num(bp, &i, 1, 12);
+                       tm->tm_mon = i - 1;
                        LEGAL_ALT(ALT_O);
-                       if (!(conv_num(&bp, &i, 1, 12)))
-                               return (0);
-                       tm->tm_mon = i - 1;
-                       break;
+                       continue;
 
                case 'p':       /* The locale's equivalent of AM/PM. */
+                       bp = find_string(bp, &i, _ctloc(am_pm),
+                                       _ctloc(am_pm), 2);
+                       if (tm->tm_hour > 11)
+                               return 0;
+                       tm->tm_hour += i * 12;
                        LEGAL_ALT(0);



Home | Main Index | Thread Index | Old Index