Module Name: src
Committed By: ginsbach
Date: Thu May 14 02:37:37 UTC 2009
Modified Files:
src/distrib/sets/lists/base: mi
src/distrib/sets/lists/comp: mi
src/etc/mtree: NetBSD.dist
src/include: time.h
src/lib/libc/time: Makefile.inc
src/share/examples: Makefile
Added Files:
src/lib/libc/time: getdate.3 getdate.c
src/share/examples/getdate: Makefile datemsk.template posixmsk.example3
posixmsk.example4
Log Message:
Add the getdate(3) function and getdate_err value, conforming to IEEE
Std 1003.1 (``POSIX.1'') and the Open Group Base Specifications X/Open
System Interfaces extension (``XSI'').
To generate a diff of this commit:
cvs rdiff -u -r1.808 -r1.809 src/distrib/sets/lists/base/mi
cvs rdiff -u -r1.1259 -r1.1260 src/distrib/sets/lists/comp/mi
cvs rdiff -u -r1.399 -r1.400 src/etc/mtree/NetBSD.dist
cvs rdiff -u -r1.38 -r1.39 src/include/time.h
cvs rdiff -u -r1.11 -r1.12 src/lib/libc/time/Makefile.inc
cvs rdiff -u -r0 -r1.1 src/lib/libc/time/getdate.3 \
src/lib/libc/time/getdate.c
cvs rdiff -u -r1.17 -r1.18 src/share/examples/Makefile
cvs rdiff -u -r0 -r1.1 src/share/examples/getdate/Makefile \
src/share/examples/getdate/datemsk.template \
src/share/examples/getdate/posixmsk.example3 \
src/share/examples/getdate/posixmsk.example4
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/distrib/sets/lists/base/mi
diff -u src/distrib/sets/lists/base/mi:1.808 src/distrib/sets/lists/base/mi:1.809
--- src/distrib/sets/lists/base/mi:1.808 Fri May 8 23:28:46 2009
+++ src/distrib/sets/lists/base/mi Thu May 14 02:37:35 2009
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.808 2009/05/08 23:28:46 christos Exp $
+# $NetBSD: mi,v 1.809 2009/05/14 02:37:35 ginsbach Exp $
#
# Note: Don't delete entries from here - mark them as "obsolete" instead,
# unless otherwise stated below.
@@ -1787,6 +1787,7 @@
./usr/share/examples/emul/ultrix/etc base-sys-examples
./usr/share/examples/fstab base-fstab-examples
./usr/share/examples/ftpd base-netutil-examples
+./usr/share/examples/getdate base-sys-examples
./usr/share/examples/hostapd base-netutil-examples
./usr/share/examples/ipf base-netutil-examples
./usr/share/examples/isdn base-isdn-examples
Index: src/distrib/sets/lists/comp/mi
diff -u src/distrib/sets/lists/comp/mi:1.1259 src/distrib/sets/lists/comp/mi:1.1260
--- src/distrib/sets/lists/comp/mi:1.1259 Wed May 13 02:50:31 2009
+++ src/distrib/sets/lists/comp/mi Thu May 14 02:37:36 2009
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1259 2009/05/13 02:50:31 pgoyette Exp $
+# $NetBSD: mi,v 1.1260 2009/05/14 02:37:36 ginsbach Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@@ -5535,7 +5535,8 @@
./usr/share/man/cat3/getcurx.0 comp-c-catman .cat
./usr/share/man/cat3/getcury.0 comp-c-catman .cat
./usr/share/man/cat3/getcwd.0 comp-c-catman .cat
-./usr/share/man/cat3/getdate.0 comp-obsolete obsolete
+./usr/share/man/cat3/getdate.0 comp-c-catman .cat
+./usr/share/man/cat3/getdate_err.0 comp-c-catman .cat
./usr/share/man/cat3/getdevmajor.0 comp-c-catman .cat
./usr/share/man/cat3/getdirentries.0 comp-c-catman .cat
./usr/share/man/cat3/getdiskbyname.0 comp-c-catman .cat
@@ -16340,7 +16341,8 @@
./usr/share/man/man3/getcurx.3 comp-c-man .man
./usr/share/man/man3/getcury.3 comp-c-man .man
./usr/share/man/man3/getcwd.3 comp-c-man .man
-./usr/share/man/man3/getdate.3 comp-obsolete obsolete
+./usr/share/man/man3/getdate.3 comp-c-man .man
+./usr/share/man/man3/getdate_err.3 comp-c-man .man
./usr/share/man/man3/getdevmajor.3 comp-c-man .man
./usr/share/man/man3/getdirentries.3 comp-c-man .man
./usr/share/man/man3/getdiskbyname.3 comp-c-man .man
Index: src/etc/mtree/NetBSD.dist
diff -u src/etc/mtree/NetBSD.dist:1.399 src/etc/mtree/NetBSD.dist:1.400
--- src/etc/mtree/NetBSD.dist:1.399 Sat May 2 16:02:19 2009
+++ src/etc/mtree/NetBSD.dist Thu May 14 02:37:35 2009
@@ -1,4 +1,4 @@
-# $NetBSD: NetBSD.dist,v 1.399 2009/05/02 16:02:19 pooka Exp $
+# $NetBSD: NetBSD.dist,v 1.400 2009/05/14 02:37:35 ginsbach Exp $
# @(#)4.4BSD.dist 8.1 (Berkeley) 6/13/93
# Do not customize this file as it may be overwritten on upgrades.
@@ -677,6 +677,7 @@
./usr/share/examples/disktab
./usr/share/examples/fstab
./usr/share/examples/ftpd
+./usr/share/examples/getdate
./usr/share/examples/hostapd
./usr/share/examples/ipf
./usr/share/examples/isdn
Index: src/include/time.h
diff -u src/include/time.h:1.38 src/include/time.h:1.39
--- src/include/time.h:1.38 Sun Jan 11 03:04:12 2009
+++ src/include/time.h Thu May 14 02:37:36 2009
@@ -1,4 +1,4 @@
-/* $NetBSD: time.h,v 1.38 2009/01/11 03:04:12 christos Exp $ */
+/* $NetBSD: time.h,v 1.39 2009/05/14 02:37:36 ginsbach Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -131,6 +131,12 @@
struct tm * __restrict);
#endif
+#if (defined(_XOPEN_SOURCE) && defined(_XOPEN_SOURCE_EXTENDED)) || \
+ defined(_NETBSD_SOURCE)
+struct tm *getdate(const char *);
+extern int getdate_err;
+#endif
+
#if (_POSIX_C_SOURCE - 0) >= 199309L || (_XOPEN_SOURCE - 0) >= 500 || \
defined(_NETBSD_SOURCE)
#include <sys/time.h> /* XXX for struct timespec */
Index: src/lib/libc/time/Makefile.inc
diff -u src/lib/libc/time/Makefile.inc:1.11 src/lib/libc/time/Makefile.inc:1.12
--- src/lib/libc/time/Makefile.inc:1.11 Sat Jul 16 19:36:25 2005
+++ src/lib/libc/time/Makefile.inc Thu May 14 02:37:36 2009
@@ -1,10 +1,11 @@
-# $NetBSD: Makefile.inc,v 1.11 2005/07/16 19:36:25 christos Exp $
+# $NetBSD: Makefile.inc,v 1.12 2009/05/14 02:37:36 ginsbach Exp $
.PATH: ${.CURDIR}/time
SRCS+= _daylight.c \
- asctime.c difftime.c localtime.c strftime.c strptime.c
-MAN+= ctime.3 offtime.3 time2posix.3 tzfile.5 tzset.3 strftime.3 strptime.3
+ asctime.c difftime.c localtime.c getdate.c strftime.c strptime.c
+MAN+= ctime.3 getdate.3 offtime.3 strftime.3 strptime.3 \
+ time2posix.3 tzfile.5 tzset.3
CPPFLAGS+=-DALL_STATE -DUSG_COMPAT
MLINKS+=ctime.3 ctime_r.3 \
Index: src/share/examples/Makefile
diff -u src/share/examples/Makefile:1.17 src/share/examples/Makefile:1.18
--- src/share/examples/Makefile:1.17 Mon Jan 19 07:08:28 2009
+++ src/share/examples/Makefile Thu May 14 02:37:36 2009
@@ -1,6 +1,6 @@
-# $NetBSD: Makefile,v 1.17 2009/01/19 07:08:28 jmmv Exp $
+# $NetBSD: Makefile,v 1.18 2009/05/14 02:37:36 ginsbach Exp $
-SUBDIR= amd apm disktab emul fstab ftpd hostapd isdn pppd racoon \
+SUBDIR= amd apm disktab emul fstab ftpd getdate hostapd isdn pppd racoon \
supfiles syslogd wsmoused
.include <bsd.subdir.mk>
Added files:
Index: src/lib/libc/time/getdate.3
diff -u /dev/null src/lib/libc/time/getdate.3:1.1
--- /dev/null Thu May 14 02:37:37 2009
+++ src/lib/libc/time/getdate.3 Thu May 14 02:37:36 2009
@@ -0,0 +1,234 @@
+.\" $NetBSD: getdate.3,v 1.1 2009/05/14 02:37:36 ginsbach Exp $
+.\"
+.\" Copyright (c) 2009, The NetBSD Foundation.
+.\" All Rights Reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Brian Ginsbach.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+.\" POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd May 8, 2009
+.Dt GETDATE 3
+.Os
+.Sh NAME
+.Nm getdate ,
+.Nm getdate_err
+.Nd convert user format date and time
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In time.h
+.Ft "struct tm *"
+.Fo "getdate"
+.Fa "const char *str"
+.Fc
+.Vt extern int getdate_err ;
+.Sh DESCRIPTION
+The
+.Fn getdate
+function converts a date or time character string pointed to by
+.Fa str
+into a static
+.Va tm
+structure.
+.Pp
+The input string is parsed and interpreted using templates.
+A text file containing templates is specified by the
+environment variable
+.Ev DATEMSK .
+This should contain the full path to the template file.
+Lines in the template file represent acceptable date and/or time
+conversion specifications.
+These specifications are similar to those given for
+.Xr strptime 3 .
+The first line in the template file that matches the input string
+is used to interpret and convert to internal time format.
+.Ss Internal Format Conversion
+The following rules apply to converting the input into the internal format.
+.Bl -bullet -offset indent
+.It
+If only the weekday is given, the conversion assumes today when the
+weekday matches today or the first future matching weekday.
+.It
+If only the month and no year is given, the conversion assumes the
+current month when the month matches or the first future matching month.
+The first day of the month is assumed if no day is given.
+.It
+If only the year is given, the values of the
+.Fa tm_mon ,
+.Fa tm_mday ,
+.Fa tm_wday ,
+.Fa tm_yday ,
+and
+.Fa tm_isdst
+members of the returned
+.Va "struct tm"
+are unspecified.
+.It
+If the century is given, but the year within the century is not given,
+the conversion assumes the current year.
+.It
+If no hour, minute, and second are given, the conversion assumes
+the current hour, minute, and second.
+.It
+If no date is given, the conversion assumes today when the given hour
+is greater than the current hour and tomorrow when the given hour is less.
+.It
+If
+.Cm \&%Z
+is being scanned, then the broken-down time is based on the the
+current time of the matched timezone and not the current runtime
+environment timezone.
+.El
+.Sh RETURN VALUES
+If successful, the
+.Fn getdate
+function returns a pointer to a static
+.Va tm
+structure containing the broken-down time.
+Otherwise, a null pointer is returned and
+.Va getdate_err
+is set to indicate the error.
+.Pp
+The variable
+.Va getdate_err
+can have the following values:
+.Bl -tag -width NNN
+.It 1
+.Ev DATEMSK
+environment variable is null or undefined.
+.It 2
+Cannot open the template file for reading.
+.It 3
+Get file status failed for template file.
+.It 4
+Template file is not a regular file.
+.It 5
+Encountered an error while reading the template file.
+.It 6
+Cannot allocate memory.
+.It 7
+Input string does not match any line in the template file.
+.It 8
+Input string is invalid
+.Pq for example February 31
+or could not be represented in a
+.Va time_t .
+.El
+.Sh ENVIRONMENT
+.Bl -tag -width DATEMSK
+.It Ev DATEMSK
+The full path to the text file containing the templates
+for acceptable date and/or time conversions.
+.El
+.Sh FILES
+.Bl -tag -width DATEMSK
+.It Pa /usr/share/examples/getdate/datemsk.template
+An example template file that could be specified via the
+.Ev DATEMSK
+environment variable.
+.El
+.Sh EXAMPLES
+The following example shows the possible contents of a template file:
+.Pp
+.Bd -literal -offset indent -compact
+%m
+%A %B %d, %Y, %H:%M:%S
+%A
+%B
+%m/%d/%y %I %p
+%d,%m,%Y %H:%M
+at %A the %dst of %B in %Y
+run job at %I %p, %B %dnd
+%A den %d. %B %Y %H.%M Uhr
+.Ed
+.Pp
+The following are examples of valid input for the above template:
+.Pp
+.Bd -literal -offset indent -compact
+10/1/87 4 PM
+Friday
+Firday September 18, 1987, 10:30:30
+24,9,1986 10:30
+at monday the 1st of december in 1986
+run job at 3 PM, december 2nd
+.Ed
+.Pp
+The following examples show how local data and time specification can be
+defined in the template.
+.Pp
+.Bl -column -offset indent ".Sy Input String" ".Sy Line in Template"
+.It Sy "Input String" Ta Sy "Line in Template"
+.It Li 11/27/86 Ta Li \&%m/\&%d/\&%y
+.It Li 27.11.86 Ta Li \&%d.\&%m/\&%y
+.It Li 86-11-27 Ta Li \&%y-\&%m-\&%d
+.It Li "Friday 12:00:00" Ta "\&%A \&%H:\&%M:\&%S"
+.El
+.Pp
+The following examples illustrate the Internal Format Conversion rules
+given that the current date is
+.Li "Mon Sep 22 12:19:47 EDT 1986"
+and the
+.Ev LC_TIME
+environment variable is set to the default C locale.
+.Pp
+.Bl -column -offset indent ".Sy Input String" ".Sy Line in Template" ".Sy Date"
+.It Sy Input String Ta Sy Line in Template Ta Sy Date
+.It Li Mon Ta Li \&%a Ta Li "Mon Sep 22 12:19:47 EDT 1986"
+.It Li Sun Ta Li \&%a Ta Li "Sun Sep 28 12:19:47 EDT 1986"
+.It Li Fri Ta Li \&%a Ta Li "Sun Sep 26 12:19:47 EDT 1986"
+.It Li September Ta Li \&%B Ta Li "Mon Sep 1 12:19:47 EDT 1986"
+.It Li January Ta Li \&%B Ta Li "Thu Jan 1 12:19:47 EST 1987"
+.It Li December Ta Li \&%B Ta Li "Mon Dec 1 12:19:47 EST 1987"
+.It Li "Sep Mon" Ta Li "\&%b %a" Ta Li "Mon Sep 1 12:19:47 EDT 1986"
+.It Li "Jan Fri" Ta Li "\&%b %a" Ta Li "Fri Jan 2 12:19:47 EDT 1987"
+.It Li "Dec Mon" Ta Li "\&%b %a" Ta Li "Mon Dec 1 12:19:47 EDT 1986"
+.It Li "Jan Wed 1989" Ta Li "\&%b \&%a \&%Y" Ta Li "Wed Jan 4 12:19:47 EST 1989"
+.It Li "Fri 9" Ta Li "\&%a \&%H" Ta Li "Fri Sep 26 09:00:00 EDT 1986"
+.It Li "Feb 10:30" Ta Li "\&%b \&%H:\&%S" Ta Li "Sun Feb 1 10:00:30 EST 1987"
+.It Li 10:30 Ta Li "\&%H:\&%M" Ta Li "Tue Sep 23 10:30:00 EDT 1986"
+.It Li 13:30 Ta Li "\&%H:\&%M" Ta Li "Tue Sep 22 13:30:00 EDT 1986"
+.El
+.Sh SEE ALSO
+.Xr ctime 3 ,
+.Xr localtime 3 ,
+.Xr mktime 3 ,
+.Xr strftime 3 ,
+.Xr strptime 3 ,
+.Xr time 3
+.Sh STANDARDS
+The
+.Fn getdate
+function conforms to
+.St -p1003.1-2001 .
+.Sh HISTORY
+The
+.Nm
+function appeared in
+.At V.4 .
+.Sh BUGS
+The
+.Nm
+interface is inherently unsafe for multi-threaded programs or libraries,
+since it returns a pointer to a static variable and uses a global state
+variable.
Index: src/lib/libc/time/getdate.c
diff -u /dev/null src/lib/libc/time/getdate.c:1.1
--- /dev/null Thu May 14 02:37:37 2009
+++ src/lib/libc/time/getdate.c Thu May 14 02:37:36 2009
@@ -0,0 +1,270 @@
+/* $NetBSD: getdate.c,v 1.1 2009/05/14 02:37:36 ginsbach Exp $ */
+/*
+ * Copyright (c) 2009 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Brian Ginsbach.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <util.h>
+
+#define TMSENTINEL (-1)
+
+/*
+ * getdate_err is set to one of the following values on error.
+ *
+ * 1 The DATEMSK environment variable is null or undefined.
+ * 2 The template file cannot be opened for reading.
+ * 3 Failed to get file status information.
+ * 4 Template file is not a regular file.
+ * 5 Encountered an error while reading the template file.
+ * 6 Cannot allocate memory.
+ * 7 Input string does not match any line in the template.
+ * 8 Input string is invalid (for example, February 31) or could not
+ * be represented in a time_t.
+ */
+
+int getdate_err;
+
+struct tm *
+getdate(const char *str)
+{
+ char *datemsk, *line, *rp;
+ FILE *fp;
+ struct stat sb;
+ static struct tm rtm, tmnow;
+ struct tm *tmp, *rtmp = &rtm;
+ size_t lineno = 0;
+ time_t now;
+
+ if (((datemsk = getenv("DATEMSK")) == NULL) || *datemsk == '\0') {
+ getdate_err = 1;
+ return (NULL);
+ }
+
+ if (stat(datemsk, &sb) < 0) {
+ getdate_err = 3;
+ return (NULL);
+ }
+
+ if ((sb.st_mode & S_IFMT) != S_IFREG) {
+ getdate_err = 4;
+ return (NULL);
+ }
+
+ if ((fp = fopen(datemsk, "r")) == NULL) {
+ getdate_err = 2;
+ return (NULL);
+ }
+
+ /* loop through datemsk file */
+ errno = 0;
+ rp = NULL;
+ while ((line = fparseln(fp, NULL, &lineno, NULL, 0)) != NULL) {
+ /* initialize tmp with sentinels */
+ rtm.tm_sec = rtm.tm_min = rtm.tm_hour = TMSENTINEL;
+ rtm.tm_mday = rtm.tm_mon = rtm.tm_year = TMSENTINEL;
+ rtm.tm_wday = rtm.tm_yday = rtm.tm_isdst = TMSENTINEL;
+ rtm.tm_gmtoff = 0;
+ rtm.tm_zone = NULL;
+ rp = strptime(str, line, rtmp);
+ free(line);
+ if (rp != NULL)
+ break;
+ errno = 0;
+ }
+ if (errno != 0 || ferror(fp)) {
+ if (errno == ENOMEM)
+ getdate_err = 6;
+ else
+ getdate_err = 5;
+ fclose(fp);
+ return (NULL);
+ }
+ if (feof(fp) || (rp != NULL && *rp != '\0')) {
+ getdate_err = 7;
+ return (NULL);
+ }
+ fclose(fp);
+
+ time(&now);
+ tmp = localtime(&now);
+ tmnow = *tmp;
+
+ /*
+ * This implementation does not accept setting the broken-down time
+ * to anything other than the localtime(). It is not possible to
+ * change the scanned timezone with %Z.
+ *
+ * Note IRIX and Solaris accept only the current zone for %Z.
+ * XXX Is there any implementation that matches the standard?
+ * XXX (Or am I reading the standard wrong?)
+ *
+ * Note: Neither XPG 6 (POSIX 2004) nor XPG 7 (POSIX 2008)
+ * requires strptime(3) support for %Z.
+ */
+
+ /*
+ * Given only a weekday find the first matching weekday starting
+ * with the current weekday and moving into the future.
+ */
+ if (rtm.tm_wday != TMSENTINEL && rtm.tm_year == TMSENTINEL &&
+ rtm.tm_mon == TMSENTINEL && rtm.tm_mday == TMSENTINEL) {
+ rtm.tm_year = tmnow.tm_year;
+ rtm.tm_mon = tmnow.tm_mon;
+ rtm.tm_mday = tmnow.tm_mday +
+ (rtm.tm_wday - tmnow.tm_wday + 7) % 7;
+ }
+
+ /*
+ * Given only a month (and no year) find the first matching month
+ * starting with the current month and moving into the future.
+ */
+ if (rtm.tm_mon != TMSENTINEL) {
+ if (rtm.tm_year == TMSENTINEL) {
+ rtm.tm_year = tmnow.tm_year +
+ ((rtm.tm_mon < tmnow.tm_mon)? 1 : 0);
+ }
+ if (rtm.tm_mday == TMSENTINEL) {
+ /* assume the first of the month */
+ rtm.tm_mday = 1;
+ /*
+ * XXX This isn't documented! Just observed behavior.
+ *
+ * Given the weekday find the first matching weekday
+ * starting with the weekday of the first day of the
+ * the month and moving into the future.
+ */
+ if (rtm.tm_wday != TMSENTINEL) {
+ struct tm tm;
+
+ memset(&tm, 0, sizeof(struct tm));
+ tm.tm_year = rtm.tm_year;
+ tm.tm_mon = rtm.tm_mon;
+ tm.tm_mday = 1;
+ mktime(&tm);
+ rtm.tm_mday +=
+ (rtm.tm_wday - tm.tm_wday + 7) % 7;
+ }
+ }
+ }
+
+ /*
+ * Given no time of day assume the current time of day.
+ */
+ if (rtm.tm_hour == TMSENTINEL &&
+ rtm.tm_min == TMSENTINEL && rtm.tm_sec == TMSENTINEL) {
+ rtm.tm_hour = tmnow.tm_hour;
+ rtm.tm_min = tmnow.tm_min;
+ rtm.tm_sec = tmnow.tm_sec;
+ }
+ /*
+ * Given an hour and no date, find the first matching hour starting
+ * with the current hour and moving into the future
+ */
+ if (rtm.tm_hour != TMSENTINEL &&
+ rtm.tm_year == TMSENTINEL && rtm.tm_mon == TMSENTINEL &&
+ rtm.tm_mday == TMSENTINEL) {
+ rtm.tm_year = tmnow.tm_year;
+ rtm.tm_mon = tmnow.tm_mon;
+ rtm.tm_mday = tmnow.tm_mday;
+ if (rtm.tm_hour < tmnow.tm_hour)
+ rtm.tm_hour += 24;
+ }
+
+ /*
+ * Set to 'sane' values; mktime(3) does funny things otherwise.
+ * No hours, no minutes, no seconds, no service.
+ */
+ if (rtm.tm_hour == TMSENTINEL)
+ rtm.tm_hour = 0;
+ if (rtm.tm_min == TMSENTINEL)
+ rtm.tm_min = 0;
+ if (rtm.tm_sec == TMSENTINEL)
+ rtm.tm_sec = 0;
+
+ /*
+ * Given only a year the values of month, day of month, day of year,
+ * week day and is daylight (summer) time are unspecified.
+ * (Specified on the Solaris man page not POSIX.)
+ */
+ if (rtm.tm_year != TMSENTINEL &&
+ rtm.tm_mon == TMSENTINEL && rtm.tm_mday == TMSENTINEL) {
+ rtm.tm_mon = 0;
+ rtm.tm_mday = 1;
+ /*
+ * XXX More undocumented functionality but observed.
+ *
+ * Given the weekday find the first matching weekday
+ * starting with the weekday of the first day of the the
+ * month and moving into the future.
+ */
+ if (rtm.tm_wday != TMSENTINEL) {
+ struct tm tm;
+
+ memset(&tm, 0, sizeof(struct tm));
+ tm.tm_year = rtm.tm_year;
+ tm.tm_mon = rtm.tm_mon;
+ tm.tm_mday = 1;
+ mktime(&tm);
+ rtm.tm_mday += (rtm.tm_wday - tm.tm_wday + 7) % 7;
+ }
+ }
+
+ /*
+ * Given only the century but no year within, the current year
+ * is assumed. (Specified on the Solaris man page not POSIX.)
+ *
+ * Warning ugly end case
+ *
+ * This is more work since strptime(3) doesn't "do the right thing".
+ */
+ if (rtm.tm_year != TMSENTINEL && (rtm.tm_year - 1900) >= 0) {
+ rtm.tm_year -= 1900;
+ rtm.tm_year += (tmnow.tm_year % 100);
+ }
+
+ /*
+ * mktime() will normalize all values and also check that the
+ * value will fit into a time_t.
+ *
+ * This is only for POSIX correctness. A date >= 1900 is
+ * really ok, but using a time_t limits things.
+ */
+ if (mktime(rtmp) < 0) {
+ getdate_err = 8;
+ return (NULL);
+ }
+
+ return (rtmp);
+}
Index: src/share/examples/getdate/Makefile
diff -u /dev/null src/share/examples/getdate/Makefile:1.1
--- /dev/null Thu May 14 02:37:37 2009
+++ src/share/examples/getdate/Makefile Thu May 14 02:37:36 2009
@@ -0,0 +1,12 @@
+# $NetBSD: Makefile,v 1.1 2009/05/14 02:37:36 ginsbach Exp $
+
+NOOBJ= # defined
+
+.include <bsd.own.mk>
+
+.if ${MKSHARE} != "no"
+FILES= datemsk.template posixmsk.example3 posixmsk.example4
+FILESDIR=/usr/share/examples/getdate
+.endif
+
+.include <bsd.prog.mk>
Index: src/share/examples/getdate/datemsk.template
diff -u /dev/null src/share/examples/getdate/datemsk.template:1.1
--- /dev/null Thu May 14 02:37:37 2009
+++ src/share/examples/getdate/datemsk.template Thu May 14 02:37:36 2009
@@ -0,0 +1,38 @@
+# $NetBSD: datemsk.template,v 1.1 2009/05/14 02:37:36 ginsbach Exp $
+# getdate(3) DATEMSK template file
+%m/%d/%y %I:%M:%S %p
+%m/%d/%Y %I:%M:%S %p
+%m/%d/%y %H:%M:%S
+%m/%d/%Y %H:%M:%S
+%m/%d/%y %I:%M %p
+%m/%d/%Y %I:%M %p
+%m/%d/%y %H:%M
+%m/%d/%Y %H:%M
+%m/%d/%y %I %p
+%m/%d/%Y %I %p
+%m/%d/%y %H
+%m/%d/%Y %H
+%m/%d/%y
+%m/%d/%Y
+%m/%d
+%b %d, %Y %I:%M:%S %p
+%b %d, %Y %H:%M:%S
+%B %d, %Y %I:%M:%S %p
+%B %d, %Y %H:%M:%S
+%b %d, %Y %I:%M %p
+%b %d, %Y %H:%M
+%B %d, %Y %I:%M %p
+%B %d, %Y %H:%M
+%b %d, %Y %I %p
+%b %d, %Y %H
+%B %d, %Y %I %p
+%B %d, %Y %H
+%b %d, %Y
+%B %d, %Y
+%b %d
+%B %d
+%m%d%H%M%y
+%m%d%H%M%Y
+%m%d%H%M
+%m%d%H
+%m%d
Index: src/share/examples/getdate/posixmsk.example3
diff -u /dev/null src/share/examples/getdate/posixmsk.example3:1.1
--- /dev/null Thu May 14 02:37:37 2009
+++ src/share/examples/getdate/posixmsk.example3 Thu May 14 02:37:36 2009
@@ -0,0 +1,9 @@
+# $NetBSD: posixmsk.example3,v 1.1 2009/05/14 02:37:36 ginsbach Exp $
+#
+# The Open Group Base Specifications Issue 7 / IEEE Std 1003.1-2008
+# Example 3
+#
+%m/%d/%y
+%d.%m.%y
+%y-%m-%d
+%A %H:%M:%S
Index: src/share/examples/getdate/posixmsk.example4
diff -u /dev/null src/share/examples/getdate/posixmsk.example4:1.1
--- /dev/null Thu May 14 02:37:37 2009
+++ src/share/examples/getdate/posixmsk.example4 Thu May 14 02:37:36 2009
@@ -0,0 +1,12 @@
+# $NetBSD: posixmsk.example4,v 1.1 2009/05/14 02:37:36 ginsbach Exp $
+#
+# The Open Group Base Specifications Issue 7 / IEEE Std 1003.1-2008
+# Example 4
+#
+%a
+%B
+%b %a
+%b %a %Y
+%a %H
+%b %H:%S
+%H:%M