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