Source-Changes-HG archive

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

[src/trunk]: src/lib/libutil - Add support for "midnight" "noon", dawn etc.



details:   https://anonhg.NetBSD.org/src/rev/939d6f8d3395
branches:  trunk
changeset: 342127:939d6f8d3395
user:      christos <christos%NetBSD.org@localhost>
date:      Mon Dec 07 20:55:49 2015 +0000

description:
- Add support for "midnight" "noon", dawn etc.
- Add validation to date/time strings by checking that mktime did not change
  the fields of struct tm from the ones requested
- Allow the format "year monthname day".
>From kre

diffstat:

 lib/libutil/parsedate.3 |  16 +++++++++++---
 lib/libutil/parsedate.y |  51 ++++++++++++++++++++++++++++++++++++++++++++----
 2 files changed, 58 insertions(+), 9 deletions(-)

diffs (163 lines):

diff -r b90992971a42 -r 939d6f8d3395 lib/libutil/parsedate.3
--- a/lib/libutil/parsedate.3   Mon Dec 07 20:52:46 2015 +0000
+++ b/lib/libutil/parsedate.3   Mon Dec 07 20:55:49 2015 +0000
@@ -1,4 +1,4 @@
-.\"     $NetBSD: parsedate.3,v 1.17 2015/11/26 09:48:21 wiz Exp $
+.\"     $NetBSD: parsedate.3,v 1.18 2015/12/07 20:55:49 christos Exp $
 .\"
 .\" Copyright (c) 2006 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -27,7 +27,7 @@
 .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 .\" POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd November 25, 2015
+.Dd December 7, 2015
 .Dt PARSEDATE 3
 .Os
 .Sh NAME
@@ -106,7 +106,14 @@
 .Dv AM ,
 .Dv PM ,
 .Dv a.m. ,
-.Dv p.m.
+.Dv p.m. ,
+.Dv midnight ,
+.Dv mn ,
+.Dv noon ,
+.Dv dawn ,
+.Dv sunup ,
+.Dv sunset ,
+.Dv sundown .
 .Pp
 The months:
 .Dv january ,
@@ -229,7 +236,7 @@
 The year in an ISO-8601 date is always taken literally,
 so this is the year 69, not 2069.
 .It 10/1/2000
-October 10, 2000; the common US format.
+October 1, 2000; the common, but bizarre, US format.
 .It 20 Jun 1994
 .It 23jun2001
 .It 1-sep-06
@@ -253,6 +260,7 @@
 .It 12:11:01.000012
 .It 12:21-0500
 .El
+Fractions of seconds (after a decimal point) are parsed, but ignored.
 .Pp
 Relative items are also supported:
 .Bl -tag -compact -width "this thursday"
diff -r b90992971a42 -r 939d6f8d3395 lib/libutil/parsedate.y
--- a/lib/libutil/parsedate.y   Mon Dec 07 20:52:46 2015 +0000
+++ b/lib/libutil/parsedate.y   Mon Dec 07 20:55:49 2015 +0000
@@ -14,7 +14,7 @@
 
 #include <sys/cdefs.h>
 #ifdef __RCSID
-__RCSID("$NetBSD: parsedate.y,v 1.22 2015/12/06 14:43:59 christos Exp $");
+__RCSID("$NetBSD: parsedate.y,v 1.23 2015/12/07 20:55:49 christos Exp $");
 #endif
 
 #include <stdio.h>
@@ -99,10 +99,10 @@
 }
 
 %token tAGO tDAY tDAYZONE tID tMERIDIAN tMINUTE_UNIT tMONTH tMONTH_UNIT
-%token tSEC_UNIT tSNUMBER tUNUMBER tZONE tDST AT_SIGN
+%token tSEC_UNIT tSNUMBER tUNUMBER tZONE tDST AT_SIGN tTIME
 
 %type  <Number>        tDAY tDAYZONE tMINUTE_UNIT tMONTH tMONTH_UNIT
-%type  <Number>        tSEC_UNIT tSNUMBER tUNUMBER tZONE
+%type  <Number>        tSEC_UNIT tSNUMBER tUNUMBER tZONE tTIME
 %type  <Meridian>      tMERIDIAN o_merid
 
 %parse-param   { struct dateinfo *param }
@@ -215,6 +215,15 @@
            param->yyMeridian = MER24;
 /* XXX: Do nothing with millis */
        }
+       | tTIME {
+           param->yyHour = $1;
+           param->yyMinutes = 0;
+           param->yySeconds = 0;
+           param->yyMeridian = MER24;
+           /* Tues midnight --> Weds 00:00, midnight Tues -> Tues 00:00 */
+           if ($1 == 0 && param->yyHaveDay)
+               param->yyDayNumber++;
+       }
        ;
 
 time_numericzone : tUNUMBER ':' tUNUMBER tSNUMBER {
@@ -306,8 +315,13 @@
        }
        | tUNUMBER tMONTH tUNUMBER {
            param->yyMonth = $2;
-           param->yyDay = $1;
-           param->yyYear = $3;
+           if ($1 < 35) {
+               param->yyDay = $1;
+               param->yyYear = $3;
+           } else {
+               param->yyDay = $3;
+               param->yyYear = $1;
+           }
        }
        ;
 
@@ -589,6 +603,17 @@
     { NULL,    0,      0 }
 };
 
+static const TABLE TimeNames[] = {
+    { "midnight",      tTIME,           0 },
+    { "mn",            tTIME,           0 },
+    { "noon",          tTIME,          12 },
+    { "dawn",          tTIME,           6 },
+    { "sunup",         tTIME,           6 },
+    { "sunset",                tTIME,          18 },
+    { "sundown",       tTIME,          18 },
+    { NULL,            0,               0 }
+};
+
 
 
 
@@ -635,6 +660,7 @@
 )
 {
     struct tm tm = {.tm_sec = 0};
+    struct tm otm;
     time_t result;
 
     tm.tm_sec = Seconds;
@@ -673,6 +699,15 @@
     fprintf(stderr, " %s", ctime(&result));
 #endif
 
+#define        TM_NE(fld) (otm.tm_ ## fld != tm.tm_ ## fld)
+    if (TM_NE(year) || TM_NE(mon) || TM_NE(mday) ||
+       TM_NE(hour) || TM_NE(min) || TM_NE(sec)) {
+           /* mktime() "corrected" our tm, so it must have been invalid */
+           result = -1;
+           errno = EAGAIN;
+    }
+#undef TM_NE
+
     return result;
 }
 
@@ -800,6 +835,12 @@
     if (strcmp(buff, "dst") == 0) 
        return tDST;
 
+    for (tp = TimeNames; tp->name; tp++)
+       if (strcmp(buff, tp->name) == 0) {
+           yylval->Number = tp->value;
+           return tp->type;
+       }
+
     for (tp = UnitsTable; tp->name; tp++)
        if (strcmp(buff, tp->name) == 0) {
            yylval->Number = tp->value;



Home | Main Index | Thread Index | Old Index