diff options
| author | christos <christos@NetBSD.org> | 2015-12-07 20:55:49 +0000 |
|---|---|---|
| committer | christos <christos@NetBSD.org> | 2015-12-07 20:55:49 +0000 |
| commit | 301fa4e030df83d53eafbe03da85089e31d8f8ba (patch) | |
| tree | c6714caae5f079cbcc47f31e4d6a7b272258f423 /lib/libutil | |
| parent | 8d2127644e576ebc2b9171cafded070615b8e200 (diff) | |
- 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 (limited to 'lib/libutil')
| -rw-r--r-- | lib/libutil/parsedate.3 | 16 | ||||
| -rw-r--r-- | lib/libutil/parsedate.y | 51 |
2 files changed, 58 insertions, 9 deletions
diff --git a/lib/libutil/parsedate.3 b/lib/libutil/parsedate.3 index 09f406ccaee..a0ed6128f5b 100644 --- a/lib/libutil/parsedate.3 +++ b/lib/libutil/parsedate.3 @@ -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 @@ The following words are recognized in English only: .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 @@ An ISO-8601 date. 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 @@ As well as times: .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 --git a/lib/libutil/parsedate.y b/lib/libutil/parsedate.y index 892227bee0c..2f6a9d4e6eb 100644 --- a/lib/libutil/parsedate.y +++ b/lib/libutil/parsedate.y @@ -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 @@ struct dateinfo { } %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 @@ time : tUNUMBER tMERIDIAN { 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 @@ date : tUNUMBER '/' tUNUMBER { } | 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 @@ static const TABLE MilitaryTable[] = { { 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 @@ Convert( ) { struct tm tm = {.tm_sec = 0}; + struct tm otm; time_t result; tm.tm_sec = Seconds; @@ -673,6 +699,15 @@ Convert( 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 @@ LookupWord(YYSTYPE *yylval, char *buff) 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; |
