(O_DIRECTORY): Define, if needed.
[gnulib.git] / lib / posixtm.c
index 6993050..2c392e4 100644 (file)
@@ -1,5 +1,5 @@
-/* Parse dates for touch.
-   Copyright (C) 1989, 1990, 1991, 1998 Free Software Foundation Inc.
+/* Parse dates for touch and date.
+   Copyright (C) 1989, 1990, 1991, 1998, 2000 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
 #endif
 
 #include <stdio.h>
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
 #include <sys/types.h>
+#if HAVE_STRING_H
+# include <string.h>
+#else
+# include <strings.h>
+#endif
 
 #ifdef TM_IN_SYS_TIME
 # include <sys/time.h>
 # include <time.h>
 #endif
 
+#include "posixtm.h"
+
+/* ISDIGIT differs from isdigit, as follows:
+   - Its arg may be any int or unsigned int; it need not be an unsigned char.
+   - It's guaranteed to evaluate its argument exactly once.
+   - It's typically faster.
+   Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that
+   only '0' through '9' are digits.  Prefer ISDIGIT to isdigit unless
+   it's important to use the locale's definition of `digit' even when the
+   host does not conform to Posix.  */
+#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9)
+
 /* The return value. */
 static struct tm t;
 
@@ -43,7 +63,7 @@ time_t mktime ();
     8, 10, or 12 digits, followed by optional .ss
     (PDS_LEADING_YEAR | PDS_CENTURY | PDS_SECONDS)
 
-  touch mmddhhmm[YY] FILE...
+  touch mmddhhmm[YY] FILE... (obsolescent)
     8 or 10 digits
     (PDS_TRAILING_YEAR)
 
@@ -53,13 +73,6 @@ time_t mktime ();
 
 */
 
-/* FIXME: put these in posixtm.h */
-/* POSIX Date Syntax flags.  */
-#define PDS_LEADING_YEAR 1
-#define PDS_TRAILING_YEAR 2
-#define PDS_CENTURY 4
-#define PDS_SECONDS 8
-
 static int
 year (const int *digit_pair, size_t n, int allow_century)
 {
@@ -104,10 +117,10 @@ year (const int *digit_pair, size_t n, int allow_century)
 static int
 posix_time_parse (const char *s, unsigned int syntax_bits)
 {
-  const char *dot;
+  const char *dot = NULL;
   int pair[6];
   int *p;
-  int i;
+  unsigned int i;
 
   size_t s_len = strlen (s);
   size_t len = (((syntax_bits & PDS_SECONDS) && (dot = strchr (s, '.')))
@@ -147,21 +160,22 @@ posix_time_parse (const char *s, unsigned int syntax_bits)
   if (*p < 1 || *p > 12)
     return 1;
   t.tm_mon = *p - 1;
-
   ++p; --len;
+
   if (*p < 1 || *p > 31)
     return 1;
   t.tm_mday = *p;
-
   ++p; --len;
+
   if (*p < 0 || *p > 23)
     return 1;
   t.tm_hour = *p;
-
   ++p; --len;
+
   if (*p < 0 || *p > 59)
     return 1;
   t.tm_min = *p;
+  ++p; --len;
 
   /* Handle any trailing year.  */
   if (syntax_bits & PDS_TRAILING_YEAR)
@@ -194,11 +208,11 @@ posix_time_parse (const char *s, unsigned int syntax_bits)
 
 /* Parse a POSIX-style date and return it, or (time_t)-1 for an error.  */
 
-struct tm *
-posixtime (const char *s)
+time_t
+posixtime (const char *s, unsigned int syntax_bits)
 {
   t.tm_isdst = -1;
-  if (posix_time_parse (s))
+  if (posix_time_parse (s, syntax_bits))
     return (time_t)-1;
   else
     return mktime (&t);
@@ -207,9 +221,56 @@ posixtime (const char *s)
 /* Parse a POSIX-style date and return it, or NULL for an error.  */
 
 struct tm *
-posixtm (const char *s)
+posixtm (const char *s, unsigned int syntax_bits)
 {
-  if (posixtime (s) == -1)
+  if (posixtime (s, syntax_bits) == -1)
     return NULL;
   return &t;
 }
+
+#ifdef TEST_POSIXTIME
+/*
+    Test mainly with syntax_bits == 13
+    (aka: (PDS_LEADING_YEAR | PDS_CENTURY | PDS_SECONDS))
+
+BEGIN-DATA
+1112131415      13 1323807300 Tue Dec 13 14:15:00 2011
+1112131415.16   13 1323807316 Tue Dec 13 14:15:16 2011
+201112131415.16 13 1323807316 Tue Dec 13 14:15:16 2011
+191112131415.16 13 -1 ***
+203712131415.16 13 2144348116 Sun Dec 13 14:15:16 2037
+3712131415.16   13 2144348116 Sun Dec 13 14:15:16 2037
+6812131415.16   13 -1 ***
+6912131415.16   13 -1 ***
+7012131415.16   13 29967316 Sun Dec 13 14:15:16 1970
+12131415.16     13 913580116 Sun Dec 13 14:15:16 1998
+
+1213141599       2 945116100 Mon Dec 13 14:15:00 1999
+1213141500       2 976738500 Wed Dec 13 14:15:00 2000
+END-DATA
+
+*/
+
+# define MAX_BUFF_LEN 1024
+
+int
+main ()
+{
+  char buff[MAX_BUFF_LEN + 1];
+
+  buff[MAX_BUFF_LEN] = 0;
+  while (fgets (buff, MAX_BUFF_LEN, stdin) && buff[0])
+    {
+      char time_str[MAX_BUFF_LEN];
+      unsigned int syntax_bits;
+      time_t t;
+      char *result;
+      sscanf (buff, "%s %u", time_str, &syntax_bits);
+      t = posixtime (time_str, syntax_bits);
+      result = (t == (time_t) -1 ? "***" : ctime (&t));
+      printf ("%d %s\n", (int) t, result);
+    }
+  exit (0);
+
+}
+#endif