changeset 91:93cc929329eb noffle

[svn] Date output change and now date parsing
author bears
date Fri, 19 May 2000 16:12:45 +0100
parents 9cf0d605465a
children 160a0af71cf8
files src/util.c src/util.h
diffstat 2 files changed, 188 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/util.c	Fri May 19 08:59:51 2000 +0100
+++ b/src/util.c	Fri May 19 16:12:45 2000 +0100
@@ -1,7 +1,7 @@
 /*
   util.c
 
-  $Id: util.c 99 2000-05-18 12:11:05Z bears $
+  $Id: util.c 110 2000-05-19 15:12:45Z bears $
 */
 
 #if HAVE_CONFIG_H
@@ -25,12 +25,18 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include "configfile.h"
 #include "log.h"
 #include "wildmat.h"
 #include "portable.h"
 
+#if defined(UTIL_TEST)
+#define	Log_err	printf
+#define	Log_dbg	printf
+#endif
+
 static const char *
 nextWhiteSpace( const char *p )
 {
@@ -254,10 +260,145 @@
     return TRUE;
 }
 
+static const char *DOTW[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri",
+			      "Sat", NULL };
+static const char *MON[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
+			     "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
+
 void
-Utl_rfc822Date( time_t t, Str res )
+Utl_newsDate( time_t t, Str res )
+{    
+    struct tm local, localAsGmt;
+    time_t tlocalAsGmt;
+    int tzdiff, hoffset, moffset;
+
+    local = *localtime( &t );
+    memset( &localAsGmt, 0, sizeof( localAsGmt ) );
+    localAsGmt.tm_sec = local.tm_sec;
+    localAsGmt.tm_min = local.tm_min;
+    localAsGmt.tm_hour = local.tm_hour;
+    localAsGmt.tm_mday = local.tm_mday;
+    localAsGmt.tm_mon = local.tm_mon;
+    localAsGmt.tm_year = local.tm_year;
+    tlocalAsGmt = mktime( &localAsGmt );
+    tzdiff = (int) ( ( (long) difftime( tlocalAsGmt, t ) ) / 60 );
+    hoffset = tzdiff / 60;
+    moffset = tzdiff % 60;
+    if ( moffset < 0 ) moffset = -moffset;
+
+    sprintf( res, "%s, %d %s %4d %02d:%02d:%02d %+03d%02d",
+	     DOTW[local.tm_wday], local.tm_mday,
+	     MON[local.tm_mon], local.tm_year + 1900,
+	     local.tm_hour, local.tm_min, local.tm_sec,
+	     hoffset, moffset );
+}
+
+time_t
+Utl_parseNewsDate( const char *s )
 {
-    strftime( res, MAXCHAR,"%a, %d %b %Y %H:%M:%S %z", localtime( &t ) );
+    struct tm tm;
+    int wday, tzoffset, hoffset, moffset;
+    char *p;
+    time_t res;
+
+    memset( &tm, 0, sizeof( tm ) );
+    wday = -1;
+    
+    s = nextNonWhiteSpace( s );
+
+    /* Is this the day number, or a weekday? */
+    if ( ! isdigit( *s ) )
+    {
+	if ( strlen( s ) < 4 )
+	    return (time_t) -1;
+	
+	for ( wday = 0; DOTW[ wday ] != NULL; wday++ )
+	    if ( strncmp( DOTW[ wday ], s, 3 ) == 0 )
+		break;
+
+	if( DOTW[ wday ] == NULL || s[3] != ',' )
+	    return (time_t) -1;
+
+	s += 4;
+    }
+    
+    /* Get the day number */
+    tm.tm_mday = (int) strtol( s, &p, 10 );
+    if ( p == s )
+	return (time_t) -1;
+    s = p;
+
+    /* Look for month name */
+    s = nextNonWhiteSpace( s );
+    if ( strlen( s ) < 4 )
+	return (time_t) -1;
+    for ( tm.tm_mon = 0; MON[ tm.tm_mon ] != NULL; tm.tm_mon++ )
+	if ( strncmp( MON[ tm.tm_mon ], s, 3 ) == 0 )
+	    break;
+
+    if ( MON[ tm.tm_mon ] == NULL )
+	return (time_t) -1;
+    s += 3;
+
+    /* Year next */
+    tm.tm_year = (int) strtol( s, &p, 10 );
+    if ( p == s || ( tm.tm_year >= 100 && tm.tm_year < 1900  ) )
+	return (time_t) -1;
+    if ( tm.tm_year >= 1900 )
+	tm.tm_year -= 1900;
+    s = p;  
+
+    /* Hours */
+    tm.tm_hour = (int) strtol( s, &p, 10 );
+    if ( p == s || *p != ':' )
+	return (time_t) -1;
+    s = ++p;
+
+    /* Minutes */
+    tm.tm_min = (int) strtol( s, &p, 10 );
+    if ( p == s || ( *p != ':' && *p != ' ' ) )
+	return (time_t) -1;
+    s = p;
+
+    /* Seconds */
+    if ( *s == ':' )
+    {
+	s++;
+	tm.tm_sec = (int) strtol( s, &p, 10 );
+	if ( p == s )
+	    return (time_t) -1;
+	s = p;
+    }
+
+    /* GMT/UT or timezone offset */
+    tzoffset = 0;
+    while ( isspace( *s ) )
+	s++;
+    if ( strncmp( s, "GMT", 3) == 0 )
+	s += 3;
+    else if ( strncmp( s, "UT", 2 ) == 0 )
+	s += 2;
+    else
+    {
+	tzoffset = (int) strtol( s, &p, 10 );
+	s = p;
+    }
+
+    /* Check for following junk */
+    if ( *s != '\0' && ! isspace( *s ) )
+	return (time_t) -1;
+
+    res = mktime( &tm );
+    if ( res == (time_t) -1 )
+	return res;
+    
+    if ( wday >= 0 && wday != tm.tm_wday )
+	return (time_t) -1;
+
+    moffset = tzoffset % 100;
+    hoffset = tzoffset / 100;
+    res = res - ( ( hoffset * 60 + moffset ) * 60 );
+    return res;
 }
 
 void
@@ -271,3 +412,40 @@
     }
     memcpy( *dst, src, (size_t)len + 1 );
 }
+
+#if defined(UTIL_TEST)
+
+/* Test code borrowed from wildmat.c. Yep, still uses gets(). */
+extern char	*gets();
+
+int
+main()
+{
+    Str line;
+    time_t t;
+
+    printf( "Util date tester.  Enter date to test.\n" );    
+    printf( "A blank line exits the program.\n" );
+
+    for ( ; ; )
+    {
+	printf( "\nEnter date:  " );
+	(void) fflush( stdout );
+	if ( gets( line ) == NULL || line[0] == '\0' )
+	    break;
+
+	t = Utl_parseNewsDate( line );
+	if ( t == (time_t) -1 )
+	    printf( "Date parse failed\n" );
+	else
+	{
+	    Utl_newsDate( t, line );
+	    printf( "Utl_newsDate -> '%s'\nctime() -> '%s'\n",
+		    line, ctime( &t ) );
+	}
+    }
+
+    exit(0);
+    /* NOTREACHED */
+}
+#endif
--- a/src/util.h	Fri May 19 08:59:51 2000 +0100
+++ b/src/util.h	Fri May 19 16:12:45 2000 +0100
@@ -3,7 +3,7 @@
 
   Miscellaneous helper functions.
 
-  $Id: util.h 99 2000-05-18 12:11:05Z bears $
+  $Id: util.h 110 2000-05-19 15:12:45Z bears $
 */
 
 #ifndef UTL_H
@@ -76,9 +76,13 @@
 Bool
 Utl_getStamp( time_t *result, Str file );
 
-/* Put RFC822-compliant date string into res. */
+/* Put SonOfRFC1036 compliant date string into res. */
 void
-Utl_rfc822Date( time_t t, Str res );
+Utl_newsDate( time_t t, Str res );
+
+/* Attempt to parse a SonOfRFC1036 compliant date string. Return -1 on fail. */
+time_t
+Utl_parseNewsDate( const char *s );
 
 void
 Utl_cpyStr( Str dst, const char *src );