From ccbd1d7dc5189f4637468a8136f672e60ee0e531 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Sun, 1 Nov 1992 05:44:29 +0000 Subject: Initial revision --- lib/posixtm.y | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 lib/posixtm.y (limited to 'lib/posixtm.y') diff --git a/lib/posixtm.y b/lib/posixtm.y new file mode 100644 index 000000000..bb5b40e75 --- /dev/null +++ b/lib/posixtm.y @@ -0,0 +1,173 @@ +/* Parse dates for touch. + Copyright (C) 1989, 1990, 1991 Free Software Foundation Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Written by Jim Kingdon and David MacKenzie. */ +%{ +#ifdef __GNUC__ +#define alloca __builtin_alloca +#else +#ifdef sparc +#include +#else +#ifdef _AIX + #pragma alloca +#else +char *alloca (); +#endif +#endif +#endif + +#include +#include +#include + +#define YYDEBUG 1 + +/* Lexical analyzer's current scan position in the input string. */ +static char *curpos; + +/* The return value. */ +static struct tm t; + +time_t mktime (); + +#define yyparse posixtime_yyparse +static int yylex (); +static int yyerror (); +%} + +%token DIGIT + +%% +date : + digitpair /* month */ + digitpair /* day */ + digitpair /* hours */ + digitpair /* minutes */ + year + seconds { + if ($1 >= 1 && $1 <= 12) + t.tm_mon = $1 - 1; + else { + YYABORT; + } + if ($2 >= 1 && $2 <= 31) + t.tm_mday = $2; + else { + YYABORT; + } + if ($3 >= 0 && $3 <= 23) + t.tm_hour = $3; + else { + YYABORT; + } + if ($4 >= 0 && $4 <= 59) + t.tm_min = $4; + else { + YYABORT; + } + } + +year : digitpair { + t.tm_year = $1; + /* Deduce the century based on the year. + See POSIX.2 section 4.63.3. */ + if ($1 <= 68) + t.tm_year += 100; + } + | digitpair digitpair { + t.tm_year = $1 * 100 + $2; + if (t.tm_year < 1900) { + YYABORT; + } else + t.tm_year -= 1900; + } + | /* empty */ { + time_t now; + struct tm *tmp; + + /* Use current year. */ + time (&now); + tmp = localtime (&now); + t.tm_year = tmp->tm_year; + } + ; + +seconds : /* empty */ { + t.tm_sec = 0; + } + | '.' digitpair { + if ($2 >= 0 && $2 <= 61) + t.tm_sec = $2; + else { + YYABORT; + } + } + ; + +digitpair : DIGIT DIGIT { + $$ = $1 * 10 + $2; + } + ; +%% +static int +yylex () +{ + char ch = *curpos++; + + if (ch >= '0' && ch <= '9') + { + yylval = ch - '0'; + return DIGIT; + } + else if (ch == '.' || ch == 0) + return ch; + else + return '?'; /* Cause an error. */ +} + +static int +yyerror () +{ + return 0; +} + +/* Parse a POSIX-style date and return it, or (time_t)-1 for an error. */ + +time_t +posixtime (s) + char *s; +{ + curpos = s; + /* Let mktime decide whether it is daylight savings time. */ + t.tm_isdst = -1; + if (yyparse ()) + return (time_t)-1; + else + return mktime (&t); +} + +/* Parse a POSIX-style date and return it, or NULL for an error. */ + +struct tm * +posixtm (s) + char *s; +{ + if (posixtime (s) == -1) + return NULL; + return &t; +} -- cgit v1.2.3-70-g09d2