1 /* Parse dates for touch.
2 Copyright (C) 1989, 1990, 1991, 1998 Free Software Foundation Inc.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software Foundation,
16 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18 /* Yacc-based version written by Jim Kingdon and David MacKenzie.
19 Rewritten by Jim Meyering. */
26 #include <sys/types.h>
29 # include <sys/time.h>
34 /* The return value. */
42 touch -t [[CC]YY]mmddhhmm[.ss] FILE...
43 8, 10, or 12 digits, followed by optional .ss
44 (PDS_LEADING_YEAR | PDS_CENTURY | PDS_SECONDS)
46 touch mmddhhmm[YY] FILE...
52 (PDS_TRAILING_YEAR | PDS_CENTURY)
56 /* FIXME: put these in posixtm.h */
57 /* POSIX Date Syntax flags. */
58 #define PDS_LEADING_YEAR 1
59 #define PDS_TRAILING_YEAR 2
64 year (const int *digit_pair, size_t n, int allow_century)
69 t.tm_year = *digit_pair;
70 /* Deduce the century based on the year.
71 See POSIX.2 section 4.63.3. */
72 if (digit_pair[0] <= 68)
79 t.tm_year = digit_pair[0] * 100 + digit_pair[1];
90 /* Use current year. */
92 tmp = localtime (&now);
93 t.tm_year = tmp->tm_year;
105 posix_time_parse (const char *s, unsigned int syntax_bits)
112 size_t s_len = strlen (s);
113 size_t len = (((syntax_bits & PDS_SECONDS) && (dot = strchr (s, '.')))
117 if (len != 8 && len != 10 && len != 12)
122 if (!(syntax_bits & PDS_SECONDS))
125 if (s_len - len != 3)
129 for (i = 0; i < len; i++)
134 for (i = 0; i < len; i++)
135 pair[i] = 10 * (s[2*i] - '0') + s[2*i + 1] - '0';
138 if (syntax_bits & PDS_LEADING_YEAR)
140 if (year (p, len - 4, syntax_bits & PDS_CENTURY))
146 /* Handle 8 digits worth of `MMDDhhmm'. */
147 if (*p < 1 || *p > 12)
152 if (*p < 1 || *p > 31)
157 if (*p < 0 || *p > 23)
162 if (*p < 0 || *p > 59)
166 /* Handle any trailing year. */
167 if (syntax_bits & PDS_TRAILING_YEAR)
169 if (year (p, len, syntax_bits & PDS_CENTURY))
173 /* Handle seconds. */
183 if (!ISDIGIT (dot[0]) || !ISDIGIT (dot[1]))
185 seconds = 10 * (dot[0] - '0') + dot[1] - '0';
187 if (seconds < 0 || seconds > 61)
195 /* Parse a POSIX-style date and return it, or (time_t)-1 for an error. */
198 posixtime (const char *s)
201 if (posix_time_parse (s))
207 /* Parse a POSIX-style date and return it, or NULL for an error. */
210 posixtm (const char *s)
212 if (posixtime (s) == -1)