PHOON, part one of two.
Jef Poskanzer
jef at unisoft.UUCP
Fri Nov 21 03:09:44 AEST 1986
First distribution of phoon, deltime, and libtws - 15nov86.
This package contains two programs and a library:
phoon - program to display the PHase of the mOON. Unlike other
such programs, which just tell you how long since first quarter
or something like that, phoon *shows* you the phase with a little
picture. I've put an example at the end of this file.
deltime - program to subtract date/times. Tells you the difference
between two date/times, or between now and a specified date/time.
I once used this to help a friend quit smoking - every time she
logged in, the computer told her how many days since her last
cigarette. I also use it in my .login, to tell me how old I am.
libtws - date/time library. Unlike the standard Unix(R)
date/time routines, libtws lets you parse a date/time string
into internal form. Most of this library came from version
6.5 of the MH message handling system, courtesy of Marshall Rose.
Files in this distribution:
README this
Makefile guess
deltime.c source for time subtraction tool
deltime.man manual for time subtraction tool
dtime.c source for most of the time routines
dtimep.lex source for time-parsing routine
lexedit.sed script to modify output of lex
lexstring.c front end for time-parsing routine
libtws.man manual for time library
parsetime.c source for test program
phoon.c source for phase of moon program
phoon.man manual for phase of moon program
tws.h include file for time library
Unpack the files, edit Makefile and change the options to suit,
make, and enjoy! I've tested this stuff under 4.2 BSD, 4.3 BSD,
and System V rel 2. Nevertheless, I'm sure bugs remain. Feedback
is welcome - send bug reports, enhancements, checks, money orders,
etc. to the addresses below.
Jef Poskanzer, UniSoft Systems, Berkeley
unisoft!jef at ucbvax.Berkeley.Edu
...ucbvax!unisoft!jef
(415)644-1230
------------.
.--' o . . `--.
.-' . O . . `-.
-'@ @@@@@@@ . @@@@@ `-.
@@@ @@@@@@@@@@@ @@@@@@@ . \
/ o @@@@@@@@@@@ @@@@@@@ . \.
@@ o @@@@@@@@@@@. @@@@@@@ O \
@@@@ . @@@@@@@o @@@@@@@@@@ @@@ \
@@@@@ . @@@@@@@@@@@@@ o @@@@|
@@@@@ O `.-./ . @@@@@@@@@@@@ @@ \ First Quarter +
@@@@ --`-' o @@@@@@@@ @@@@ | 5 22:33:24
@ @@@ ` o . @@ . @@@@@@@ | Full Moon -
@@ .-. @@@ @@@@@@@ | 1 10:37:39
. o @@@ `-' . @@@@ @@@@ o /
@@ @@@@@ . @@ . |
@@@@ @\@@ / . O . o . /
o @@ \ \ / . . /
\ . .\.-.___ . . .-. /'
`-' `-' /
-. o / | o O . .-'
`-. / . . .-'
`--. . .--'
------------'
#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# README
# Makefile
# deltime.c
# deltime.man
# dtime.c
# dtimep.lex
# This archive created: Mon Nov 17 11:55:54 1986
# By: Jef Poskanzer ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'README'" '(3041 characters)'
if test -f 'README'
then
echo shar: will not over-write existing file "'README'"
else
sed 's/^X//' << \SHAR_EOF > 'README'
XFirst distribution of phoon, deltime, and libtws - 15nov86.
X
X
XThis package contains two programs and a library:
X
X phoon - program to display the PHase of the mOON. Unlike other
X such programs, which just tell you how long since first quarter
X or something like that, phoon *shows* you the phase with a little
X picture. I've put an example at the end of this file.
X
X deltime - program to subtract date/times. Tells you the difference
X between two date/times, or between now and a specified date/time.
X I once used this to help a friend quit smoking - every time she
X logged in, the computer told her how many days since her last
X cigarette. I also use it in my .login, to tell me how old I am.
X
X libtws - date/time library. Unlike the standard Unix(R)
X date/time routines, libtws lets you parse a date/time string
X into internal form. Most of this library came from version
X 6.5 of the MH message handling system, courtesy of Marshall Rose.
X
X
XFiles in this distribution:
X
X README this
X Makefile guess
X deltime.c source for time subtraction tool
X deltime.man manual for time subtraction tool
X dtime.c source for most of the time routines
X dtimep.lex source for time-parsing routine
X lexedit.sed script to modify output of lex
X lexstring.c front end for time-parsing routine
X libtws.man manual for time library
X parsetime.c source for test program
X phoon.c source for phase of moon program
X phoon.man manual for phase of moon program
X tws.h include file for time library
X
X
XUnpack the files, edit Makefile and change the options to suit,
Xmake, and enjoy! I've tested this stuff under 4.2 BSD, 4.3 BSD,
Xand System V rel 2. Nevertheless, I'm sure bugs remain. Feedback
Xis welcome - send bug reports, enhancements, checks, money orders,
Xetc. to the addresses below.
X
X
X Jef Poskanzer, UniSoft Systems, Berkeley
X unisoft!jef at ucbvax.Berkeley.Edu
X ...ucbvax!unisoft!jef
X (415)644-1230
X
X ------------.
X .--' o . . `--.
X .-' . O . . `-.
X -'@ @@@@@@@ . @@@@@ `-.
X @@@ @@@@@@@@@@@ @@@@@@@ . \
X / o @@@@@@@@@@@ @@@@@@@ . \.
X @@ o @@@@@@@@@@@. @@@@@@@ O \
X @@@@ . @@@@@@@o @@@@@@@@@@ @@@ \
X @@@@@ . @@@@@@@@@@@@@ o @@@@|
X @@@@@ O `.-./ . @@@@@@@@@@@@ @@ \ First Quarter +
X @@@@ --`-' o @@@@@@@@ @@@@ | 5 22:33:24
X @ @@@ ` o . @@ . @@@@@@@ | Full Moon -
X @@ .-. @@@ @@@@@@@ | 1 10:37:39
X . o @@@ `-' . @@@@ @@@@ o /
X @@ @@@@@ . @@ . |
X @@@@ @\@@ / . O . o . /
X o @@ \ \ / . . /
X \ . .\.-.___ . . .-. /'
X `-' `-' /
X -. o / | o O . .-'
X `-. / . . .-'
X `--. . .--'
X ------------'
SHAR_EOF
if test 3041 -ne "`wc -c < 'README'`"
then
echo shar: error transmitting "'README'" '(should have been 3041 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'Makefile'" '(1873 characters)'
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
sed 's/^X//' << \SHAR_EOF > 'Makefile'
X# Makefile for phoon, deltime, parsetime, and libtws (stolen from mh).
X
X
X# Valid options:
X# BSD42 Set this if your system is BSD 4.2 or later.
X# SYS5 Set this if your system is System V.
X# EUROPE Makes nn/nn/nn mean dd/mm/yy instead of mm/dd/yy.
X# ATZ This has something to do with alpha-numeric time zones.
X# DSTXXX This has something to do with daylight savings time.
X# HUJI I don't
X# INETONLY know what
X# LEXDEBUG the rest of these
X# ONECASE do.
XOPTIONS = -DBSD42 -DATZ -DDSTXXX
X
X
XCC = cc
XCFLAGS = -O $(OPTIONS)
XLDFLAGS = -ns
X
X.SUFFIXES: .man .cat
X.man.cat:
X nroff -h -man $< > $@
X
X
Xall: phoon phoon.cat deltime deltime.cat parsetime libtws.cat
X
X
Xphoon: phoon.o libtws.a
X $(CC) $(LDFLAGS) -o phoon phoon.o -lm libtws.a
X
Xphoon.o: phoon.c tws.h
X
X
Xdeltime: deltime.o libtws.a
X $(CC) $(LDFLAGS) -o deltime deltime.o libtws.a
X
Xdeltime.o: deltime.c tws.h
X
X
Xparsetime: parsetime.o libtws.a
X $(CC) $(LDFLAGS) -o parsetime parsetime.o libtws.a
X
Xparsetime.o: parsetime.c tws.h
X
X
Xlibtws.a: dtime.o dtimep.o lexstring.o
X ar r libtws.a dtime.o dtimep.o lexstring.o
X ranlib libtws.a
X
X
Xdtime.o: dtime.c tws.h
X
X
Xdtimep.o: dtimep.c tws.h
X
Xdtimep.c: dtimep.lex
X lex -nt dtimep.lex | sed -f lexedit.sed > dtimep.c
X
X
Xlexstring.o: lexstring.c
X $(CC) $(CFLAGS) -c -DONECASE lexstring.c
X
X
Xclean:
X -rm -f dtimep.c *.o libtws.a phoon deltime parsetime *.cat phoon.shar core
X
Xphoon.shar: phoon.shar1 phoon.shar2
X
Xphoon.shar1: README Makefile deltime.c deltime.man dtime.c dtimep.lex
X shar -v -c -p X README Makefile deltime.c deltime.man dtime.c dtimep.lex > phoon.shar1
X
Xphoon.shar2: lexedit.sed lexstring.c libtws.man parsetime.c phoon.c phoon.man tws.h
X shar -v -c -p X lexedit.sed lexstring.c libtws.man parsetime.c phoon.c phoon.man tws.h > phoon.shar2
SHAR_EOF
if test 1873 -ne "`wc -c < 'Makefile'`"
then
echo shar: error transmitting "'Makefile'" '(should have been 1873 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'deltime.c'" '(2156 characters)'
if test -f 'deltime.c'
then
echo shar: will not over-write existing file "'deltime.c'"
else
sed 's/^X//' << \SHAR_EOF > 'deltime.c'
X/* deltime.c - subtract date/times
X
Xver date who remarks
X--- ------- --- -------------------------------------------------------------
X01B 15nov86 JP Modified to use twsubtract().
X01A 08nov86 JP Written.
X
XCopyright (C) 1986 by Jef Poskanzer. Permission to use, copy,
Xmodify, and distribute this software and its documentation for any
Xpurpose and without fee is hereby granted, provided that this copyright
Xnotice appear in all copies and in all supporting documentation. No
Xrepresentation is made about the suitability of this software for any
Xpurpose. It is provided "as is" without express or implied warranty.
X
X*/
X
Xstatic char copyright[] = "\nCopyright (C) 1986 by Jef Poskanzer.\n";
X
X
X#include "tws.h"
X#include <stdio.h>
X
X#define SECSPERMINUTE 60
X#define SECSPERHOUR (60 * SECSPERMINUTE)
X#define SECSPERDAY (24 * SECSPERHOUR)
X
Xmain( argc, argv )
Xint argc;
Xchar *argv[];
X {
X struct tws tws1, tws2, *twp;
X long delta, days, hours, minutes, secs;
X char *illdt = "illegal date/time: %s\n";
X
X if ( argc == 2 )
X {
X twp = dparsetime( argv[1] );
X if ( twp == NULL || twp -> tw_flags & TW_JUNK )
X {
X fprintf( stderr, illdt, argv[1] );
X exit( 1 );
X }
X twscopy( &tws1, twp );
X twscopy( &tws2, dtwstime( ) );
X }
X else if ( argc == 3 )
X {
X twp = dparsetime( argv[1] );
X if ( twp == NULL || twp -> tw_flags & TW_JUNK )
X {
X fprintf( stderr, illdt, argv[1] );
X exit( 1 );
X }
X twscopy( &tws1, twp );
X twp = dparsetime( argv[2] );
X if ( twp == NULL || twp -> tw_flags & TW_JUNK )
X {
X fprintf( stderr, illdt, argv[2] );
X exit( 1 );
X }
X twscopy( &tws2, twp );
X }
X else
X {
X fprintf( stderr, "usage: %s <time> [ <time2> ]\n", argv[0] );
X exit( 1 );
X }
X
X delta = twsubtract( &tws2, &tws1 );
X if ( delta < 0 )
X {
X printf( "-" );
X delta = -delta;
X }
X
X days = delta / SECSPERDAY;
X delta = delta - days * SECSPERDAY;
X hours = delta / SECSPERHOUR;
X delta = delta - hours * SECSPERHOUR;
X minutes = delta / SECSPERMINUTE;
X delta = delta - minutes * SECSPERMINUTE;
X secs = delta;
X
X printf( "%ld %2ld:%02ld:%02ld\n", days, hours, minutes, secs );
X
X exit( 0 );
X }
SHAR_EOF
if test 2156 -ne "`wc -c < 'deltime.c'`"
then
echo shar: error transmitting "'deltime.c'" '(should have been 2156 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'deltime.man'" '(760 characters)'
if test -f 'deltime.man'
then
echo shar: will not over-write existing file "'deltime.man'"
else
sed 's/^X//' << \SHAR_EOF > 'deltime.man'
X.TH example 1 "08 November 1986"
X.SH NAME
Xdeltime \- compute a delta time
X.SH SYNOPSIS
X.in +.5i
X.ti -.5i
Xdeltime <time> \%[ <time2> ]
X.in -.5i
X.SH DESCRIPTION
X.PP
X.I Deltime
Xcomputes the elapsed time between now and a
Xspecified date/time, or between two specified date/times.
XThe format for specifying date/times is pretty loose - basically
Xthe same as the format for date/times in network mail.
XJust be careful to put them in quotes if they contain spaces.
XThe output format is dddd hh:mm:ss.
X.PP
XTimes earlier than 1970
X.I can
Xbe handled, because the internal Unix(R) time format is not used.
XHowever, time spans greater than 66 years
X.I cannot
Xbe handled, because that's 2**31 seconds.
X.SH "SEE\ ALSO"
X.IR phoon(1),
X.IR libtws(3)
X.SH AUTHOR
XJef Poskanzer
SHAR_EOF
if test 760 -ne "`wc -c < 'deltime.man'`"
then
echo shar: error transmitting "'deltime.man'" '(should have been 760 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'dtime.c'" '(8989 characters)'
if test -f 'dtime.c'
then
echo shar: will not over-write existing file "'dtime.c'"
else
sed 's/^X//' << \SHAR_EOF > 'dtime.c'
X/* dtime.c - routines to do ``ARPA-style'' time structures
X
Xver date who remarks
X--- ------- --- -------------------------------------------------------------
X01B 15nov86 JP Thouroughly hacked by Jef Poskanzer.
X01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
X of Marshall Rose.
X
X*/
X
X
X#include "tws.h"
X#include <stdio.h>
X#include <sys/types.h>
X#include <time.h>
X#ifdef SYS5
X#include <string.h>
X#else SYS5
X#include <strings.h>
X#include <sys/timeb.h>
X#endif SYS5
X
X#ifdef SYS5
Xextern int daylight;
Xextern long timezone;
Xextern char *tzname[];
X#endif SYS5
X
X/* */
X
X#define abs(a) ( a >= 0 ? a : -a )
X
Xchar *tw_moty[] = {
X "Jan", "Feb", "Mar", "Apr", "May", "Jun",
X "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL };
X
Xchar *tw_dotw[] = {
X "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL };
X
Xchar *tw_ldotw[] = {
X "Sunday", "Monday", "Tuesday", "Wednesday",
X "Thursday", "Friday", "Saturday", NULL };
X
X/* */
X
Xstatic struct zone
X {
X char *std;
X char *dst;
X int shift;
X }
X zones[] = {
X "GMT", "BST", 0,
X "EST", "EDT", -5,
X "CST", "CDT", -6,
X "MST", NULL, -7,
X "PST", "PDT", -8,
X "A", NULL, -1,
X "B", NULL, -2,
X "C", NULL, -3,
X "D", NULL, -4,
X "E", NULL, -5,
X "F", NULL, -6,
X "G", NULL, -7,
X "H", NULL, -8,
X "I", NULL, -9,
X "K", NULL, -10,
X "L", NULL, -11,
X "M", NULL, -12,
X "N", NULL, 1,
X#ifndef HUJI
X "O", NULL, 2,
X#else HUJI
X "JST", "JDT", 2,
X#endif HUJI
X "P", NULL, 3,
X "Q", NULL, 4,
X "R", NULL, 5,
X "S", NULL, 6,
X "T", NULL, 7,
X "U", NULL, 8,
X "V", NULL, 9,
X "W", NULL, 10,
X "X", NULL, 11,
X "Y", NULL, 12,
X NULL };
X
X#define CENTURY 19
X
Xlong time( );
Xstruct tm *localtime( );
X
X/* */
X
Xchar *dtimenow( )
X {
X long clock;
X
X (void) time( &clock );
X return ( dtime( &clock ) );
X }
X
X
Xchar *
Xdctime( tw )
Xstruct tws *tw;
X {
X static char buffer[25];
X
X if ( tw == NULL )
X return ( NULL );
X
X (void) sprintf( buffer, "%.3s %.3s %02d %02d:%02d:%02d %.4d\n",
X tw_dotw[tw -> tw_wday], tw_moty[tw -> tw_mon], tw -> tw_mday,
X tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
X tw -> tw_year >= 100 ? tw -> tw_year : 1900 + tw -> tw_year );
X
X return ( buffer );
X }
X
X/* */
X
Xstruct tws *
Xdtwstime( )
X {
X long clock;
X
X (void) time( &clock );
X return ( dlocaltime( &clock ) );
X }
X
X
Xstruct tws *
Xdlocaltime( clock )
Xlong *clock;
X {
X register struct tm *tm;
X#ifndef SYS5
X struct timeb tb;
X#endif not SYS5
X static struct tws tw;
X
X if ( clock == NULL )
X return ( NULL );
X tw.tw_flags = TW_NULL;
X
X tm = localtime( clock );
X tw.tw_sec = tm -> tm_sec;
X tw.tw_min = tm -> tm_min;
X tw.tw_hour = tm -> tm_hour;
X tw.tw_mday = tm -> tm_mday;
X tw.tw_mon = tm -> tm_mon;
X tw.tw_year = tm -> tm_year;
X tw.tw_wday = tm -> tm_wday;
X tw.tw_yday = tm -> tm_yday;
X if ( tm -> tm_isdst )
X tw.tw_flags |= TW_DST;
X#ifndef SYS5
X ftime( &tb );
X tw.tw_zone = -tb.timezone;
X#else SYS5
X tzset( );
X tw.tw_zone = -(timezone / 60);
X#endif SYS5
X tw.tw_flags &= ~TW_SDAY;
X tw.tw_flags |= TW_SEXP;
X tw.tw_clock = *clock;
X
X return ( &tw );
X }
X
X
Xstruct tws *
Xdgmtime( clock )
Xlong *clock;
X {
X register struct tm *tm;
X static struct tws tw;
X
X if ( clock == NULL )
X return ( NULL );
X tw.tw_flags = TW_NULL;
X
X tm = gmtime( clock );
X tw.tw_sec = tm -> tm_sec;
X tw.tw_min = tm -> tm_min;
X tw.tw_hour = tm -> tm_hour;
X tw.tw_mday = tm -> tm_mday;
X tw.tw_mon = tm -> tm_mon;
X tw.tw_year = tm -> tm_year;
X tw.tw_wday = tm -> tm_wday;
X tw.tw_yday = tm -> tm_yday;
X if ( tm -> tm_isdst )
X tw.tw_flags |= TW_DST;
X tw.tw_zone = 0;
X tw.tw_flags &= ~TW_SDAY;
X tw.tw_flags |= TW_SEXP;
X tw.tw_clock = *clock;
X
X return( &tw );
X }
X
X/* */
X
Xchar *
Xdasctime( tw, flags )
Xstruct tws *tw;
Xint flags;
X {
X static char buffer[80], result[80];
X
X if ( tw == NULL )
X return ( NULL );
X
X (void) sprintf( buffer, "%02d %s %02d %02d:%02d:%02d %s",
X tw -> tw_mday, tw_moty[tw -> tw_mon], tw -> tw_year,
X tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
X dtimezone( tw -> tw_zone, tw -> tw_flags | flags ) );
X
X if ( (tw -> tw_flags & TW_SDAY) == TW_SEXP )
X (void) sprintf( result, "%s, %s", tw_dotw[tw -> tw_wday], buffer );
X else
X if ( (tw -> tw_flags & TW_SDAY) == TW_SNIL )
X (void) strcpy( result, buffer );
X else
X (void) sprintf( result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday] );
X
X return ( result );
X }
X
X/* */
X
Xchar *
Xdtimezone( offset, flags )
Xint offset, flags;
X {
X register int hours, mins;
X register struct zone *z;
X static char buffer[10];
X
X if ( offset < 0 )
X {
X mins = -((-offset) % 60);
X hours = -((-offset) / 60);
X }
X else
X {
X mins = offset % 60;
X hours = offset / 60;
X }
X
X if ( !(flags & TW_ZONE) && mins == 0 )
X for ( z = zones; z -> std; z++ )
X if ( z -> shift == hours )
X return ( z -> dst && (flags & TW_DST) ? z -> dst : z -> std );
X
X#ifdef DSTXXX
X if ( flags & TW_DST )
X hours += 1;
X#endif DSTXXX
X (void) sprintf( buffer, "%s%02d%02d",
X offset < 0 ? "-" : "+", abs( hours ), abs( mins ) );
X return ( buffer );
X }
X
X/* */
X
Xvoid
Xtwscopy( tb, tw )
Xstruct tws *tb, *tw;
X {
X#ifdef notdef
X tb -> tw_sec = tw -> tw_sec;
X tb -> tw_min = tw -> tw_min;
X tb -> tw_hour = tw -> tw_hour;
X tb -> tw_mday = tw -> tw_mday;
X tb -> tw_mon = tw -> tw_mon;
X tb -> tw_year = tw -> tw_year;
X tb -> tw_wday = tw -> tw_wday;
X tb -> tw_yday = tw -> tw_yday;
X tb -> tw_zone = tw -> tw_zone;
X tb -> tw_clock = tw -> tw_clock;
X tb -> tw_flags = tw -> tw_flags;
X#else not notdef
X *tb = *tw;
X#endif not notdef
X }
X
X
Xint
Xtwsort( tw1, tw2 )
Xstruct tws *tw1, *tw2;
X {
X register long c1, c2;
X
X (void) twclock( tw1 );
X (void) twclock( tw2 );
X
X return ( (c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1
X : c1 == c2 ? 0 : -1 );
X }
X
X/* */
X
X
X/* Julian day number of the Unix clock's origin, 01 Jan 1970. */
X#define JD1970 2440587L
X
X
Xlong
Xtwjuliandate( tw )
Xstruct tws *tw;
X {
X register int mday, mon, year;
X register long a, b;
X double jd;
X
X if ( (mday = tw -> tw_mday) < 1 || mday > 31 ||
X (mon = tw -> tw_mon + 1) < 1 || mon > 12 ||
X (year = tw -> tw_year) < 1 || year > 10000 )
X return ( -1L );
X if ( year < 100 )
X year += CENTURY * 100;
X
X if ( mon == 1 || mon == 2 )
X {
X --year;
X mon += 12;
X }
X if ( year < 1583 )
X return ( -1L );
X a = year / 100;
X b = 2 - a + a / 4;
X b += (long) ( (double) year * 365.25 );
X b += (long) ( 30.6001 * ( (double) mon + 1.0 ) );
X jd = mday + b + 1720994.5;
X return ( (long) jd );
X }
X
X
Xlong
Xtwsubdayclock( tw )
Xstruct tws *tw;
X {
X register int i, sec, min, hour;
X register long result;
X
X if ( (sec = tw -> tw_sec) < 0 || sec > 59 ||
X (min = tw -> tw_min) < 0 || min > 59 ||
X (hour = tw -> tw_hour) < 0 || hour > 23 )
X return ( -1L );
X
X result = ( hour * 60 + min ) * 60 + sec;
X result -= 60 * tw -> tw_zone;
X if ( tw -> tw_flags & TW_DST )
X result -= 60 * 60;
X
X return ( result );
X }
X
X
Xlong
Xtwclock( tw )
Xstruct tws *tw;
X {
X register long jd, sdc, result;
X
X if ( tw -> tw_clock != 0L )
X return ( tw -> tw_clock );
X
X if ( ( jd = twjuliandate( tw ) ) == -1L )
X return ( tw -> tw_clock = -1L );
X if ( ( sdc = twsubdayclock( tw ) ) == -1L )
X return ( tw -> tw_clock = -1L );
X
X result = ( jd - JD1970 ) * 24 * 60 * 60 + sdc;
X
X return ( tw -> tw_clock = result );
X }
X
X/* */
X
X/*** twsubtract - subtract tw2 from tw1, returning result in seconds
X
XThe point of this routine is that using twclock( tw1 ) - twclock( tw2 )
Xwould limit you to dates after the Unix Epoch ( 01 January 1970 ). This
Xroutine avoids that limit. However, because the result is represented
Xby 32 bits, it is still limited to a span of two billion seconds, which is
Xabout 66 years.
X
X*/
X
Xlong
Xtwsubtract( tw1, tw2 )
Xstruct tws *tw1, *tw2;
X {
X register long jd1, jd2, sdc1, sdc2, result;
X
X if ( ( jd1 = twjuliandate( tw1 ) ) == -1L )
X return ( 0L );
X if ( ( sdc1 = twsubdayclock( tw1 ) ) == -1L )
X return ( 0L );
X
X if ( ( jd2 = twjuliandate( tw2 ) ) == -1L )
X return ( 0L );
X if ( ( sdc2 = twsubdayclock( tw2 ) ) == -1L )
X return ( 0L );
X
X result = ( jd1 - jd2 ) * 24 * 60 * 60 + ( sdc1 - sdc2 );
X
X return ( result );
X }
X
X/* */
X
X/*
X * Simple calculation of day of the week. Algorithm used is Zeller's
X * congruence. Currently, we assume if tw -> tw_year < 100
X * then the century is CENTURY.
X */
X
Xset_dotw( tw )
Xstruct tws *tw;
X {
X register int month, day, year, century;
X
X month = tw -> tw_mon - 1;
X day = tw -> tw_mday;
X year = tw -> tw_year % 100;
X century = tw -> tw_year >= 100 ? tw -> tw_year / 100 : CENTURY;
X
X if ( month <= 0 )
X {
X month += 12;
X if ( --year < 0 )
X {
X year += 100;
X century--;
X }
X }
X
X tw -> tw_wday =
X ((26 * month - 2) / 10 + day + year + year / 4
X - 3 * century / 4 + 1) % 7;
X
X tw -> tw_flags &= ~TW_SDAY;
X tw -> tw_flags |= TW_SIMP;
X }
SHAR_EOF
if test 8989 -ne "`wc -c < 'dtime.c'`"
then
echo shar: error transmitting "'dtime.c'" '(should have been 8989 characters)'
fi
fi # end of overwriting check
echo shar: extracting "'dtimep.lex'" '(7171 characters)'
if test -f 'dtimep.lex'
then
echo shar: will not over-write existing file "'dtimep.lex'"
else
sed 's/^X//' << \SHAR_EOF > 'dtimep.lex'
X%e 2000
X%p 5000
X%n 1000
X%a 4000
X%START Z
Xsun (sun(day)?)
Xmon (mon(day)?)
Xtue (tue(sday)?)
Xwed (wed(nesday)?)
Xthu (thu(rsday)?)
Xfri (fri(day)?)
Xsat (sat(urday)?)
X
XDAY ({sun}|{mon}|{tue}|{wed}|{thu}|{fri}|{sat})
X
Xjan (jan(uary)?)
Xfeb (feb(ruary)?)
Xmar (mar(ch)?)
Xapr (apr(il)?)
Xmay (may)
Xjun (jun(e)?)
Xjul (jul(y)?)
Xaug (aug(ust)?)
Xsep (sep(tember)?)
Xoct (oct(ober)?)
Xnov (nov(ember)?)
Xdec (dec(ember)?)
X
XMONTH ({jan}|{feb}|{mar}|{apr}|{may}|{jun}|{jul}|{aug}|{sep}|{oct}|{nov}|{dec})
X
Xw ([ \t]*)
XW ([ \t]+)
XD ([0-9]?[0-9])
Xd [0-9]
X%{
X/* dtimep.lex - routines to do ``ARPA-style'' time parsing
X
Xver date who remarks
X--- ------- --- -------------------------------------------------------------
X01B 15nov86 JP Thouroughly hacked by Jef Poskanzer.
X01A ??????? MTR Original version from the MH 6.5 distribution, courtesy
X of Marshall Rose.
X
X*/
X
X#include "tws.h"
X#include <ctype.h>
X#include <sys/types.h>
X#include <time.h>
X#ifdef SYS5
X#include <string.h>
X#else SYS5
X#include <strings.h>
X#include <sys/timeb.h>
X#endif SYS5
X
X#ifdef SYS5
Xextern int daylight;
Xextern long timezone;
Xextern char *tzname[];
X#endif SYS5
X
X/*
X * Table to convert month names to numeric month. We use the
X * fact that the low order 5 bits of the sum of the 2nd & 3rd
X * characters of the name is a hash with no collisions for the 12
X * valid month names. (The mask to 5 bits maps any combination of
X * upper and lower case into the same hash value).
X */
Xstatic int month_map[] = {
X 0,
X 6, /* 1 - Jul */
X 3, /* 2 - Apr */
X 5, /* 3 - Jun */
X 0,
X 10, /* 5 - Nov */
X 0,
X 1, /* 7 - Feb */
X 11, /* 8 - Dec */
X 0,
X 0,
X 0,
X 0,
X 0,
X 0,
X 0, /*15 - Jan */
X 0,
X 0,
X 0,
X 2, /*19 - Mar */
X 0,
X 8, /*21 - Sep */
X 0,
X 9, /*23 - Oct */
X 0,
X 0,
X 4, /*26 - May */
X 0,
X 7 }; /*28 - Aug */
X/*
X * Same trick for day-of-week using the hash function
X * (c1 & 7) + (c2 & 4)
X */
Xstatic int day_map[] = {
X 0,
X 0,
X 0,
X 6, /* 3 - Sat */
X 4, /* 4 - Thu */
X 0,
X 5, /* 6 - Fri */
X 0, /* 7 - Sun */
X 2, /* 8 - Tue */
X 1 /* 9 - Mon */,
X 0,
X 3 }; /*11 - Wed */
X#define SETDAY tw.tw_wday= day_map[(cp[0] & 7) + (cp[1] & 4)];\
X tw.tw_flags |= TW_SEXP;\
X cp += 2;
X#define SETMONTH tw.tw_mon = month_map[(cp[0] + cp[1]) & 0x1f]; gotdate++;\
X cp += 2;\
X SKIPD;
X#define CVT1OR2 (i=(*cp++ - '0'), isdigit(*cp)? i*10 + (*cp++ - '0') : i)
X#define CVT2 ( (*cp++ - '0')*10 + (*cp++ - '0') )
X#define CVT3 ( ( (*cp++ - '0')*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )
X#define CVT4 ( ( ( (*cp++ - '0')*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )*10 + (*cp++ - '0') )
X#define SKIPD while ( ! isdigit( *cp++ ) ) ; --cp;
X#define ZONE(x) tw.tw_zone=(x);
X#define ZONED(x) tw.tw_zone=(x); tw.tw_flags |= TW_DST;
X#define LC(c) (isupper( c ) ? tolower( c ) : ( c ))
X%}
X%%
X%{
Xstruct tws *
Xdparsetime( str )
Xchar *str;
X {
X register int i;
X static struct tws tw;
X register char *cp;
X register int gotdate = 0;
X#ifndef SYS5
X struct timeb tb;
X#endif not SYS5
X long clock;
X
X start_cond = 0;
X
X /* Zero out the struct. */
X bzero( (char *) &tw, sizeof tw );
X
X /* Set default time zone. */
X#ifndef SYS5
X ftime( &tb );
X tw.tw_zone = -tb.timezone;
X#else SYS5
X tzset( );
X tw.tw_zone = -(timezone / 60);
X#endif SYS5
X
X for ( ; ; )
X switch ( cp = str, lex_string( &str, start_cond ) )
X {
X case -1:
X if ( ! gotdate )
X return ( NULL );
X tw.tw_flags |= TW_JUNK;
X /* fall through */
X case 0:
X if ( tw.tw_year == 0 )
X {
X /* Set default year. */
X time( &clock );
X tw.tw_year = localtime( &clock ) -> tm_year;
X }
X return ( &tw );
X
X%}
X{DAY}","?{w} SETDAY;
X"("{DAY}")"(","?) cp++, SETDAY;
X
X{D}"/"{D}"/"{D}?{d}{d}{w} {
X#ifdef EUROPE
X tw.tw_mday = CVT1OR2; cp++;
X tw.tw_mon = CVT1OR2 - 1; cp++;
X#else EUROPE
X tw.tw_mon = CVT1OR2 - 1; cp++;
X tw.tw_mday = CVT1OR2; cp++;
X#endif EUROPE
X for ( i = 0; isdigit( *cp ); )
X i = i * 10 + (*cp++ - '0');
X tw.tw_year = i;
X gotdate++;
X }
X{D}"/"{D}{w} {
X#ifdef EUROPE
X tw.tw_mday = CVT1OR2; cp++;
X tw.tw_mon = CVT1OR2 - 1;
X#else EUROPE
X tw.tw_mon = CVT1OR2 - 1; cp++;
X tw.tw_mday = CVT1OR2;
X#endif EUROPE
X gotdate++;
X }
X{D}"-"?{MONTH}"-"?{D}?{d}{d}({W}at)?{w} |
X{D}" "{MONTH}" "{D}?{d}{d}({W}at)?{w} {
X tw.tw_mday = CVT1OR2;
X while ( ! isalpha( *cp++ ) )
X ;
X SETMONTH;
X for ( i = 0; isdigit( *cp ); )
X i = i * 10 + (*cp++ - '0');
X tw.tw_year = i;
X gotdate++;
X }
X{D}"-"?{MONTH}({W}at)?{w} {
X tw.tw_mday = CVT1OR2;
X while ( ! isalpha( *cp++ ) )
X ;
X SETMONTH;
X gotdate++;
X }
X{MONTH}{W}{D}","{W}{D}?{d}{d}{w} {
X cp++;
X SETMONTH;
X tw.tw_mday = CVT1OR2;
X SKIPD;
X for ( i = 0; isdigit( *cp ); )
X i = i * 10 + (*cp++ - '0');
X tw.tw_year = i;
X gotdate++;
X }
X{MONTH}{W}{D}{w} {
X cp++;
X SETMONTH;
X tw.tw_mday = CVT1OR2;
X gotdate++;
X }
X
X{D}:{D}:{D}({w}am)?{w} {
X tw.tw_hour = CVT1OR2; cp++;
X tw.tw_min = CVT1OR2; cp++;
X tw.tw_sec = CVT1OR2;
X BEGIN Z;
X }
X{D}:{D}:{D}{w}pm{w} {
X tw.tw_hour = CVT1OR2 + 12; cp++;
X tw.tw_min = CVT1OR2; cp++;
X tw.tw_sec = CVT1OR2;
X BEGIN Z;
X }
X{D}:{D}({w}am)?{w} {
X tw.tw_hour = CVT1OR2; cp++;
X tw.tw_min = CVT1OR2;
X BEGIN Z;
X }
X{D}:{D}{w}pm{w} {
X tw.tw_hour = CVT1OR2 + 12; cp++;
X tw.tw_min = CVT1OR2;
X BEGIN Z;
X }
X[0-2]{d}{d}{d}{d}{d}{w} {
X tw.tw_hour = CVT1OR2;
X tw.tw_min = CVT1OR2;
X tw.tw_sec = CVT1OR2;
X BEGIN Z;
X }
X[0-2]{d}{d}{d}{w} {
X tw.tw_hour = CVT1OR2;
X tw.tw_min = CVT1OR2;
X BEGIN Z;
X }
X<Z>"-"?ut ZONE(0 * 60);
X<Z>"-"?gmt ZONE(0 * 60);
X<Z>"-"?jst ZONE(2 * 60);
X<Z>"-"?jdt ZONED(2 * 60);
X<Z>"-"?est ZONE(-5 * 60);
X<Z>"-"?edt ZONED(-5 * 60);
X<Z>"-"?cst ZONE(-6 * 60);
X<Z>"-"?cdt ZONED(-6 * 60);
X<Z>"-"?mst ZONE(-7 * 60);
X<Z>"-"?mdt ZONED(-7 * 60);
X<Z>"-"?pst ZONE(-8 * 60);
X<Z>"-"?pdt ZONED(-8 * 60);
X<Z>"-"?nst ZONE(-(3 * 60 + 30));
X<Z>"-"?ast ZONE(-4 * 60);
X<Z>"-"?adt ZONED(-4 * 60);
X<Z>"-"?yst ZONE(-9 * 60);
X<Z>"-"?ydt ZONED(-9 * 60);
X<Z>"-"?hst ZONE(-10 * 60);
X<Z>"-"?hdt ZONED(-10 * 60);
X<Z>"-"?bst ZONED(-1 * 60);
X<Z>[a-i] tw.tw_zone = 60 * (('a'-1) - LC (*cp));
X<Z>[k-m] tw.tw_zone = 60 * ('a' - LC (*cp));
X<Z>[n-y] tw.tw_zone = 60 * (LC (*cp) - 'm');
X<Z>"+"[0-1]{d}{d}{d} {
X cp++;
X tw.tw_zone = ((cp[0] * 10 + cp[1])
X -('0' * 10 + '0'))*60
X +((cp[2] * 10 + cp[3])
X -('0' * 10 + '0'));
X#ifdef DSTXXX
X zonehack (&tw);
X#endif DSTXXX
X cp += 4;
X }
X<Z>"-"[0-1]{d}{d}{d} {
X cp++;
X tw.tw_zone = (('0' * 10 + '0')
X -(cp[0] * 10 + cp[1]))*60
X +(('0' * 10 + '0')
X -(cp[2] * 10 + cp[3]));
X#ifdef DSTXXX
X zonehack (&tw);
X#endif DSTXXX
X cp += 4;
X }
X
X<Z>{W}{d}{d}{d}{d} {
X SKIPD;
X tw.tw_year = CVT4;
X }
X\n |
X{W} ;
X%%
X
X#ifdef DSTXXX
Xstatic
Xzonehack( tw )
Xregister struct tws *tw;
X {
X register struct tm *tm;
X
X if ( twclock( tw ) == -1L )
X return;
X
X tm = localtime( &tw -> tw_clock );
X if ( tm -> tm_isdst )
X {
X tw -> tw_flags |= TW_DST;
X tw -> tw_zone -= 60;
X }
X }
X#endif DSTXXX
SHAR_EOF
if test 7171 -ne "`wc -c < 'dtimep.lex'`"
then
echo shar: error transmitting "'dtimep.lex'" '(should have been 7171 characters)'
fi
fi # end of overwriting check
# End of shell archive
exit 0
More information about the Comp.sources.unix
mailing list