home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume35
/
hebcal
/
part01
next >
Wrap
Text File
|
1993-02-21
|
53KB
|
1,944 lines
Newsgroups: comp.sources.misc,soc.culture.jewish
From: sadinoff@unagi.cis.upenn.edu (Danny Sadinoff)
Subject: v35i076: hebcal - A Jewish calendar generator, v2.0, Part01/01
Message-ID: <1993Feb22.035212.14721@sparky.imd.sterling.com>
X-Md4-Signature: c40b69fb42d9e91ed258eb9aea8dbbc6
Date: Mon, 22 Feb 1993 03:52:12 GMT
Approved: kent@sparky.imd.sterling.com
Submitted-by: sadinoff@unagi.cis.upenn.edu (Danny Sadinoff)
Posting-number: Volume 35, Issue 76
Archive-name: hebcal/part01
Environment: UNIX
Supersedes: hebcal: Volume 34, Issue 117
[ THIS PROGRAM IS SHAREWARE/GUILTWARE -Kent+ ]
Hebcal 2.0 - a program for printing Jewish calendars
by Danny Sadinoff
DESCRIPTION
Hebcal is a program which prints out the days in the Jewish calendar
for a given gregorian year. Hebcal is fairly flexible in terms of which
events in the Jewish calendar it displays. Each of the following can
be individualy turned on or off:
The Hebrew date
Jewish Holdiays (including Yom Ha'atzmaut and Yom HaShoah etc.)
The weekly Sedrah
The day of the week
The days of the Omer
CHANGES
Since version 1.4:
Optimized code, with an eye towards the -t and -T switches
Added -i user events option.
Added -S "what's this week's sedra?" option
Since version 1.3:
This is a quickie fix of the new Chanukah routine added in the last release
I also changed the suffix of the manpage from .l to .1, since it was
causing some versions of make to compile the manpage as a lex
file, destroying the source code in the process.
Added Yom Yerushalayim
changed output format from "24 of Kislev" to "24th of Kislev"
Since version 1.2:
Fixed a critical bug which put Purim on the 15th of Adar, instead of
the 14th
Now uses sys/types.h instead of stdlib.h
Added the rest of the 8 days of Chanukah
Added -e European output switch.
Since version 1.1, the following changes were made:
Changed usage-- the -p "parshiot" switch was changed to "-s" sedrot switch
Fixed certain slippery variable type bugs
Changed code to K&R old style
Added Manpage
Decided to change the "Distribu-Ware" to a normal shareware.
DISTRIBUTION
This program is GUILTWARE.
It may be distributed freely, with a few conditions:
1) The package must be distributed INTACT with ALL source code, as
well as this file. You are welcome to modify the code,
but DON'T distribute it modified. This disclaimer should certainly
appear with every distributed copy.
2) You can use this program for free for one week. After that
trial period, if you wish to use this program, drop me a line.
I'd like to know who you are, what version you're using, and how
you're using hebcal, and anything else you'd like to tell me, so
that I can adjust the program to meet users' needs.
I am NOT demanding payment for the use of my program, but writing
this program DID take time. Feel free to send $10 to
me at my US Mail address. (hint)
send US Mail to: send email to:
Danny Sadinoff sadinoff@eniac.seas.upenn.edu
1 Cove La.
Great Neck, NY 11024
Email respondents will receive notifications of new versions as they
come out, as will US Mail responents (if they send me postage for a disk).
If you do not mail me or email me after one week, please don't
use the program, although you may feel free to distribute it further.
COMPILATION
The code has K&R "old style" declarations in it, so it should compile
on most machines.
The distribution includes a "Makefile" so once you've unpacked all the
files, (including this one) just run the command "make" and that
should compile everything for you.
The file hebcal.1 is the manual page. For information on using man in
conjunction with local manpages, see the manpage for man. Briefly, to
read a manpage, type
nroff -man <filename> | more
#! /bin/sh
# This is a shell archive. Remove anything before this line, then feed it
# into a shell via "sh file" or similar. To overwrite existing files,
# type "sh file -c".
# Contents: README Makefile danlib.c danlib.h error.c error.h greg.c
# greg.h hebcal.1 hebcal.c hebcal.h start.c
# Wrapped by kent@sparky on Sat Feb 20 23:25:26 1993
PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
echo If this archive is complete, you will see the following message:
echo ' "shar: End of archive 1 (of 1)."'
if test -f 'README' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(6003 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XHebcal 2.0 - a program for printing Jewish calendars
X by Danny Sadinoff
X
XDESCRIPTION
XHebcal is a program which prints out the days in the Jewish calendar
Xfor a given gregorian year. Hebcal is fairly flexible in terms of which
Xevents in the Jewish calendar it displays. Each of the following can
Xbe individualy turned on or off:
X
X The Hebrew date
X Jewish Holdiays (including Yom Ha'atzmaut and Yom HaShoah etc.)
X The weekly Sedrah
X The day of the week
X The days of the Omer
X
XCHANGES
XSince version 1.4:
X Optimized code, with an eye towards the -t and -T switches
X Added -i user events option.
X Added -S "what's this week's sedra?" option
X
XSince version 1.3:
X This is a quickie fix of the new Chanukah routine added in the last release
X I also changed the suffix of the manpage from .l to .1, since it was
X causing some versions of make to compile the manpage as a lex
X file, destroying the source code in the process.
X Added Yom Yerushalayim
X changed output format from "24 of Kislev" to "24th of Kislev"
X
XSince version 1.2:
X Fixed a critical bug which put Purim on the 15th of Adar, instead of
X the 14th
X Now uses sys/types.h instead of stdlib.h
X Added the rest of the 8 days of Chanukah
X Added -e European output switch.
X
XSince version 1.1, the following changes were made:
X Changed usage-- the -p "parshiot" switch was changed to "-s" sedrot switch
X Fixed certain slippery variable type bugs
X Changed code to K&R old style
X Added Manpage
X Decided to change the "Distribu-Ware" to a normal shareware.
X
XDISTRIBUTION
XThis program is GUILTWARE.
XIt may be distributed freely, with a few conditions:
X 1) The package must be distributed INTACT with ALL source code, as
X well as this file. You are welcome to modify the code,
X but DON'T distribute it modified. This disclaimer should certainly
X appear with every distributed copy.
X
X 2) You can use this program for free for one week. After that
X trial period, if you wish to use this program, drop me a line.
X I'd like to know who you are, what version you're using, and how
X you're using hebcal, and anything else you'd like to tell me, so
X that I can adjust the program to meet users' needs.
X
X I am NOT demanding payment for the use of my program, but writing
X this program DID take time. Feel free to send $10 to
X me at my US Mail address. (hint)
X
X send US Mail to: send email to:
X Danny Sadinoff sadinoff@eniac.seas.upenn.edu
X 1 Cove La.
X Great Neck, NY 11024
X
X Email respondents will receive notifications of new versions as they
X come out, as will US Mail responents (if they send me postage for a disk).
X
X If you do not mail me or email me after one week, please don't
X use the program, although you may feel free to distribute it further.
X
X
XCOMPILATION
XThe code has K&R "old style" declarations in it, so it should compile
Xon most machines.
XThe distribution includes a "Makefile" so once you've unpacked all the
Xfiles, (including this one) just run the command "make" and that
Xshould compile everything for you.
X
XThe file hebcal.1 is the manual page. For information on using man in
Xconjunction with local manpages, see the manpage for man. Briefly, to
Xread a manpage, type
Xnroff -man <filename> | more
X
X
XOPERATION:
XThe operation of hebcal is fairly simple. Hebcal defaults to printing
Xout the holidays for the current gregorian year. With the
Xcommand-line options, a specific gregorian year, month or date can be
Xspecified.
X
XGiven one numeric argument, hebcal will print out the calendar
Xfor that year. Given two numeric argumetnts mm yyyy, it
Xprints out the calendar for month mm of year yyyy. Given three
Xnumeric arguments mm dd yyyy, it will print out the hebrew calendar
Xentries for day dd of month mm of year yyyy. In the last case, the -d
Xoption is automatically enabled.
X
XBe sure to give the whole year to hebcal.
Xhebcal 92 will return the calendar for a time somewhere in the early
Xchristian era, not in the twentieth century. Use hebcal 1992 instead.
X
Xusage: hebcal [-dehosStTw] [-i filename] [[month [day]] year]
X hebcal help --- prints this message.
X
XOPTIONS:
X -d : add hebrew dates
X -e : use European dates (dd mm yyyy) for OUTPUT ONLY (input format
X the same)
X -h : suppress holidays
X -i : draw user-defined calendar events from the specified file
X -o : add days of the omer
X -s : add weekly sedrot on Saturdays
X -S : add sedra of the week every day
X -t : only output today's date. This switch implies the -d switch.
X -T : only output today's date, suppressing gregorian date. This
X switch implies the -d and -o switches.
X -w : add day of the week
X
X
XExamples:
Xexample% hebcal -ho
X4/19/1992 1st day of the Omer
X4/20/1992 2nd day of the Omer
X4/21/1992 3rd day of the Omer
X4/22/1992 4th day of the Omer
X4/23/1992 5th day of the Omer
X4/24/1992 6th day of the Omer
X.
X.
X6/5/1992 48th day of the Omer
X6/6/1992 49th day of the Omer
X
Xto find out what's happening in today's Jewish calendar, use
Xexample% hebcal -ToS
X19 of Nisan, 5752
XPesach V (CH"M)
X4th day of the Omer
X
X
XDISCLAIMER
XI tried to make this program as accurate as possible. However, I
Xtake no responsibility for any horrible consequences which may come
Xabout as a result of faulty output from this program. Remember: never
Xtrust a program with a zero at the end of its revision number.
X
XThe secular dates before september 1752 are off by two weeks due to
Xthe correction that took place then.
X
XThe secular dates before 1522 become progressively meaningless, as I
Xmade no correction for the changeover from julian to gregorian
Xcalendars; but the Hebrew dates and years are correct.
X
XCOMING SOON
XFeatures to be included in future versions:
X - Arba' parshiot
X - The ability to specify and output a particular HEBREW year, month
X or date. The absence of this feature is a serious drawback to
X hebcal as it now stands.
X
XGRIPES
Xsend questions, comments or complaints to:
XDanny Sadinoff
Xsadinoff@eniac.seas.upenn.edu
END_OF_FILE
if test 6003 -ne `wc -c <'README'`; then
echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(99 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
XCFLAGS = -O
XOBJ= start.o hebcal.o greg.o error.o danlib.o
Xhebcal: $(OBJ)
X $(CC) $(OBJ) -o hebcal
END_OF_FILE
if test 99 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'danlib.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'danlib.c'\"
else
echo shar: Extracting \"'danlib.c'\" \(1285 characters\)
sed "s/^X//" >'danlib.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include <sys/types.h>
X#include <ctype.h>
X#include "danlib.h"
X#include "error.h"
X
X/* Some generally useful routines */
X
Xvoid initStr(s,size)
Xchar **s;
Xint size;
X{
X /* allocate space for a string */
X if ((*s = (char *)malloc((size_t) (size + 1) * sizeof(char))) == NULL)
X die("\n Memory Error: Couldn't allocate string\n","");
X
X **s = '\0';
X}
X
Xint isAllNums(s)
Xchar * s;
X{
X/* returns true if a string contains only digits, dashes and newlines */
X int n = 0, len = strlen(s);
X
X for(n=0;
X (n < len) && ( isdigit(s[n]) || (s[n] == '-') || (s[n] == '\n'));
X n++);
X return (n == len);
X}
X
Xchar * numSuffix(i)
Xint i;
X{
X/* returns he proper ordinal suffix of a number */
X if ((i / 10) == 1) return "th";
X switch (i % 10) {
X case 1 : return "st";
X case 2 : return "nd";
X case 3 : return "rd";
X default: return "th";
X }
X}
X
Xchar * itoa (i)
Xint i;
X{
X static char ret[7];
X int c = 0;
X char tmp;
X
X if (i < 0) { /* is i negative? */
X ret[c++] = '-'; /* then put a minus */
X i = abs(i);
X }
X
X while (i >0) { /* compose the number */
X ret[c++] = (i % 10) + '0';
X i /= 10;
X }
X i = c-1;
X
X for (c =0; c < i; c++) { /* reverse the number */
X tmp = ret[c];
X ret[c] = ret[i-c];
X ret[i-c] = tmp;
X }
X
X return ret;
X}
X
X
END_OF_FILE
if test 1285 -ne `wc -c <'danlib.c'`; then
echo shar: \"'danlib.c'\" unpacked with wrong size!
fi
# end of 'danlib.c'
fi
if test -f 'danlib.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'danlib.h'\"
else
echo shar: Extracting \"'danlib.h'\" \(187 characters\)
sed "s/^X//" >'danlib.h' <<'END_OF_FILE'
X#ifndef __DANLIB__
X#define __DANLIB
X
X#define CHAR2NUM(x) ((x) - '0')
X#define LAST_INDEX(x) (sizeof x / sizeof x[0])
X
Xint isAllNums();
Xvoid initStr();
Xchar * numSuffix(), *itoa();
X
X#endif
END_OF_FILE
if test 187 -ne `wc -c <'danlib.h'`; then
echo shar: \"'danlib.h'\" unpacked with wrong size!
fi
# end of 'danlib.h'
fi
if test -f 'error.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'error.c'\"
else
echo shar: Extracting \"'error.c'\" \(589 characters\)
sed "s/^X//" >'error.c' <<'END_OF_FILE'
X#include "error.h"
X
Xextern int errno, sys_nerr;
Xextern char *sys_errlist[], *progname;
X
Xvoid die (s1,s2) /* print error message and die */
Xchar *s1, *s2;
X{
X if (progname)
X fprintf(stderr, "%s: ", progname);
X fprintf(stderr, s1, s2);
X if (errno > 0 && errno < sys_nerr)
X fprintf(stderr, " (%s)\n", sys_errlist[errno]);
X exit(1);
X}
X
Xvoid warn (s1,s2) /* print error message but don't die */
Xchar *s1, *s2;
X{
X if (progname)
X fprintf(stderr, "%s: ", progname);
X fprintf(stderr, s1, s2);
X if (errno > 0 && errno < sys_nerr)
X fprintf(stderr, " (%s)\n", sys_errlist[errno]);
X}
END_OF_FILE
if test 589 -ne `wc -c <'error.c'`; then
echo shar: \"'error.c'\" unpacked with wrong size!
fi
# end of 'error.c'
fi
if test -f 'error.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'error.h'\"
else
echo shar: Extracting \"'error.h'\" \(102 characters\)
sed "s/^X//" >'error.h' <<'END_OF_FILE'
X#ifndef __ERROR__
X#define __ERROR__
X#include <stdio.h>
X#include <errno.h>
X
Xvoid die(), warn();
X#endif
END_OF_FILE
if test 102 -ne `wc -c <'error.h'`; then
echo shar: \"'error.h'\" unpacked with wrong size!
fi
# end of 'error.h'
fi
if test -f 'greg.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'greg.c'\"
else
echo shar: Extracting \"'greg.c'\" \(2697 characters\)
sed "s/^X//" >'greg.c' <<'END_OF_FILE'
X#include "greg.h"
X
X/* greg.c gregorian calendar module for hebrew calendar program
X By Danny Sadinoff
X (C) 1992
X
X*/
X
Xchar * eMonths[] = {
X "January","February","March","April","May","June","July",
X "August","September","October","November","December"
X };
X
Xint MonthLengths[][12] ={
X {31,28,31,30,31,30,31,31,30,31,30,31},
X {31,29,31,30,31,30,31,31,30,31,30,31}
X};
X
Xchar * DayNames[] = {
X "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
X };
X
Xchar * ShortDayNames[] = {
X "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
X };
X
Xstatic void checkRange (dt,routine)
Xdate_t dt;
Xchar * routine;
X{
X if ((dt.mm > 13)||(dt.dd > 31) || (dt.yy > 7000) ||
X (dt.mm <0) ||(dt.dd <0 ) || (dt.yy < -7000))
X die("Date out of range from routine %s.",routine);
X}
X
Xstatic long int daysSinceOrigin (dt)
Xdate_t dt;
X{
X int m,y;
X long int days = 0L;
X
X checkRange(dt,"daysSinceOrigin");
X
X for (y =1; y < dt.yy; y++)
X days += DAYS_IN(y);
X y = dt.yy;
X for (m= JAN; m < dt.mm; m++)
X days += MonthLengths[LEAP(y)][m];
X days += dt.dd -1;
X return days;
X}
X
Xint diffDays(d1,d2)
Xdate_t d1, d2;
X{
X return (int) (daysSinceOrigin(d1) - daysSinceOrigin(d2));
X}
X
Xint exceeds (d1,d2)
Xdate_t d1, d2;
X{
X if (d1.yy > d2.yy)
X return 1;
X else if (d1.yy < d2.yy)
X return 0;
X else if (d1.mm > d2.mm)
X return 1;
X else if (d1.mm < d2.mm)
X return 0;
X else if (d1.dd > d2.dd)
X return 1;
X else return 0;
X}
X
Xvoid decDate (dt,n) /* decrements dt by n days */
Xdate_t *dt;
Xint n;
X{
X/*under construction*/
X/* while (n > 365) {
X n -= DAYS_IN(dt->yy -1);
X dt ->yy--;
X }
X
X
X if ((dt->mm == FEB) && (dt->dd == 29) && !LEAP(dt->yy))
X dt->dd--;
X*/
X
X while (n--)
X if (dt->dd ==1) {
X if (dt->mm == JAN) {
X dt->yy--;
X dt->mm = DEC;
X dt->dd = 31;
X }
X else {
X dt->mm--;
X dt->dd = MonthLengths[LEAP(dt->yy)][dt->mm];
X }
X }
X else dt->dd--;
X}
X
Xvoid incDate (dt,n) /* increments dt by n days */
Xdate_t *dt;
Xint n;
X{
X/* while (n > 365) {
X n -= DAYS_IN(dt->yy);
X dt->yy++;
X }
X
X if ((dt->mm == FEB) && (dt->dd == 29) && !LEAP(dt->yy) ) {
X dt-> mm = MAR;
X dt-> dd = 1;
X }
X*/
X while (n--)
X if ((dt->dd + 1) > MonthLengths[LEAP(dt->yy)][dt->mm])
X if (dt->mm == DEC) {
X dt->yy++;
X dt->mm = JAN;
X dt->dd = 1;
X }
X else {
X dt->mm++;
X dt->dd =1;
X }
X else
X dt->dd ++;
X}
X
Xint dayOfWeek(d1) /* sunday = 0 */
Xdate_t d1;
X{
X return (int) ((daysSinceOrigin(d1) + 1) % 7 ) ;
X}
X
Xvoid setDate (d)
Xdate_t *d;
X{
X time_t secs;
X struct tm *loctm;
X
X secs = time(NULL);
X loctm = localtime(&secs);
X d->yy = 1900 + loctm->tm_year;
X d->mm = loctm->tm_mon;
X d->dd = loctm->tm_mday;
X}
X
X
END_OF_FILE
if test 2697 -ne `wc -c <'greg.c'`; then
echo shar: \"'greg.c'\" unpacked with wrong size!
fi
# end of 'greg.c'
fi
if test -f 'greg.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'greg.h'\"
else
echo shar: Extracting \"'greg.h'\" \(875 characters\)
sed "s/^X//" >'greg.h' <<'END_OF_FILE'
X#ifndef __GREG__
X#define __GREG__
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <time.h>
X#include "error.h"
X
X#define LEAP(x) (!((x) % 4) && ( ((x) % 100) || !((x) % 400)))
X#define DAYS_IN(x) (LEAP((x))?366:365)
X
X#define JAN 0
X#define FEB 1
X#define MAR 2
X#define APR 3
X#define MAY 4
X#define JUN 5
X#define JUL 6
X#define AUG 7
X#define SEP 8
X#define OCT 9
X#define NOV 10
X#define DEC 11
X
X#define SUN 0
X#define MON 1
X#define TUE 2
X#define WED 3
X#define THU 4
X#define FRI 5
X#define SAT 6
X
Xextern char * eMonths[];
Xextern int MonthLengths[][12] ;
Xextern char * DayNames[] ;
Xextern char * ShortDayNames[];
Xextern char * eDays[] ;
X
Xtypedef struct {
X int mm; /* months since january 0,11*/
X int dd; /* day of month 1,31 */
X int yy; /* years since year 1 BCE i.e. -1 = 2 BCE */
X } date_t;
X
Xint diffDays(), exceeds(), dayOfWeek();
Xvoid decDate (), incDate(), setDate();
X
X#endif
END_OF_FILE
if test 875 -ne `wc -c <'greg.h'`; then
echo shar: \"'greg.h'\" unpacked with wrong size!
fi
# end of 'greg.h'
fi
if test -f 'hebcal.1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'hebcal.1'\"
else
echo shar: Extracting \"'hebcal.1'\" \(4582 characters\)
sed "s/^X//" >'hebcal.1' <<'END_OF_FILE'
X.TH HEBCAL 1 "Hebcal Version 2.0" "Danny Sadinoff"
X.SH NAME
Xhebcal - a Jewish calendar generator
X.SH SYNOPSIS
X.B hebcal
X[
X\-dehosStTw
X] [
X\-i
X.I file
X] [[
X.I month
X[
X.I day
X]]
X.I year
X]
X.br
X.B hebcal help
X.SH DESCRIPTION
XWith no arguments,
X.B hebcal
Xwill print to stdout the
Xdates of the Jewish holidays in the current
Xsecular year. Each line is prefixed with a gregorian date of the form
Xmm/dd/yy.
X.sp
XBy specifying
X.I month,
X.I day,
Xor
X.I year
Xoutput can be limited to a particular month or date
Xin a particular year.
X.sp
X.I year
Xis an integer (it can be negative). So 92 is in the early Christian
Xera, not the late twentieth century.
X.sp
X.I month
Xis a number from 1..12.
X.sp
X.I day
Xis a number from 1..31.
X.sp
XFor example, the command
X.nf
X
X hebcal 10 1992
X
X.fi
Xwill print out the holidays occurring in October of 1992.
X.PP
XA few other bells and whistles include the weekly
X.I sedra
Xas well as the day of the week, the count of the
X.I omer,
Xand the Hebrew date.
X.PP
XOutput from hebcal can be used to drive calendar(1).
XDay\-to\-day use for hebcal is provided for in the
X.B -T
X and
X.B -t
Xswitches, which print out Jewish calendar entries for the current date.
X.PP
X.SH OPTIONS
X.TP 1.0i
X.B " -d"
XAdd the Hebrew date to the output.
X.TP
X.B " -e"
XChange the output format to European\-style dates: dd.mm.yyyy
X.TP
X.B " -h"
XSuppress holidays in output. User defined calendar events are
Xunaffected by this switch.
X.TP
X.B " -i "
XRead extra events from specified file. These events are printed
Xregardless of the
X.B -h
Xsuppress holidays switch.
X.br
XThere is one holiday per line in
X.I file,
Xeach with the format
X.br
X.I month day description
X.br
Xwhere
X.I month
Xis a number from 1 to 12,
X.I day
Xis a number from 1 to 30, and
X.I description
Xis a newline-terminated string describing the holiday.
X.br
XHere is the list of Hebrew months and their code numbers:
X.br
X1 Tishrei
X.br
X2 Cheshvan
X.br
X3 Kislev
X.br
X4 Tevet
X.br
X5 Shvat
X.br
X6 Adar (Adar II on leap years)
X.br
X6a Adar (Adar I on leap years)
X.br
X6b same as 6
X.br
X7 Nisan
X.br
X8 Iyyar
X.br
X9 Sivan
X.br
X10 Tamuz
X.br
X11 Av
X.br
X12 Elul
X.br
XPlease note the special option associated with Adar. If a birthday
Xoccurs in Adar of a non-leap year, It ought to get the 6a month
Xcode. Only people born on leap years in Adar II should have their
Xbirthdays on 6b.
X.br
X.br
XA similar but opposite rule applies to
X.I yahrtzeits.
XIf a person died in Adar of a non-leap year, the
X.I yahrtzeit
Xlands in Adar II of a leap year, so the event gets the 6b (or 6) month
Xcode. Only people who died on leap years in Adar II should have their
X.I yahrtzeits
Xon 6a.
X.TP
X.B " -o"
XAdd the count of the
X.I omer
Xto the output.
X.TP
X.B " -s"
XAdd the weekly
X.I sedra
Xto the output on Saturdays.
X.TP
X.B " -S"
XAdd the weekly
X.I sedra
Xto the output every day.
X.TP
X.B " -t"
XPrint calendar information for today's date only. -d is
Xasserted with this option.
X.TP
X.B " -T"
XSame as -t, only without the gregorian date. This option is useful in
Xlogin scripts, just to see what's happening today in the Jewish calendar.
X.TP
X.B " -w"
XAdd the day of the week to the output.
X.SH EXAMPLES
X.LP
XTo find the days of the
X.I omer
Xin 1997, printing the days of the week:
X.RS
X.nf
X.ft B
Xexample% hebcal -how 1997
X.br
X4/23/97 Wed, 1st day of the Omer
X.br
X4/24/97 Thu, 2nd day of the Omer
X.br
X4/25/97 Fri, 3rd day of the Omer
X.br
X .
X.br
X .
X.br
X .
X.br
X6/9/97 Mon, 48th day of the Omer
X.br
X6/10/97 Tue, 49th day of the Omer
X.RE
X.LP
XTo just print the weekly
X.I sedrot
Xof December 2000
X.RS
X.nf
X.ft B
Xexample% hebcal -hp 12 2000
X.br
X12/2/00 Parshat Toldot
X.br
X12/9/00 Parshat Vayetzei
X.br
X12/16/00 Parshat Vayishlach
X.br
X12/23/00 Parshat Vayeshev
X.br
X12/30/00 Parshat Miketz
X.br
X.RE
X.LP
XTo find out what's happening in the Jewish calendar today , use
X.RS
X.nf
X.ft B
Xexample% hebcal -ToS
X.br
X19 of Nisan, 5752
X.br
XParshat Achrei Mot
X.br
XPesach V (CH"M)
X.br
X4th day of the Omer
X.br
X.RE
X.SH AUTHOR
XDanny Sadinoff, University of Pennsylvania
X.SH SEE ALSO
Xcalendar(1), hcal(1), hdate(1), omer(1), rise(1)
X.sp
XThe motivation for the algorithms in this program is the
X.I "Tur Shulchan Aruch. "
XA well written treatment of the Jewish calendar is given in
X.I Understanding the Jewish Calendar
Xby Rabbi Nathan Bushwick. A more complete bibliography on the topic
Xcan be found there.
X.SH BUGS
XHebcal performs no checking for changes between the julian and
Xgregorian calendar, so secular dates before 1752 are untrustworthy.
X.sp
XHebcal cannot currently handle date computations before 2 C.E. sorry.
X.SH BUG REPORTS TO
XDanny Sadinoff sadinoff@eniac.seas.upenn.edu
END_OF_FILE
if test 4582 -ne `wc -c <'hebcal.1'`; then
echo shar: \"'hebcal.1'\" unpacked with wrong size!
fi
# end of 'hebcal.1'
fi
if test -f 'hebcal.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'hebcal.c'\"
else
echo shar: Extracting \"'hebcal.c'\" \(20368 characters\)
sed "s/^X//" >'hebcal.c' <<'END_OF_FILE'
X#include "hebcal.h"
X#include "danlib.h"
X#include <string.h>
X
X
X /* hebcal.c main module for hebrew calendar program
X By Danny Sadinoff
X (C) 1992
X
X $Date: 93/02/12 16:22:16 $
X $Revision: 2.0 $
X
X */
X
X
X int sedrot_sw, hebDates_sw, euroDates_sw, specMonth_sw,specDay_sw,
X inputFile_sw, weekday_sw, suppressHolidays_sw, suppressGreg_sw,
X printOmer_sw, sedraAllWeek_sw, omer;
X
XFILE *inFile;
X
Xholstorep_t holidays[13][MAXDAYS],union_Adar[MAXDAYS];
X
Xyear_t legend[2][8] = {
X { /* stam years */
X {"1BX",353,29,29,1,1,1,1,0,1,1}, /* BX */
X {"1BS",355,30,30,1,1,1,1,1,1,1}, /* BS */
X {"2GC",354,29,30,1,1,1,1,1,1,1}, /* GC */
X {"4HC",354,29,30,1,1,1,1,0,1,0}, /* HC */
X {"0error - HX",354,29,29,1,1,1,1,0,1,0}, /* error! hx */
X {"4HS",355,30,30,0,1,1,1,0,1,0}, /* HS */
X {"6ZX",353,29,29,1,1,1,1,0,1,0}, /* ZX */
X {"6ZS",355,30,30,1,1,1,1,0,1,1}, /* ZS */
X },
X { /* leap years */
X {"1BX",383,29,29,0,0,0,0,1,1,1}, /* BX */
X {"1BS",385,30,30,0,0,0,0,0,1,0}, /* BS */
X {"2GC",384,29,30,0,0,0,0,0,1,0}, /* GC */
X {"0error - HC",383,29,30,0,0,0,0,0,0,0}, /* error ! hc */
X {"4HX",383,29,29,0,0,0,0,0,0,0}, /* HX */
X {"4HS",385,30,30,0,0,0,0,0,0,1}, /* HS */
X {"6ZX",383,29,29,0,0,0,0,0,1,1}, /* ZX */
X {"6ZS",385,30,30,0,0,0,0,1,1,1}, /* ZS */
X }
X};
X
Xint leapYears[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
X/*enum {BX,BS,GC,HC,HX,HS,ZX,ZS}; */
X#define BX 0
X#define BS 1
X#define GC 2
X#define HC 3
X#define HX 4
X#define HS 5
X#define ZX 6
X#define ZS 7
X
Xint luach[][19] =
X{
X {HC,BX,HS,HC,BS,ZX,HC,BS,BX,HS,GC,BS,ZX,GC,BS,ZS,HX,GC,ZS},
X {ZS,HC,BX,ZS,HC,BX,ZS,HS,HC,BX,HS,HC,BS,ZX,HC,BS,ZX,HS,GC},
X {BS,ZX,GC,BS,ZS,HX,GC,ZS,ZS,HC,BX,ZS,HC,BS,BX,HC,BS,BS,ZX},
X {HC,HS,ZX,HC,HS,ZS,ZX,GC,BS,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BX},
X {ZS,HC,BS,BX,HC,BS,BS,ZX,HC,BS,ZX,HS,GC,ZS,ZS,HC,BX,ZS,HX},
X {GC,ZS,HS,HC,BX,HS,HC,BX,ZS,HC,BS,BX,HS,GC,BS,ZX,GC,BS,ZS},
X {ZX,GC,ZS,ZS,HC,BX,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BS,ZX,HC,BS},
X {BS,ZX,GC,BS,ZS,HX,GC,ZS,ZX,GC,ZS,ZS,HC,BX,ZS,HC,BS,BX,HS},
X {HC,BS,ZX,HC,BS,ZX,HS,GC,BS,ZX,GC,BS,ZS,HX,GC,ZS,HS,HC,BX},
X {ZS,HC,BX,ZS,HC,BS,BX,HS,HC,BS,ZX,HC,BS,ZX,HS,GC,ZS,ZX,GC},
X {BS,ZS,HX,GC,ZS,HS,HC,BX,ZS,HC,BX,ZS,HC,BS,BX,HS,GC,BS,ZX}, /* 10,11 GX? */
X {HC,BS,ZS,ZX,GC,ZS,ZS,HX,GC,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BS},
X {BX,HC,BS,BS,ZX,GC,BS,ZX,HS,GC,ZS,ZS,HC,BX,ZS,HC,BX,ZS,HS}
X};
X
Xstruct {
X char * name;
X int length;
X}hMonths[][14] = {
X {
X {"Tishrei",30}, {"Cheshvan",29}, {"Kislev",30},
X {"Tevet",29}, {"Shvat",30}, {"Adar",29},
X {"Nisan",30}, {"Iyyar",29}, {"Sivan",30},
X {"Tamuz",29}, {"Av",30},{"Elul",29},{"Tishrei",30}},
X {
X {"Tishrei",30}, {"Cheshvan",29}, {"Kislev",30},
X {"Tevet",29}, {"Shvat",30}, {"Adar I",29}, {"Adar II",30},
X {"Nisan",30}, {"Iyyar",29}, {"Sivan",30},
X {"Tamuz",29}, {"Av",30},{"Elul",29},{"Tishrei",30}}
X};
X
X#define TISHREI 0
X#define CHESHVAN 1
X#define KISLEV 2
X#define ADAR_2 6
X
Xchar * sedrot[] = {
X "Bereshit", "Noach", "Lech Lecha", "Vayera", "Chayei Sara",
X "Toldot", "Vayetzei", "Vayishlach", "Vayeshev", "Miketz", "Vayigash",
X "Vayechi",
X
X "Sh'mot", "Vaera", "Bo", "Beshalach", "Yitro", "Mishpatim",
X "Terumah", "Tetzaveh", "Ki Tisa", "Vayakhel", "Pekudei",
X
X "Vayikra", "Tzav", "Shmini", "Tazria", "Metzora", "Achrei Mot",
X "Kedoshim", "Emor", "Behar", "Bechukosai",
X
X "Bamidbar", "Nasso", "Beha'aloscha", "Sh'lach", "Korach", "Chukat",
X "Balak", "Pinchas", "Matot", "Masei",
X
X "Devarim", "Vaetchanan", "Eikev", "Re'eh", "Shoftim",
X "Ki Teitzei", "Ki Tavo", "Nitzavim", "Vayeilech", "Ha'Azinu",
X "V'Zot Habracha"
X };
X
X#define VAYAKHEL 21
X#define TAZRIA 26
X#define ACHREI 28
X#define BEHAR 31
X#define CHUKAT 38
X#define MATOT 41
X#define NITZAVIM 50
X
X#define NM_LEN 30
X
X#define OWNSEDRA 1
X#define NIDCHE 2
X#define MUKDAM 4
X#define MUKDAM2 8
X#define SKIP_NORMAL_ADAR 16
X#define USER_EVENT 32
X
Xholinput_t inp_holidays[] = { /* 5 = Adar I */
X /* 6 = Adar = Adar II */
X {{0,1},"Rosh Hashana I",OWNSEDRA},{{0,2},"Rosh Hashana II",OWNSEDRA},
X {{0,3},"Tzom Gedalia",NIDCHE},
X {{0,9},"Erev Yom Kippur"},
X {{0,10},"Yom Kippur",OWNSEDRA},
X
X {{0,15},"Sukkot I",OWNSEDRA},{{0,16},"Sukkot II",OWNSEDRA},
X {{0,17},"Sukkot III (CH\"M)",OWNSEDRA},{{0,18},"Sukkot IV (CH\"M)",OWNSEDRA},
X {{0,19},"Sukkot V (CH\"M)",OWNSEDRA},{{0,20},"Sukkot VI (CH\"M)",OWNSEDRA},
X {{0,21},"Sukkot VII (Hoshana Raba)",OWNSEDRA},
X {{0,22},"Shmini Atzeret",OWNSEDRA},{{0,23},"Simchat Torah",OWNSEDRA},
X
X {{2,25},"Chanukah I"},
X {{2,26},"Chanukah II"},{{2,27},"Chanukah III"},{{2,28},"Chanukah IV"},
X {{3,10},"Asara B'Tevet",NIDCHE},
X
X {{4,15},"Tu B'Shvat"} /*NIDCHE?*/,
X
X {{5,15},"Purim katan",SKIP_NORMAL_ADAR},
X {{6,13},"Ta'anit Esther",MUKDAM},{{6,14},"Purim"},
X {{6,15},"Shushan Purim"},
X
X {{7,14},"Erev Pesach - Taanit B'chorot",0},
X#define PESACH2_STR "Pesach II"
X {{7,15},"Pesach I",OWNSEDRA},{{7,16},PESACH2_STR,OWNSEDRA},
X {{7,17},"Pesach III (CH\"M)",OWNSEDRA},{{7,18},"Pesach IV (CH\"M)",OWNSEDRA},
X {{7,19},"Pesach V (CH\"M)",OWNSEDRA},{{7,20},"Pesach VI (CH\"M)",OWNSEDRA},
X {{7,21},"Pesach VII",OWNSEDRA},
X {{7,22},"Pesach VIII",OWNSEDRA},
X
X {{7,27},"Yom HaShoah"},
X {{8,4},"Yom HaZikaron",MUKDAM2},
X {{8,5},"Yom Ha'atzmaut",MUKDAM},
X {{8,28},"Yom Yerushalayim",MUKDAM}, /* not certain about mukdam status of the yoms */
X#define SHAVUOT_STR "Shavuot I"
X {{9,6},SHAVUOT_STR,OWNSEDRA},{{9,7},"Shavuot II",OWNSEDRA},
X {{10,17},"Shiva Assar B'Tamuz",NIDCHE},
X {{11,9},"Tish'a B'Av",NIDCHE},
X {{12,29},"Erev Rosh Hashana"}
X};
X
Xholstore_t chanukah_arr[5] =
X{
X {""},
X {"Chanukah V"},
X {"Chanukah VI"},
X {"Chanukah VII"},
X {"Chanukah VIII"}
X};
X
X#define SIMCHAT_DAY 23
X
X/* = {
X {{0,0},"Shabbat Shekalim"},
X {{0,0},"Shabbat Zachor"},
X {{0,0},"Parshat HaChodesh"},
X {{0,0},"Parshat Parah"},
X
X };*/
X
X
X#define LEAP_YR_HEB(x) (leapYears[((x) -1) % 19])
X#define MONTHS_IN_HEB(x) (LEAP_YR_HEB(x) ? 13 :12)
X
Xyear_t yearData(yr)
X int yr;
X{
X return legend[LEAP_YR_HEB(yr)][luach[((yr-1)/19+7)%13][(yr-1) %19]];
X}
X
Xint daysInHebMonth(month, year)
X int month, year;
X{
X year_t theYear;
X
X theYear = yearData(year);
X if (month == CHESHVAN)
X return theYear.daysInCheshvan;
X else if (month == KISLEV)
X return theYear.daysInKislev;
X else return hMonths[LEAP_YR_HEB(year)][month].length;
X}
X
Xdate_t nextHebDate (dth)
X date_t dth;
X{
X dth.dd++;
X if (dth.dd > daysInHebMonth(dth.mm,dth.yy))
X if (dth.mm == MONTHS_IN_HEB(dth.yy)-1)
X {
X dth.yy++;
X dth.mm =0;
X dth.dd =1;
X }
X else
X {
X dth.mm++;
X dth.dd =1;
X }
X return dth;
X}
X
Xdate_t prevHebDate (dth)
X date_t dth;
X{
X dth.dd--;
X if (dth.dd == 0)
X if (dth.mm == 0)
X {
X dth.yy--;
X dth.mm = MONTHS_IN_HEB(dth.yy) -1 ;
X dth.dd = daysInHebMonth(dth.mm,dth.yy);
X }
X else
X {
X dth.mm--;
X dth.dd = daysInHebMonth(dth.mm,dth.yy);
X }
X return dth;
X}
X
Xholstorep_t getHolstorep (s) /* return a pointer to a new */
Xchar *s; /* holiday */
X{
X holstorep_t tmp;
X if (!(tmp = (holstorep_t)malloc ( (size_t) sizeof (holstore_t))))
X die("Unable to allocate memory for holiday. Called from %s",s);
X tmp->next = NULL;
X tmp->name = NULL;
X tmp->typeMask = 0;
X return tmp;
X}
X
Xint PushHoliday (hp,lp) /*pushes a copy of a holiday on to a holiday list */
X holstorep_t
X hp, /* the holiday to be added */
X *lp; /* pointer to the list to be added to.*/
X{
X holstorep_t temp;
X
X temp = getHolstorep("PushHoliday");
X initStr(&temp->name,MAX_LINE_LEN);
X strcpy(temp->name,hp->name);
X temp->typeMask = hp->typeMask;
X
X if (!*lp)
X /* if there are no holidays here yet, start a new bucket*/
X *lp = temp;
X else
X {
X temp->next = *lp; /* put hp at the head of the list */
X *lp = temp;
X }
X return temp->typeMask;
X}
X
X
Xvoid InitHolidays(roshDt) /* set up the stored holidays array */
X date_t roshDt;
X{
X
X int d,m;
X holstorep_t tmpholp;
X holinputp_t todayinp;
X
X for (m = 0; m<= 12; m++) /* clear holidays buckets */
X for (d = 0; d < MAXDAYS; d++)
X holidays[m][d] = NULL;
X
X for (m = 0,todayinp = inp_holidays; /* load holiday buckets */
X m < LAST_INDEX(inp_holidays);
X m++, todayinp++)
X {
X tmpholp = getHolstorep("InitHolidays"); /* allocate hsnode*/
X tmpholp->typeMask = todayinp->typeMask; /* load the new holiday into it. */
X tmpholp->name = todayinp->name;
X PushHoliday(tmpholp,&holidays[todayinp->date.mm][todayinp->date.dd]);
X if ((todayinp->date.mm == 5 || todayinp->date.mm == 6) &&
X !(tmpholp->typeMask & SKIP_NORMAL_ADAR))
X PushHoliday(tmpholp,&union_Adar[todayinp->date.dd]);
X }
X
X if (inputFile_sw) /* get user-defined "holidays" */
X {
X char *s,*monthStr,*adarp,*eventStr,nextChar;
X int index,hYear,inMonth,inDay,lineNum = 1;
X
X
X hYear = JUL2HEB(roshDt.yy)+1;
X initStr(&s,MAX_LINE_LEN);
X initStr(&monthStr,MAX_LINE_LEN);
X nextChar = (char) getc(inFile); /* priming getc */
X while (!feof(inFile))
X {
X ungetc(nextChar,inFile);
X if (!fgets(s,MAX_LINE_LEN,inFile))
X die ("input file read error at line number %s.\n",itoa(lineNum));
X
X if (!sscanf(s,"%s %d%n",monthStr,&inDay,&index))
X die ("Error in input file at line %s\n",itoa(lineNum));
X
X if (isAllNums(monthStr) && (inMonth = atoi(monthStr)) < 6)
X inMonth--;
X else if (adarp = strchr(monthStr,'a'))
X {
X *adarp = '\0'; /* terminate the string at the 'a' */
X if (isAllNums(monthStr))
X inMonth = atoi(monthStr)-1;
X else die ("Error in input file at line %s\n",itoa(lineNum));
X }
X else if (adarp = strchr(monthStr,'b'))
X { /* this case puts the event in month 6 = Adar II*/
X *adarp = '\0';
X if (isAllNums(monthStr))
X inMonth = atoi(monthStr); /* note no decrement */
X else die ("Error in input file at line %s\n",itoa(lineNum));
X }
X
X if (inMonth >12 || inMonth <0)
X die ("Month out of range in input file at line %s\n",itoa(lineNum));
X
X if(inDay <0 || inDay >30)
X die ("Date out of range in input file at line %s\n",itoa(lineNum));
X
X#if 0
X if ((inMonth == 5) && !LEAP_YR_HEB(hYear))
X warn("Warning:user event scheduled on Adar I in nonleap year. line %s\n",
X itoa(lineNum));
X#endif
X if (inDay > daysInHebMonth(inMonth,hYear))
X warn("Warning:user event scheduled on date not appearing this year. line %s\n",
X itoa(lineNum));
X
X eventStr = s +index +1; /* get the name of the event */
X eventStr[strlen(eventStr)-1] = '\0'; /* chop off the \n */
X
X /* store the holiday in the LUT */
X tmpholp = getHolstorep("InitHolidays:inputFile");
X initStr(&tmpholp->name,MAX_LINE_LEN);
X strcpy(tmpholp->name,eventStr); /* load the user holiday into it. */
X tmpholp->typeMask = USER_EVENT;
X PushHoliday(tmpholp,&holidays[inMonth][inDay]);
X if (inMonth == 5 || inMonth == 6)
X PushHoliday(tmpholp,&union_Adar[inDay]);
X
X lineNum++;
X nextChar = (char) getc(inFile); /* force an EOF */
X }
X }
X}
X
X
X
Xvoid getHebHolidays (dth,weekday, holiList)
X /* returns a linked list of holidays for that date*/
X date_t dth;
X int weekday;
X holstorep_t *holiList; /* the typeMask on the first element of */
X /* the returned list must reflect */
X /* the union of all component masks */
X{
X char * funName = "getHebHolidays";
X int tmpMask;
X holstorep_t tmpholip, chp;
X static holstorep_t todayp, yesterp, morrowp, morrow2p;
X static int chanukah_day,first;
X
X#define CORRECTION(yy,mm) (LEAP_YR_HEB(yy) ? 0 : (((mm) > 4) ? 1: 0))
X
X if (first)
X {
X todayp = holidays[dth.mm][dth.dd];
X yesterp = holidays[prevHebDate(dth).mm][prevHebDate(dth).dd];
X morrowp = holidays[nextHebDate(dth).mm][nextHebDate(dth).dd];
X morrow2p = holidays[nextHebDate(nextHebDate(dth)).mm]
X [nextHebDate(nextHebDate(dth)).dd];
X first = 0;
X }
X else
X {
X date_t morrow2dt;
X
X morrow2dt = nextHebDate(nextHebDate(dth));
X yesterp = todayp;
X todayp = morrowp;
X morrowp = morrow2p;
X if (!LEAP_YR_HEB(dth.yy) && morrow2dt.mm == 5)
X morrow2p = union_Adar[morrow2dt.dd];
X else
X morrow2p = holidays[morrow2dt.mm +CORRECTION(dth.yy,morrow2dt.mm)]
X [morrow2dt.dd];
X }
X
X tmpMask =0;
X *holiList = NULL;
X
X for (chp = todayp; chp; chp = chp->next)
X {
X /* for normal holidays */
X if (!(weekday == SAT && chp->typeMask & NIDCHE) &&
X !(chp->typeMask & MUKDAM &&
X (weekday == FRI || weekday == SAT)) &&
X !(chp->typeMask & MUKDAM2 &&
X (weekday == THU || weekday == FRI)))
X { /* do normal holidays*/
X tmpMask |= PushHoliday(chp,holiList);
X if (!strcmp(chp->name,PESACH2_STR)) omer++;
X if (omer && !strcmp(chp->name,SHAVUOT_STR)) omer=0;
X }
X }
X
X if (weekday == SUN && yesterp) /* fast days which are nidche */
X for (chp = yesterp; chp; chp = chp->next)
X if (chp->typeMask & NIDCHE)
X {
X char *st;
X
X initStr(&st,NM_LEN);
X strncat(st,chp->name,NM_LEN);
X strncat(st," [nidche]",NM_LEN);
X tmpMask |= PushHoliday(chp,holiList);
X (*holiList)->name = st;
X }
X
X /* if the date actually falls */
X /* on friday or shabbat*/
X if (weekday == THU)
X {
X for (chp = morrowp; chp; chp = chp->next)
X if (chp->typeMask & MUKDAM)
X tmpMask |= PushHoliday(chp,holiList);
X for (chp = morrow2p; chp; chp = chp->next)
X if (chp->typeMask & MUKDAM)
X tmpMask |= PushHoliday(chp,holiList);
X }
X
X /* if the date actually falls */
X /* on thursday or friday*/
X if (weekday == WED)
X {
X for (chp = morrowp; chp; chp = chp->next)
X if (chp->typeMask & MUKDAM2)
X tmpMask |= PushHoliday(chp,holiList);
X for (chp = morrow2p; chp; chp = chp->next)
X if (chp->typeMask & MUKDAM2)
X tmpMask |= PushHoliday(chp,holiList);
X }
X
X /* Lag B'Omer Processing */
X if (omer == 33) {
X tmpholip = getHolstorep(funName);
X initStr(&tmpholip->name,NM_LEN);
X strncpy(tmpholip->name,"Lag B'Omer",NM_LEN);
X tmpMask |= PushHoliday(tmpholip,holiList);
X }
X
X if (dth.dd == 29 && dth.mm == 2)
X chanukah_day = 1;
X
X if (chanukah_day) {
X tmpMask |= PushHoliday(&chanukah_arr[chanukah_day],holiList);
X if (chanukah_day == 4)
X chanukah_day = 0;
X else chanukah_day++;
X }
X
X
X /* rosh Chodesh Processing... */
X if (dth.dd == 1 && dth.mm){ /* every 1st of the month except tishrei */
X tmpholip = getHolstorep(funName);
X initStr(&tmpholip->name,NM_LEN);
X strcat(tmpholip->name,"Rosh Chodesh ");
X strncat(tmpholip->name,hMonths[LEAP_YR_HEB(dth.yy)][dth.mm].name,NM_LEN);
X tmpMask |= PushHoliday(tmpholip,holiList);
X }
X if (dth.dd == 30){
X tmpholip = getHolstorep(funName);
X initStr(&tmpholip->name,NM_LEN);
X strcat(tmpholip->name,"Rosh Chodesh ");
X strncat(tmpholip->name,hMonths[LEAP_YR_HEB(dth.yy)][dth.mm+1].name,NM_LEN);
X tmpMask |= PushHoliday(tmpholip,holiList);
X }
X
X if (*holiList) (*holiList)->typeMask = tmpMask;
X
X}
X
Xvoid incHebJulDate(dth,dtj,wkday)
X date_t *dth, *dtj;
X int *wkday;
X{
X /* increments both hebrew and julian calendars */
X
X incDate (dtj,1);
X *wkday = dayOfWeek(*dtj);
X *dth = nextHebDate(*dth);
X}
X
Xvoid PrintWeekday (dt)
X date_t dt;
X{
X printf ("%s, ",ShortDayNames[dayOfWeek(dt)]);
X}
X
Xvoid PrintJulDate (dt)
X date_t dt;
X{
X if (!suppressGreg_sw)
X if (euroDates_sw)
X printf ("%d.%d.%d ",dt.dd,dt.mm+1,dt.yy);
X else
X printf ("%d/%d/%d ",dt.mm+1,dt.dd,dt.yy);
X
X if (weekday_sw)
X PrintWeekday(dt);
X}
X
X
Xchar *DoSedra (sedra, ydat,increment) /* returns a string "Parshat <parsha>" */
X int *sedra,increment; /* based on the current parsha number */
X year_t ydat;
X{
X#define PLENGTH 40
X static char s[PLENGTH+1];
X
X if (increment) increment = 1;
X *s = '\0';
X strncat(s,"Parshat ",PLENGTH);
X strncat(s,sedrot[*sedra],PLENGTH);
X switch (*sedra) {
X case VAYAKHEL :
X if (ydat.vayakhelPikudei){
X strncat(s,"-",PLENGTH);
X strncat(s,sedrot[*sedra+1],PLENGTH);
X *sedra += 2*increment;
X }
X else *sedra += 1*increment;
X break;
X case TAZRIA:
X if (ydat.tazriaMetzorah){
X strncat(s,"-",PLENGTH);
X strncat(s,sedrot[*sedra+1],PLENGTH);
X *sedra += 2*increment;
X }
X else *sedra += 1*increment;
X break;
X case ACHREI :
X if (ydat.achreiKedoshim){
X strncat(s,"-",PLENGTH);
X strncat(s,sedrot[*sedra+1],PLENGTH);
X *sedra += 2*increment;
X }
X else *sedra += 1*increment;
X break;
X case BEHAR :
X if (ydat.beharBech){
X strncat(s,"-",PLENGTH);
X strncat(s,sedrot[*sedra+1],PLENGTH);
X *sedra += 2*increment;
X }
X else *sedra += 1*increment;
X break;
X case CHUKAT :
X if (ydat.chukatBalak){
X strncat(s,"-",PLENGTH);
X strncat(s,sedrot[*sedra+1],PLENGTH);
X *sedra += 2*increment;
X }
X else *sedra += 1*increment;
X break;
X case MATOT :
X if (ydat.matotMasei){
X strncat(s,"-",PLENGTH);
X strncat(s,sedrot[*sedra+1],PLENGTH);
X *sedra += 2*increment;
X }
X else *sedra += 1*increment;
X break;
X case NITZAVIM :
X if (ydat.nitzavimVayelech){
X strncat(s,"-",PLENGTH);
X strncat(s,sedrot[*sedra+1],PLENGTH);
X *sedra += 2*increment;
X }
X else *sedra += 1*increment;
X break;
X case LAST_INDEX(sedrot)-1:
X *sedra = 0;
X break;
X default:
X *sedra += 1*increment;
X }
X strncat(s,"\n",PLENGTH);
X return s;
X}
X
Xvoid DoCalendar (roshDt,justMonth,justDay)
X date_t roshDt; /* rosh Hashana of preceeding year */
X int justMonth, /* print this month */
X justDay; /* print this day */
X{
X int sedra,weekday;
X date_t todayj, todayh;
X holstorep_t holip; /* a list of holidays for today */
X year_t theYear;
X todayj = roshDt;
X
X todayh.mm = 0;
X todayh.dd = 1;
X todayh.yy = JUL2HEB(roshDt.yy) + 1; /* because it's after R"H */
X
X
X theYear = yearData(todayh.yy);
X
X if (CHAR2NUM(theYear.name[0]) != dayOfWeek(roshDt))
X die ("Bad Day!\n","");
X
X /* first scan forward to simchat Torah, keeping track of dates only. */
X while (todayh.dd != SIMCHAT_DAY)
X incHebJulDate(&todayh, &todayj,&weekday);
X
X sedra = 0; /* initialize sedra */
X
X /* then continue until january 1st. */
X do
X {
X getHebHolidays(todayh,weekday,&holip);
X if (weekday == SAT && !(holip && holip->typeMask & OWNSEDRA))
X DoSedra(&sedra,theYear,1);
X incHebJulDate(&todayh,&todayj,&weekday);
X } while (!(todayj.mm==0 && todayj.dd==1));
X
X /* -------Main Year Loop-------*/
X do {
X if (hebDates_sw &&
X (!specMonth_sw || (justMonth== todayj.mm)) &&
X (!specDay_sw || (justDay == todayj.dd)))
X {
X PrintJulDate(todayj);
X printf ("%d%s of %s, %d\n",todayh.dd, /* print the hebrew date */
X numSuffix(todayh.dd),
X hMonths[LEAP_YR_HEB(todayh.yy)][todayh.mm].name,
X todayh.yy);
X }
X getHebHolidays(todayh,weekday,&holip);
X
X if (todayh.mm == TISHREI && todayh.dd == 1)
X theYear = yearData(todayh.yy); /* if R"H reset YearData */
X
X
X
X if (sedraAllWeek_sw ||
X (sedrot_sw && weekday==SAT &&
X !(holip && holip->typeMask & OWNSEDRA)))
X {
X if ((!specMonth_sw || (justMonth == todayj.mm)) &&
X (!specDay_sw || (justDay == todayj.dd)))
X {
X PrintJulDate(todayj);
X printf("%s",DoSedra(&sedra,theYear,weekday==SAT &&
X !(holip && holip->typeMask & OWNSEDRA)));
X }
X else DoSedra(&sedra,theYear,weekday==SAT &&
X !(holip && holip->typeMask & OWNSEDRA));
X }
X
X
X if (sedrot_sw &&
X todayh.mm == TISHREI && /* reset the sedra on simchat torah */
X todayh.dd == SIMCHAT_DAY)
X sedra =0;
X
X if ((!specMonth_sw || (justMonth == todayj.mm)) &&
X (!specDay_sw || (justDay == todayj.dd)))
X for (;holip;holip = holip->next)
X if (!suppressHolidays_sw || (holip->typeMask & USER_EVENT))
X {
X PrintJulDate(todayj);
X printf ("%s\n",holip->name);
X }
X
X /* print the omer if desired */
X if (omer && printOmer_sw &&
X (!specMonth_sw || (justMonth == todayj.mm)) &&
X (!specDay_sw || (justDay == todayj.dd)))
X {
X char *omerStr;
X initStr(&omerStr,NM_LEN);
X strncat(omerStr,itoa(omer),NM_LEN);
X strncat(omerStr,numSuffix(omer),NM_LEN);
X strncat(omerStr," day of the Omer",NM_LEN);
X PrintJulDate(todayj);
X printf ("%s\n",omerStr);
X }
X if (omer) omer++;
X
X incHebJulDate(&todayh,&todayj,&weekday);
X } while (!(specMonth_sw && todayj.mm > justMonth) &&
X (todayj.mm!=0 || todayj.dd!=1)); /* continue to january 1st */
X}
END_OF_FILE
if test 20368 -ne `wc -c <'hebcal.c'`; then
echo shar: \"'hebcal.c'\" unpacked with wrong size!
fi
# end of 'hebcal.c'
fi
if test -f 'hebcal.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'hebcal.h'\"
else
echo shar: Extracting \"'hebcal.h'\" \(746 characters\)
sed "s/^X//" >'hebcal.h' <<'END_OF_FILE'
X#ifndef __HEBCAL__
X#define __HEBCAL__
X#include <stdio.h>
X#include "greg.h"
X#include "error.h"
X#define MAXDAYS 31
X#define JUL2HEB(x) ((x)+ 3760)
X#define MAX_LINE_LEN 100
X
Xtypedef struct {
X
X char * name;
X int length;
X
X int daysInCheshvan;
X int daysInKislev;
X
X int vayakhelPikudei; /* double parsha flags */
X int tazriaMetzorah;
X int achreiKedoshim;
X int beharBech;
X int chukatBalak;
X int matotMasei;
X int nitzavimVayelech;
X
X} year_t;
X
Xtypedef struct hinode{
X date_t date;
X char *name;
X int typeMask;
X struct hinode *next;
X} holinput_t, *holinputp_t;
X
Xtypedef struct hsnode{
X char *name;
X int typeMask;
X struct hsnode *next;
X} holstore_t, *holstorep_t;
X
Xyear_t yearData();
Xvoid InitHolidays();
Xvoid DoCalendar ();
X
X#endif
END_OF_FILE
if test 746 -ne `wc -c <'hebcal.h'`; then
echo shar: \"'hebcal.h'\" unpacked with wrong size!
fi
# end of 'hebcal.h'
fi
if test -f 'start.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'start.c'\"
else
echo shar: Extracting \"'start.c'\" \(4960 characters\)
sed "s/^X//" >'start.c' <<'END_OF_FILE'
X#include <stdio.h>
X#include "hebcal.h"
X
Xextern int sedrot_sw, hebDates_sw, euroDates_sw, specMonth_sw,specDay_sw,
X inputFile_sw, weekday_sw, suppressHolidays_sw, suppressGreg_sw,
X printOmer_sw, sedraAllWeek_sw, omer;
X
Xextern FILE *inFile;
X
Xvoid RollBack(dtg,target) /* move rosh hashana dtj back until it's */
X date_t *dtg; /* in the year before target */
X int target;
X{
X int days,theyear;
X
X for (days = 0,theyear = dtg->yy ;theyear > target -1; theyear--)
X days +=yearData(JUL2HEB(theyear)).length;
X decDate (dtg,days);
X
X}
X
Xvoid RollForward(dtg,target) /* move rosh hashana dtg forward until it's*/
X date_t *dtg; /* in the year before target*/
X int target;
X{
X int days,theyear;
X
X for (days = 0,theyear = dtg->yy ;theyear < target -1; theyear++)
X days +=yearData(JUL2HEB(theyear+1)).length;
X incDate (dtg,days);
X
X}
X
Xstatic int theYear,theMonth,theDay,yearDirty;
X
Xvoid handleArgs(argc, argv)
X int argc;
X char *argv[];
X{
X char *c;
X date_t tempdt;
X
X char * usage = "usage: hebcal [-dehosStTw] [-i file] [[month [day]] year]\n hebcal help\n";
X
X setDate(&tempdt); /* do this year */
X theYear = tempdt.yy;
X
X for (argv++, argc--; argc; argv++, argc--)
X if (isAllNums(*argv))
X if ((argc-1) && isAllNums(*(argv+1)) && !yearDirty)
X if ((argc-2) && isAllNums(*(argv+2))) {
X specMonth_sw =1;
X specDay_sw =1;
X theMonth = atoi(*argv) -1; /* year and month specified */
X theDay = atoi(*++argv); /* print theDay of theMonth */
X theYear = atoi(*++argv); /* print theMonth of theYear */
X yearDirty =1;
X argc -=2;
X }
X else {
X specMonth_sw =1;
X theMonth = atoi(*argv) -1; /* year and month specified */
X theYear = atoi(*++argv); /* print theMonth of theYear */
X yearDirty =1;
X argc--;
X }
X else if (!yearDirty) {
X theYear = atoi(*argv); /* just year specified */
X yearDirty = 1; /* print whole year */
X }
X else die(usage,"");
X else if (**argv == '-')
X for (c = *argv,c++;*c;c++)
X switch (*c) {
X case 'd' : /* print hebrew dates */
X hebDates_sw = 1;
X break;
X case 'i' :
X inputFile_sw =1;
X if (!(inFile = fopen(*++argv,"r")))
X die("could not open input file %s.",*argv);
X argc--;
X break;
X case 'e':
X euroDates_sw =1;
X break;
X case 'h':
X suppressHolidays_sw =1;
X break;
X case 'o':
X printOmer_sw =1;
X break;
X case 's' : /* print sedrot */
X sedrot_sw = 1;
X break;
X case 'S': /* print sedra every day. */
X sedraAllWeek_sw =1;
X break;
X case 't': /* do hebcal for today. */
X specMonth_sw =1;
X specDay_sw =1;
X theMonth = tempdt.mm; /* year and month specified */
X theDay = tempdt.dd; /* print theDay of theMonth */
X yearDirty =1;
X break;
X case 'T': /* do hebcal for today, omit gregorian date. */
X suppressGreg_sw = 1;
X specMonth_sw =1;
X specDay_sw =1;
X theMonth = tempdt.mm; /* year and month specified */
X theDay = tempdt.dd; /* print theDay of theMonth */
X yearDirty =1;
X printOmer_sw =1;
X break;
X case 'w' : /* print days of the week */
X weekday_sw = 1;
X break;
X default: die(usage,"");
X }
X else if (!strcmp(*argv,"help")) {
X printf ("Hebcal Version 2.0\n\n");
X printf ("Hebcal prints out hebrew calendars one solar year at a time.\n");
X printf ("Given one numeric argument, it will print out the calendar \n");
X printf ("for that year. Given two numeric argumetnts mm yyyy, it\n");
X printf ("prints out the calendar for month mm of year yyyy. \n");
X printf (usage);
X printf ("\nOPTIONS:\n -d : add hebrew dates\n");
X printf (" -e : use european dates for OUTPUT ONLY (input format the same)\n");
X printf (" -h : suppress holidays\n");
X printf (" -i : get user events from specified file\n");
X printf (" -o : add days of the omer\n");
X printf (" -s : add weekly sedrot on Saturday\n");
X printf (" -S : print sedrah of the week on all calendar days\n");
X printf (" -t : only output for today's date\n");
X printf (" -T : print today's pertinent information, no gregorian date\n");
X printf (" -w : add day of the week\n\n");
X printf (" hebcal help --- prints this message\n");
X printf ("\nExample: \n");
X printf (" hebcal -ho\n");
X printf ("will just print out the days of the omer for the current year.\n");
X exit(0);
X }
X else die (usage,"");
X}
X
Xchar * progname;
X
Xint main (argc, argv)
X int argc;
X char *argv[];
X{
X date_t startDate;
X
X progname = argv[0];
X
X startDate.dd = 28;
X startDate.mm = SEP; /* any ol' rosh hashana */
X startDate.yy = 1992;
X
X handleArgs(argc,argv);
X
X if (specDay_sw) hebDates_sw = 1;
X
X if (theYear < startDate.yy +1) /* go to R"H of the year before */
X RollBack(&startDate,theYear);
X else if (theYear > startDate.yy +1) /* start from there */
X RollForward(&startDate,theYear);
X
X InitHolidays(startDate);
X DoCalendar(startDate,theMonth,theDay);
X
X return 0;
X}
END_OF_FILE
if test 4960 -ne `wc -c <'start.c'`; then
echo shar: \"'start.c'\" unpacked with wrong size!
fi
# end of 'start.c'
fi
echo shar: End of archive 1 \(of 1\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have the archive.
rm -f ark[1-9]isdone
else
echo You still must unpack the following archives:
echo " " ${MISSING}
fi
exit 0
exit 0 # Just in case...