summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1998-03-15 23:31:01 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1998-03-15 23:31:01 +0000
commite916a7ff825f43b5a1250562d17be80ca3baa15d (patch)
tree85c92760cbf33f4220a82ad29d238b87fd87322e /lib/libc
parent3abe696b31739117e3d2f91b0c52fd4188943a28 (diff)
%C influences %y regardless of ordering. This becomes a bit tricky
due to recursion so we do all the work in _strptime which takes an extra flag specifying whether or not to initialize some statics.
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/time/strptime.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/lib/libc/time/strptime.c b/lib/libc/time/strptime.c
index c1f6cbbf5f5..996d212b9e8 100644
--- a/lib/libc/time/strptime.c
+++ b/lib/libc/time/strptime.c
@@ -36,7 +36,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: strptime.c,v 1.2 1998/03/15 06:49:01 millert Exp $";
+static char rcsid[] = "$OpenBSD: strptime.c,v 1.3 1998/03/15 23:31:00 millert Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/localedef.h>
@@ -58,6 +58,7 @@ static char rcsid[] = "$OpenBSD: strptime.c,v 1.2 1998/03/15 06:49:01 millert Ex
static int _conv_num __P((const char **, int *, int, int));
+static char *_strptime __P((const char *, const char *, struct tm *, int));
char *
@@ -65,13 +66,26 @@ strptime(buf, fmt, tm)
const char *buf, *fmt;
struct tm *tm;
{
+ return(_strptime(buf, fmt, tm, 1));
+}
+
+static char *
+_strptime(buf, fmt, tm, initialize)
+ const char *buf, *fmt;
+ struct tm *tm;
+ int initialize;
+{
char c;
const char *bp;
int alt_format, i, len;
- int century = TM_YEAR_BASE;
+ static int century, relyear;
- bp = buf;
+ if (initialize) {
+ century = TM_YEAR_BASE;
+ relyear = -1;
+ }
+ bp = buf;
while ((c = *fmt) != '\0') {
/* Clear `alternate' modifier prior to new conversion. */
alt_format = 0;
@@ -116,43 +130,43 @@ literal:
*/
case 'c': /* Date and time, using the locale's format. */
_LEGAL_ALT(_ALT_E);
- if (!(bp = strptime(bp, _ctloc(d_t_fmt), tm)))
+ if (!(bp = _strptime(bp, _ctloc(d_t_fmt), tm, 0)))
return (0);
break;
case 'D': /* The date as "%m/%d/%y". */
_LEGAL_ALT(0);
- if (!(bp = strptime(bp, "%m/%d/%y", tm)))
+ if (!(bp = _strptime(bp, "%m/%d/%y", tm, 0)))
return (0);
break;
case 'R': /* The time as "%H:%M". */
_LEGAL_ALT(0);
- if (!(bp = strptime(bp, "%H:%M", tm)))
+ if (!(bp = _strptime(bp, "%H:%M", tm, 0)))
return (0);
break;
case 'r': /* The time as "%I:%M:%S %p". */
_LEGAL_ALT(0);
- if (!(bp = strptime(bp, "%I:%M:%S %p", tm)))
+ if (!(bp = _strptime(bp, "%I:%M:%S %p", tm, 0)))
return (0);
break;
case 'T': /* The time as "%H:%M:%S". */
_LEGAL_ALT(0);
- if (!(bp = strptime(bp, "%H:%M:%S", tm)))
+ if (!(bp = _strptime(bp, "%H:%M:%S", tm, 0)))
return (0);
break;
case 'X': /* The time, using the locale's format. */
_LEGAL_ALT(_ALT_E);
- if (!(bp = strptime(bp, _ctloc(t_fmt), tm)))
+ if (!(bp = _strptime(bp, _ctloc(t_fmt), tm, 0)))
return (0);
break;
case 'x': /* The date, using the locale's format. */
_LEGAL_ALT(_ALT_E);
- if (!(bp = strptime(bp, _ctloc(d_fmt), tm)))
+ if (!(bp = _strptime(bp, _ctloc(d_fmt), tm, 0)))
return (0);
break;
@@ -320,17 +334,8 @@ literal:
case 'y': /* The year within the century (2 digits). */
_LEGAL_ALT(_ALT_E | _ALT_O);
- if (!(_conv_num(&bp, &i, 0, 99)))
+ if (!(_conv_num(&bp, &relyear, 0, 99)))
return (0);
-
- if (century == TM_YEAR_BASE) {
- if (i <= 68)
- tm->tm_year = i + 2000 - TM_YEAR_BASE;
- else
- tm->tm_year = i + 1900 - TM_YEAR_BASE;
- } else {
- tm->tm_year = i + century - TM_YEAR_BASE;
- }
break;
/*
@@ -351,6 +356,21 @@ literal:
}
+ /*
+ * We need to evaluate the two digit year spec (%y)
+ * last as we can get a century spec (%C) at any time.
+ */
+ if (relyear != -1) {
+ if (century == TM_YEAR_BASE) {
+ if (relyear <= 68)
+ tm->tm_year = relyear + 2000 - TM_YEAR_BASE;
+ else
+ tm->tm_year = relyear + 1900 - TM_YEAR_BASE;
+ } else {
+ tm->tm_year = relyear + century - TM_YEAR_BASE;
+ }
+ }
+
return ((char *)bp);
}