home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume34 / hebcal / part01 next >
Encoding:
Text File  |  1993-01-18  |  42.7 KB  |  1,588 lines

  1. Newsgroups: comp.sources.misc
  2. From: sadinoff@unagi.cis.upenn.edu (Danny Sadinoff)
  3. Subject: v34i117:  hebcal - A Jewish calendar generator, Part01/01
  4. Message-ID: <1993Jan18.172015.10848@sparky.imd.sterling.com>
  5. X-Md4-Signature: feea80fc6683d1b8caacff1e44bf6875
  6. Date: Mon, 18 Jan 1993 17:20:15 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: sadinoff@unagi.cis.upenn.edu (Danny Sadinoff)
  10. Posting-number: Volume 34, Issue 117
  11. Archive-name: hebcal/part01
  12. Environment: UNIX
  13. Supersedes: hebcal-1.2: Volume 33, Issue 71
  14.  
  15.             [ THIS PROGRAM IS SHAREWARE  -Kent+ ]
  16.  
  17. Hebcal 1.3 - a program for printing Jewish calendars
  18.   by Danny Sadinoff
  19.  
  20. DESCRIPTION
  21. Hebcal is a program which prints out the days in the Jewish calendar
  22. for a given gregorian year.  Hebcal is fairly flexible in terms of which
  23. events in the Jewish calendar it displays.  Each of the following can
  24. be individualy turned on or off:
  25.  
  26.   The Hebrew date
  27.   Jewish Holdiays (including Yom Ha'atzmaut and Yom HaShoah etc.)
  28.   The weekly Sedrah
  29.   The day of the week
  30.   The days of the Omer
  31.  
  32. CHANGES 
  33.   Fixed a critical bug which put Purim on the 15th of Adar, instead of
  34.     the 14th
  35.   Now uses sys/types.h instead of stdlib.h.  This will improve compatability
  36.   Added the rest of the 8 days of Chanukah
  37.  
  38. DISTRIBUTION
  39. This program is SHAREWARE. 
  40. It may be distributed freely, with a few conditions:
  41.    1) The package must be distributed INTACT with ALL source code, as
  42.    well as this file.  You are welcome to modify the code,
  43.    but DON'T distribute it modified.  This disclaimer should certainly
  44.    appear with every distributed copy.
  45.    
  46.    2) You can use this program for free for one week.  After that
  47.    trial period, if you wish to use this program, drop me a line.
  48.    I'd like to know who you are, how you're using hebcal, and any
  49.    thing else you'd like to tell me.  
  50.  
  51.    I am NOT demanding payment for the use of my program, but writing
  52.    this program DID take time.  Feel free to send $10 to
  53.    me at my US Mail address. (hint)
  54.  
  55.    send US Mail to:        send email to:
  56.     Danny Sadinoff       sadinoff@eniac.seas.upenn.edu
  57.     1 Cove La. 
  58.     Great Neck, NY 11024
  59.  
  60.    Email respondents will receive notifications of new versions as they
  61.    come out, as will US Mail responents (if they send me postage for a disk).
  62.  
  63.    If you do not mail me or email me after one week, please don't
  64.    use the program, although you may feel free to distribute it further.
  65.  
  66. COMPILATION
  67. The code has K&R "old style" declarations in it, so it should compile
  68. on most machines.
  69.  
  70. The distribution includes a "Makefile" so once you've unpacked all the
  71. files, just run the command "make" and that should compile everything
  72. for you.
  73.  
  74. The file hebcal.l is the manual page.  For information on using man in
  75. conjunction with local manpages, see the manpage for man.  Briefly, to
  76. read a manpage in its original format, type 
  77. nroff -man <filename> | more
  78. --------------
  79. #! /bin/sh
  80. # This is a shell archive.  Remove anything before this line, then feed it
  81. # into a shell via "sh file" or similar.  To overwrite existing files,
  82. # type "sh file -c".
  83. # Contents:  README Makefile danlib.c danlib.h error.c error.h greg.c
  84. #   greg.h hebcal.c hebcal.l test.c
  85. # Wrapped by kent@sparky on Sun Jan 17 15:21:07 1993
  86. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  87. echo If this archive is complete, you will see the following message:
  88. echo '          "shar: End of archive 1 (of 1)."'
  89. if test -f 'README' -a "${1}" != "-c" ; then 
  90.   echo shar: Will not clobber existing file \"'README'\"
  91. else
  92.   echo shar: Extracting \"'README'\" \(5599 characters\)
  93.   sed "s/^X//" >'README' <<'END_OF_FILE'
  94. XHebcal 1.3 - a program for printing Jewish calendars
  95. X  by Danny Sadinoff
  96. X
  97. XDESCRIPTION
  98. XHebcal is a program which prints out the days in the Jewish calendar
  99. Xfor a given gregorian year.  Hebcal is fairly flexible in terms of which
  100. Xevents in the Jewish calendar it displays.  Each of the following can
  101. Xbe individualy turned on or off:
  102. X
  103. X  The Hebrew date
  104. X  Jewish Holdiays (including Yom Ha'atzmaut and Yom HaShoah etc.)
  105. X  The weekly Sedrah
  106. X  The day of the week
  107. X  The days of the Omer
  108. X
  109. XCHANGES 
  110. XSince version 1.1, the following changes were made:
  111. X  Changed usage-- the -p "parshiot" switch was changed to "-s" sedrot switch
  112. X  Fixed certain slippery variable type bugs
  113. X  Changed code to K&R old style
  114. X  Added Manpage
  115. X  Decided to change the "Distribu-Ware" to a normal shareware.
  116. X
  117. XSince version 1.2:
  118. X  Fixed a critical bug which put Purim on the 15th of Adar, instead of
  119. X    the 14th
  120. X  Now uses sys/types.h instead of stdlib.h
  121. X  Added the rest of the 8 days of Chanukah
  122. X
  123. X
  124. XDISTRIBUTION
  125. XThis program is SHAREWARE. 
  126. XIt may be distributed freely, with a few conditions:
  127. X   1) The package must be distributed INTACT with ALL source code, as
  128. X   well as this file.  You are welcome to modify the code,
  129. X   but DON'T distribute it modified.  This disclaimer should certainly
  130. X   appear with every distributed copy.
  131. X   
  132. X   2) You can use this program for free for one week.  After that
  133. X   trial period, if you wish to use this program, drop me a line.
  134. X   I'd like to know who you are, what version you're using, and how
  135. X   you're using hebcal, and anything else you'd like to tell me.  
  136. X
  137. X   I am NOT demanding payment for the use of my program, but writing
  138. X   this program DID take time.  Feel free to send $10 to
  139. X   me at my US Mail address. (hint)
  140. X
  141. X   send US Mail to:        send email to:
  142. X    Danny Sadinoff       sadinoff@eniac.seas.upenn.edu
  143. X    1 Cove La. 
  144. X    Great Neck, NY 11024
  145. X
  146. X   Email respondents will receive notifications of new versions as they
  147. X   come out, as will US Mail responents (if they send me postage for a disk).
  148. X
  149. X   If you do not mail me or email me after one week, please don't
  150. X   use the program, although you may feel free to distribute it further.
  151. X
  152. XCOMPILATION
  153. XThe code has K&R "old style" declarations in it, so it should compile
  154. Xon most machines.
  155. XThe distribution includes a "Makefile" so once you've unpacked all the
  156. Xfiles, (including this one) just run the command "make" and that
  157. Xshould compile everything for you.
  158. X
  159. XThe file hebcal.l is the manual page.  For information on using man in
  160. Xconjunction with local manpages, see the manpage for man.  Briefly, to
  161. Xread a manpage, type 
  162. Xnroff -man <filename> | more
  163. X
  164. X
  165. XOPERATION:
  166. XThe operation of hebcal is fairly simple.  Hebcal defaults to printing
  167. Xout the holidays for the current gregorian year.  With the
  168. Xcommand-line options, a specific gregorian year, month or date can be
  169. Xspecified.  
  170. X
  171. XGiven one numeric argument, hebcal will print out the calendar 
  172. Xfor that year.  Given two numeric argumetnts mm yyyy, it
  173. Xprints out the calendar for month mm of year yyyy.  Given three
  174. Xnumeric arguments mm dd yyyy, it will print out the hebrew calendar
  175. Xentries for day dd of month mm of year yyyy.  In the last case, the -d
  176. Xoption is automatically enabled.
  177. X
  178. XBe sure to give the whole year to hebcal.  
  179. Xhebcal 92 will return the calendar for a time somewhere in the early
  180. Xchristian era, not in the twentieth century.  Use hebcal 1992 instead.
  181. X
  182. Xusage: hebcal [-dehostTw] [[month [day]] year]  
  183. X       hebcal help --- prints this message. 
  184. X
  185. XOPTIONS:  
  186. X   -d : add hebrew dates
  187. X   -e : use European dates (dd mm yyyy) for OUTPUT ONLY (input format
  188. X        the same)
  189. X   -h : suppress holidays
  190. X   -o : add days of the omer
  191. X   -s : add weekly sedrot
  192. X   -t : only output today's date.  This switch implies the -d switch.
  193. X   -T : only output today's date, suppressing gregorian date. This
  194. X        switch implies the -d and -o switches.
  195. X   -w : add day of the week
  196. X
  197. X
  198. XExamples: 
  199. Xexample% hebcal -ho
  200. X4/19/1992 1st day of the Omer
  201. X4/20/1992 2nd day of the Omer
  202. X4/21/1992 3rd day of the Omer
  203. X4/22/1992 4th day of the Omer
  204. X4/23/1992 5th day of the Omer
  205. X4/24/1992 6th day of the Omer
  206. X.
  207. X.
  208. X6/5/1992 48th day of the Omer
  209. X6/6/1992 49th day of the Omer
  210. X
  211. Xto print out all of the data pertaining to today's date, use
  212. X
  213. Xexample% hebcal -otw
  214. X10/26/1992 Mon, 29 of Tishrei, 5753
  215. X
  216. Xto find out what's happening in today's Jewish calendar, use
  217. X
  218. Xexample% hebcal -T
  219. X19 of Nisan, 5752
  220. XPesach V (CH"M)
  221. X4th day of the Omer
  222. X
  223. X
  224. XDISCLAIMER
  225. XI tried to make this program as accurate as possible.  However, I
  226. Xtake no responsibility for any horrible consequences which may come
  227. Xabout as a result of faulty output from this program.  Remember: never
  228. Xtrust a program with a zero at the end of its revision number.
  229. X
  230. XThe secular dates before september 1752 are off by two weeks due to
  231. Xthe correction that took place then.
  232. X
  233. XThe secular dates before 1522 become progressively meaningless, as I
  234. Xmade no correction for the changeover from julian to gregorian
  235. Xcalendars; but the Hebrew dates and years are correct.
  236. X
  237. XCOMING SOON
  238. XFeatures to be included in future versions:
  239. X  - need to add Yom Yerushalayim
  240. X  - Arba' parshiot
  241. X  - The ability to specify and output a particular HEBREW year, month
  242. X    or date.   The absence of this feature is a serious drawback to
  243. X    hebcal as it now stands.
  244. X  - calendar-like operation with user specified "holidays", 
  245. X       e.g. birthdays, yahrtzeits.
  246. X  - yahrtzeit lists: calculate a list of dates in successive gregorian
  247. X       years with the same Hebrew date.
  248. X
  249. X
  250. XGRIPES
  251. Xsend questions, comments or complaints to:
  252. XDanny Sadinoff
  253. Xsadinoff@eniac.seas.upenn.edu
  254. END_OF_FILE
  255.   if test 5599 -ne `wc -c <'README'`; then
  256.     echo shar: \"'README'\" unpacked with wrong size!
  257.   fi
  258.   # end of 'README'
  259. fi
  260. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  261.   echo shar: Will not clobber existing file \"'Makefile'\"
  262. else
  263.   echo shar: Extracting \"'Makefile'\" \(91 characters\)
  264.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  265. XCFLAGS = -O
  266. XOBJ= hebcal.o greg.o error.o danlib.o
  267. Xhebcal:  $(OBJ)
  268. X     $(CC) $(OBJ) -o hebcal
  269. END_OF_FILE
  270.   if test 91 -ne `wc -c <'Makefile'`; then
  271.     echo shar: \"'Makefile'\" unpacked with wrong size!
  272.   fi
  273.   # end of 'Makefile'
  274. fi
  275. if test -f 'danlib.c' -a "${1}" != "-c" ; then 
  276.   echo shar: Will not clobber existing file \"'danlib.c'\"
  277. else
  278.   echo shar: Extracting \"'danlib.c'\" \(1227 characters\)
  279.   sed "s/^X//" >'danlib.c' <<'END_OF_FILE'
  280. X#include <sys/types.h>
  281. X#include <ctype.h>
  282. X#include "danlib.h"
  283. X
  284. X/* Some generally useful routines */
  285. X  
  286. Xvoid initStr(s,size)
  287. Xchar **s;
  288. Xint size;
  289. X{
  290. X  /* allocate space for a string */
  291. X  if ((*s = (char *)malloc((size_t) (size + 1) * sizeof(char))) == NULL)
  292. X    die("\n Memory Error: Couldn't allocate string\n","");
  293. X
  294. X  **s = '\0';
  295. X}
  296. X
  297. Xint isAllNums(s)
  298. Xchar * s;
  299. X{
  300. X/* returns true if a string contains only digits, dashes and newlines */
  301. X  int n = 0, len = strlen(s);
  302. X  
  303. X  for(n=0;
  304. X      (n < len)  &&  ( isdigit(s[n]) || (s[n] == '-') || (s[n] == '\n'));
  305. X      n++);
  306. X  return (n == len);
  307. X}
  308. X
  309. Xchar * numSuffix(i)
  310. Xint i;
  311. X{
  312. X/* returns a pointer to the proper ordinal suffix of a number */
  313. X  switch (i % 10) {
  314. X  case 1 : return "st";
  315. X  case 2 : return "nd";
  316. X  case 3 : return "rd";
  317. X  default: return "th";
  318. X  }
  319. X}
  320. X
  321. Xchar * itoa (i) 
  322. Xint i;
  323. X{
  324. X  static char ret[7];
  325. X  int c = 0;
  326. X  char tmp;
  327. X
  328. X  if (i < 0) {            /* is i negative? */
  329. X    ret[c++] = '-';        /* then put a minus */
  330. X    i = abs(i);
  331. X  }
  332. X  
  333. X  while (i >0) {        /* compose the number */
  334. X    ret[c++] = (i % 10) + '0';
  335. X    i /= 10;
  336. X  }
  337. X  i = c-1;
  338. X  
  339. X  for (c =0; c < i; c++) {    /* reverse the number */
  340. X    tmp = ret[c];
  341. X    ret[c] = ret[i-c];
  342. X    ret[i-c] = tmp;
  343. X  } 
  344. X
  345. X  return ret;
  346. X}
  347. X
  348. END_OF_FILE
  349.   if test 1227 -ne `wc -c <'danlib.c'`; then
  350.     echo shar: \"'danlib.c'\" unpacked with wrong size!
  351.   fi
  352.   # end of 'danlib.c'
  353. fi
  354. if test -f 'danlib.h' -a "${1}" != "-c" ; then 
  355.   echo shar: Will not clobber existing file \"'danlib.h'\"
  356. else
  357.   echo shar: Extracting \"'danlib.h'\" \(135 characters\)
  358.   sed "s/^X//" >'danlib.h' <<'END_OF_FILE'
  359. X#include <stdio.h>
  360. X#include "error.h"
  361. X
  362. X#define CHAR2NUM(x) ((x) - '0')
  363. X
  364. Xint isAllNums();
  365. Xvoid initStr();
  366. Xchar * numSuffix(), *itoa();
  367. X
  368. END_OF_FILE
  369.   if test 135 -ne `wc -c <'danlib.h'`; then
  370.     echo shar: \"'danlib.h'\" unpacked with wrong size!
  371.   fi
  372.   # end of 'danlib.h'
  373. fi
  374. if test -f 'error.c' -a "${1}" != "-c" ; then 
  375.   echo shar: Will not clobber existing file \"'error.c'\"
  376. else
  377.   echo shar: Extracting \"'error.c'\" \(609 characters\)
  378.   sed "s/^X//" >'error.c' <<'END_OF_FILE'
  379. X#include <stdio.h>
  380. X#include "error.h"
  381. X
  382. X
  383. Xextern int errno, sys_nerr;
  384. Xextern char *sys_errlist[], *progname;
  385. X
  386. Xvoid die (s1,s2)    /* print error message and die */
  387. Xchar *s1, *s2;
  388. X{
  389. X  if (progname)
  390. X    fprintf(stderr, "%s: ", progname);
  391. X  fprintf(stderr, s1, s2);
  392. X  if (errno > 0 && errno < sys_nerr)
  393. X    fprintf(stderr, " (%s)\n", sys_errlist[errno]);
  394. X  exit(1);
  395. X}
  396. X
  397. Xvoid warn (s1,s2) /* print error message but don't die */
  398. Xchar *s1, *s2;
  399. X{
  400. X  if (progname)
  401. X    fprintf(stderr, "%s: ", progname);
  402. X  fprintf(stderr, s1, s2);
  403. X  if (errno > 0 && errno < sys_nerr)
  404. X    fprintf(stderr, " (%s)\n", sys_errlist[errno]);
  405. X}
  406. END_OF_FILE
  407.   if test 609 -ne `wc -c <'error.c'`; then
  408.     echo shar: \"'error.c'\" unpacked with wrong size!
  409.   fi
  410.   # end of 'error.c'
  411. fi
  412. if test -f 'error.h' -a "${1}" != "-c" ; then 
  413.   echo shar: Will not clobber existing file \"'error.h'\"
  414. else
  415.   echo shar: Extracting \"'error.h'\" \(41 characters\)
  416.   sed "s/^X//" >'error.h' <<'END_OF_FILE'
  417. X#include <errno.h>
  418. X
  419. Xvoid die(), warn();
  420. X
  421. END_OF_FILE
  422.   if test 41 -ne `wc -c <'error.h'`; then
  423.     echo shar: \"'error.h'\" unpacked with wrong size!
  424.   fi
  425.   # end of 'error.h'
  426. fi
  427. if test -f 'greg.c' -a "${1}" != "-c" ; then 
  428.   echo shar: Will not clobber existing file \"'greg.c'\"
  429. else
  430.   echo shar: Extracting \"'greg.c'\" \(2758 characters\)
  431.   sed "s/^X//" >'greg.c' <<'END_OF_FILE'
  432. X#include <stdio.h>
  433. X#include <sys/types.h>
  434. X#include "greg.h"
  435. X#include "error.h"
  436. X
  437. X/* greg.c gregorian calendar module for hebrew calendar program
  438. X   By Danny Sadinoff
  439. X   (C) 1992
  440. X
  441. X*/
  442. X
  443. Xchar * eMonths[] = { 
  444. X  "January","February","March","April","May","June","July",
  445. X  "August","September","October","November","December"
  446. X  };
  447. X              
  448. Xint MonthLengths[][12] ={ 
  449. X  {31,28,31,30,31,30,31,31,30,31,30,31},
  450. X  {31,29,31,30,31,30,31,31,30,31,30,31}
  451. X};
  452. X
  453. Xchar * DayNames[] = {
  454. X  "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
  455. X  };
  456. X
  457. Xchar * ShortDayNames[] = {
  458. X  "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
  459. X  };
  460. X
  461. Xstatic void checkRange (dt,routine)
  462. Xdate_t dt;
  463. Xchar * routine;
  464. X{
  465. X  if ((dt.mm > 13)||(dt.dd > 31) || (dt.yy > 7000) || 
  466. X      (dt.mm <0)  ||(dt.dd <0  ) || (dt.yy < -7000))
  467. X    die("Date out of range from routine %s.",routine);
  468. X}
  469. X
  470. Xstatic long int daysSinceOrigin (dt)
  471. Xdate_t dt;
  472. X{
  473. X  int m,y;
  474. X  long int days = 0L;
  475. X
  476. X  checkRange(dt,"daysSinceOrigin");
  477. X
  478. X  for (y =1; y < dt.yy; y++)
  479. X    days += DAYS_IN(y);
  480. X  y = dt.yy;
  481. X  for (m= JAN; m < dt.mm; m++)
  482. X    days += MonthLengths[LEAP(y)][m];
  483. X  days += dt.dd -1;
  484. X  return days;
  485. X}
  486. X
  487. Xint diffDays(d1,d2)
  488. Xdate_t d1, d2;
  489. X{
  490. X  return (int) (daysSinceOrigin(d1) - daysSinceOrigin(d2));
  491. X}
  492. X
  493. Xint exceeds (d1,d2)
  494. Xdate_t d1, d2;
  495. X{
  496. X  if (d1.yy > d2.yy)
  497. X    return 1;
  498. X  else if (d1.yy < d2.yy)
  499. X    return 0;
  500. X  else if (d1.mm > d2.mm)
  501. X    return 1;
  502. X  else if (d1.mm < d2.mm)
  503. X    return 0;
  504. X  else if (d1.dd > d2.dd)
  505. X    return 1;
  506. X  else return 0;
  507. X}
  508. X
  509. Xvoid decDate (dt,n) /* decrements dt by n days */
  510. Xdate_t *dt;
  511. Xint n;
  512. X{
  513. X/*under construction*/
  514. X/*  while (n > 365) {
  515. X    n -= DAYS_IN(dt->yy -1);
  516. X    dt ->yy--;
  517. X  }
  518. X
  519. X
  520. X  if ((dt->mm == FEB) && (dt->dd == 29) && !LEAP(dt->yy))
  521. X    dt->dd--;
  522. X*/
  523. X  
  524. X  while (n--) 
  525. X    if (dt->dd ==1) {
  526. X      if (dt->mm == JAN) {
  527. X    dt->yy--;
  528. X    dt->mm = DEC;
  529. X    dt->dd = 31;
  530. X      }
  531. X      else {
  532. X    dt->mm--;
  533. X    dt->dd = MonthLengths[LEAP(dt->yy)][dt->mm];
  534. X      }
  535. X    }
  536. X    else dt->dd--;
  537. X}
  538. X
  539. Xvoid incDate (dt,n)   /* increments dt by n days */
  540. Xdate_t *dt;
  541. Xint n;
  542. X{
  543. X/*  while (n > 365) {
  544. X    n -= DAYS_IN(dt->yy);
  545. X    dt->yy++;
  546. X  }
  547. X
  548. X  if ((dt->mm == FEB) && (dt->dd == 29) && !LEAP(dt->yy) ) {
  549. X    dt-> mm = MAR;
  550. X    dt-> dd = 1;
  551. X  }
  552. X*/
  553. X  while (n--) 
  554. X   if ((dt->dd + 1) > MonthLengths[LEAP(dt->yy)][dt->mm]) 
  555. X     if (dt->mm == DEC) {
  556. X       dt->yy++;
  557. X       dt->mm = JAN;
  558. X       dt->dd = 1;
  559. X     }
  560. X     else {
  561. X       dt->mm++;
  562. X       dt->dd =1;
  563. X     }
  564. X   else 
  565. X     dt->dd ++;
  566. X}
  567. X
  568. Xint dayOfWeek(d1)  /* sunday = 0 */
  569. Xdate_t d1;
  570. X{
  571. X  return (int) ((daysSinceOrigin(d1) + 1) % 7 ) ;
  572. X}
  573. X
  574. Xvoid setDate (d) 
  575. Xdate_t *d;
  576. X{
  577. X  time_t secs;
  578. X  struct tm *loctm;
  579. X
  580. X  secs = time(NULL);
  581. X  loctm = localtime(&secs);
  582. X  d->yy = 1900 + loctm->tm_year;
  583. X  d->mm = loctm->tm_mon;
  584. X  d->dd = loctm->tm_mday;
  585. X}
  586. X
  587. X
  588. END_OF_FILE
  589.   if test 2758 -ne `wc -c <'greg.c'`; then
  590.     echo shar: \"'greg.c'\" unpacked with wrong size!
  591.   fi
  592.   # end of 'greg.c'
  593. fi
  594. if test -f 'greg.h' -a "${1}" != "-c" ; then 
  595.   echo shar: Will not clobber existing file \"'greg.h'\"
  596. else
  597.   echo shar: Extracting \"'greg.h'\" \(593 characters\)
  598.   sed "s/^X//" >'greg.h' <<'END_OF_FILE'
  599. X#include <time.h>
  600. X
  601. X#define LEAP(x) (!((x) % 4) && ( ((x) % 100) || !((x) % 400)))
  602. X#define DAYS_IN(x) (LEAP((x))?366:365)
  603. X
  604. Xenum {JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC};
  605. Xenum {SUN,MON,TUE,WED,THU,FRI,SAT};
  606. Xextern char * eMonths[];
  607. Xextern int MonthLengths[][12] ;
  608. Xextern char * DayNames[] ;
  609. Xextern char * ShortDayNames[];
  610. Xextern char * eDays[] ;
  611. X
  612. Xtypedef struct {
  613. X  int mm;    /* months since january 0,11*/
  614. X  int dd;    /* day of month 1,31 */
  615. X  int yy;    /* years since year 1 BCE i.e. -1 = 2 BCE */
  616. X  } date_t;
  617. X
  618. Xint diffDays(), exceeds(), dayOfWeek();
  619. Xvoid decDate (), incDate(), setDate();
  620. END_OF_FILE
  621.   if test 593 -ne `wc -c <'greg.h'`; then
  622.     echo shar: \"'greg.h'\" unpacked with wrong size!
  623.   fi
  624.   # end of 'greg.h'
  625. fi
  626. if test -f 'hebcal.c' -a "${1}" != "-c" ; then 
  627.   echo shar: Will not clobber existing file \"'hebcal.c'\"
  628. else
  629.   echo shar: Extracting \"'hebcal.c'\" \(20147 characters\)
  630.   sed "s/^X//" >'hebcal.c' <<'END_OF_FILE'
  631. X#include <stdio.h>
  632. X#include <string.h>
  633. X#include "error.h"
  634. X#include "danlib.h"
  635. X#include "greg.h"
  636. X  /* hebcal.c main module for hebrew calendar program
  637. X     By Danny Sadinoff
  638. X     (C) 1992
  639. X     
  640. X     $Date: 93/01/11 18:19:58 $
  641. X     $Revision: 1.3 $
  642. X     
  643. X     */ 
  644. X  
  645. X  
  646. X  int sedrot_sw, hebDates_sw, euroDates_sw, specMonth_sw,specDay_sw,
  647. X  weekday_sw, suppressHolidays_sw, suppressGreg_sw, printOmer_sw, omer;
  648. X
  649. Xtypedef struct {
  650. X  
  651. X  char * name;
  652. X  int length;
  653. X  
  654. X  int daysInCheshvan;
  655. X  int daysInKislev;
  656. X  
  657. X  int vayakhelPikudei;    /* double parsha flags */
  658. X  int tazriaMetzorah;
  659. X  int achreiKedoshim;
  660. X  int beharBech;
  661. X  int chukatBalak; 
  662. X  int matotMasei;
  663. X  int nitzavimVayelech;
  664. X  
  665. X} year_t;
  666. X
  667. X
  668. Xyear_t legend[2][8] = {
  669. X  {                /* stam years */
  670. X    {"1BX",353,29,29,1,1,1,1,0,1,1},    /* BX */
  671. X    {"1BS",355,30,30,1,1,1,1,1,1,1},    /* BS */
  672. X    {"2GC",354,29,30,1,1,1,1,1,1,1},    /* GC */
  673. X    {"4HC",354,29,30,1,1,1,1,0,1,0},    /* HC */ 
  674. X    {"0error - HX",354,29,29,1,1,1,1,0,1,0},    /* error! hx */
  675. X    {"4HS",355,30,30,0,1,1,1,0,1,0},    /* HS */
  676. X    {"6ZX",353,29,29,1,1,1,1,0,1,0},    /* ZX */
  677. X    {"6ZS",355,30,30,1,1,1,1,0,1,1},    /* ZS */
  678. X  },
  679. X  {                /* leap years */
  680. X    {"1BX",383,29,29,0,0,0,0,1,1,1},    /* BX */
  681. X    {"1BS",385,30,30,0,0,0,0,0,1,0},    /* BS */
  682. X    {"2GC",384,29,30,0,0,0,0,0,1,0},    /* GC */
  683. X    {"0error - HC",383,29,30,0,0,0,0,0,0,0},    /* error ! hc */
  684. X    {"4HX",383,29,29,0,0,0,0,0,0,0},    /* HX */
  685. X    {"4HS",385,30,30,0,0,0,0,0,0,1},    /* HS */
  686. X    {"6ZX",383,29,29,0,0,0,0,0,1,1},    /* ZX */
  687. X    {"6ZS",385,30,30,0,0,0,0,1,1,1},    /* ZS */
  688. X  }
  689. X};
  690. X
  691. Xint leapYears[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
  692. X
  693. Xenum {BX,BS,GC,HC,HX,HS,ZX,ZS};
  694. X
  695. Xint luach[][19] = 
  696. X{
  697. X  {HC,BX,HS,HC,BS,ZX,HC,BS,BX,HS,GC,BS,ZX,GC,BS,ZS,HX,GC,ZS},
  698. X  {ZS,HC,BX,ZS,HC,BX,ZS,HS,HC,BX,HS,HC,BS,ZX,HC,BS,ZX,HS,GC},
  699. X  {BS,ZX,GC,BS,ZS,HX,GC,ZS,ZS,HC,BX,ZS,HC,BS,BX,HC,BS,BS,ZX},
  700. X  {HC,HS,ZX,HC,HS,ZS,ZX,GC,BS,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BX},
  701. X  {ZS,HC,BS,BX,HC,BS,BS,ZX,HC,BS,ZX,HS,GC,ZS,ZS,HC,BX,ZS,HX},
  702. X  {GC,ZS,HS,HC,BX,HS,HC,BX,ZS,HC,BS,BX,HS,GC,BS,ZX,GC,BS,ZS},
  703. X  {ZX,GC,ZS,ZS,HC,BX,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BS,ZX,HC,BS},
  704. X  {BS,ZX,GC,BS,ZS,HX,GC,ZS,ZX,GC,ZS,ZS,HC,BX,ZS,HC,BS,BX,HS},
  705. X  {HC,BS,ZX,HC,BS,ZX,HS,GC,BS,ZX,GC,BS,ZS,HX,GC,ZS,HS,HC,BX},
  706. X  {ZS,HC,BX,ZS,HC,BS,BX,HS,HC,BS,ZX,HC,BS,ZX,HS,GC,ZS,ZX,GC},
  707. X  {BS,ZS,HX,GC,ZS,HS,HC,BX,ZS,HC,BX,ZS,HC,BS,BX,HS,GC,BS,ZX}, /* 10,11 GX? */
  708. X  {HC,BS,ZS,ZX,GC,ZS,ZS,HX,GC,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BS},
  709. X  {BX,HC,BS,BS,ZX,GC,BS,ZX,HS,GC,ZS,ZS,HC,BX,ZS,HC,BX,ZS,HS}
  710. X};
  711. X
  712. Xstruct {
  713. X  char * name;
  714. X  int length;
  715. X}hMonths[][14] = {
  716. X  {  
  717. X    {"Tishrei",30}, {"Cheshvan",29}, {"Kislev",30},
  718. X    {"Tevet",29}, {"Shvat",30}, {"Adar",29},
  719. X    {"Nisan",30}, {"Iyyar",29}, {"Sivan",30},
  720. X    {"Tamuz",29}, {"Av",30},{"Elul",29},{"Tishrei",30}},
  721. X  {
  722. X    {"Tishrei",30}, {"Cheshvan",29}, {"Kislev",30},
  723. X    {"Tevet",29}, {"Shvat",30}, {"Adar I",29}, {"Adar II",30},
  724. X    {"Nisan",30}, {"Iyyar",29}, {"Sivan",30},
  725. X    {"Tamuz",29}, {"Av",30},{"Elul",29},{"Tishrei",30}}    
  726. X};
  727. X
  728. Xenum {TISHREI, CHESHVAN, KISLEV, ADAR_2 = 6};
  729. X
  730. Xchar * sedrot[] = { 
  731. X  
  732. X  "Bereshit", "Noach", "Lech Lecha", "Vayera", "Chayei Sara",
  733. X  "Toldot", "Vayetzei", "Vayishlach", "Vayeshev", "Miketz", "Vayigash",
  734. X  "Vayechi",
  735. X  
  736. X  "Sh'mot", "Vaera", "Bo", "Beshalach", "Yitro", "Mishpatim",
  737. X  "Terumah", "Tetzaveh", "Ki Tisa", "Vayakhel", "Pekudei",
  738. X  
  739. X  "Vayikra", "Tzav", "Shmini", "Tazria", "Metzora", "Achrei Mot",
  740. X  "Kedoshim", "Emor", "Behar", "Bechukosai",
  741. X  
  742. X  "Bamidbar", "Nasso", "Beha'aloscha", "Sh'lach", "Korach", "Chukat",
  743. X  "Balak", "Pinchas", "Matot", "Masei",
  744. X  
  745. X  "Devarim", "Vaetchanan", "Eikev", "Re'eh", "Shoftim", 
  746. X  "Ki Teitzei", "Ki Tavo", "Nitzavim", "Vayeilech", "Ha'Azinu", 
  747. X  "V'Zot Habracha"
  748. X  };
  749. X
  750. Xenum { VAYAKHEL = 21, 
  751. X     TAZRIA = 26, ACHREI = 28,
  752. X     BEHAR = 31,
  753. X     CHUKAT = 38, MATOT= 41, 
  754. X     NITZAVIM = 50
  755. X     };
  756. X
  757. X#define NM_LEN 30
  758. X
  759. X#define OWNSEDRA 1
  760. X#define NIDCHE 2
  761. X#define MUKDAM 4
  762. X#define MUKDAM2 8
  763. X
  764. Xtypedef struct hnode{
  765. X  date_t date;
  766. X  char *name;
  767. X  int typeMask;
  768. X  struct hnode *next;
  769. X} holiday_t, *holidayp_t;
  770. X
  771. Xholiday_t special[100];
  772. X
  773. Xholiday_t holidays[] = {    /* 5 = Adar I */
  774. X  /* 6 = Adar = Adar II */
  775. X  {{0,1},"Rosh Hashana I",OWNSEDRA},{{0,2},"Rosh Hashana II",OWNSEDRA},
  776. X  {{0,3},"Tzom Gedalia",NIDCHE},
  777. X  {{0,9},"Erev Yom Kippur"},
  778. X  {{0,10},"Yom Kippur",OWNSEDRA},
  779. X  
  780. X  {{0,15},"Sukkot I",OWNSEDRA},{{0,16},"Sukkot II",OWNSEDRA},
  781. X  {{0,17},"Sukkot III (CH\"M)",OWNSEDRA},{{0,18},"Sukkot IV (CH\"M)",OWNSEDRA},
  782. X  {{0,19},"Sukkot V (CH\"M)",OWNSEDRA},{{0,20},"Sukkot VI (CH\"M)",OWNSEDRA},
  783. X  {{0,21},"Sukkot VII (Hoshana Raba)",OWNSEDRA},
  784. X  {{0,22},"Shmini Atzeret",OWNSEDRA},{{0,23},"Simchat Torah",OWNSEDRA},
  785. X  
  786. X  {{2,25},"Chanukah I"},
  787. X  {{2,26},"Chanukah II"},{{2,27},"Chanukah III"},{{2,29},"Chanukah IV"},
  788. X  {{3,10},"Asara B'Tevet",NIDCHE},
  789. X
  790. X  {{4,15},"Tu B'Shevat"}  /*NIDCHE?*/,
  791. X  
  792. X  {{5,15},"Purim katan"},
  793. X  {{6,13},"Ta'anit Esther",MUKDAM},{{6,14},"Purim"},
  794. X  {{6,15},"Shushan Purim"}, 
  795. X  
  796. X  {{7,14},"Erev Pesach - Taanit B'chorot",0},
  797. X#define PESACH2_STR "Pesach II"
  798. X  {{7,15},"Pesach I",OWNSEDRA},{{7,16},PESACH2_STR,OWNSEDRA},
  799. X  {{7,17},"Pesach III (CH\"M)",OWNSEDRA},{{7,18},"Pesach IV (CH\"M)",OWNSEDRA},
  800. X  {{7,19},"Pesach V (CH\"M)",OWNSEDRA},{{7,20},"Pesach VI (CH\"M)",OWNSEDRA},
  801. X  {{7,21},"Pesach VII",OWNSEDRA},
  802. X  {{7,22},"Pesach VIII",OWNSEDRA},
  803. X  
  804. X  {{7,27},"Yom HaShoah"},
  805. X  {{8,4},"Yom HaZikaron",MUKDAM2},
  806. X  {{8,5},"Yom Ha'atzmaut",MUKDAM},
  807. X#define SHAVUOT_STR "Shavuot I"
  808. X  {{9,6},SHAVUOT_STR,OWNSEDRA},{{9,7},"Shavuot II",OWNSEDRA},
  809. X  {{10,17},"Shiva Assar B'Tamuz",NIDCHE},
  810. X  {{11,9},"Tish'a B'Av",NIDCHE},
  811. X  {{12,29},"Erev Rosh Hashana"}
  812. X};
  813. X
  814. Xholiday_t chanukah_arr[5] =
  815. X{
  816. X  {{0,0},""},
  817. X  {{0,0},"Chanukah V"},
  818. X  {{0,0},"Chanukah VI"},
  819. X  {{0,0},"Chanukah VII"},
  820. X  {{0,0},"Chanukah VIII"}
  821. X};
  822. X
  823. Xenum {SIMCHAT_DAY = 23};
  824. X/* = {
  825. X   {{0,0},"Shabbat Shekalim"},
  826. X   {{0,0},"Shabbat Zachor"},
  827. X   {{0,0},"Parshat HaChodesh"},
  828. X   {{0,0},"Parshat Parah"},
  829. X   {{0,0},"Yom Yerushalayim"}
  830. X   };*/
  831. X
  832. X
  833. X#define LEAP_YR_HEB(x) (leapYears[((x) -1) % 19])
  834. X#define MONTHS_IN_HEB(x) (LEAP_YR_HEB(x) ? 13 :12)
  835. X
  836. Xyear_t yearData(yr)
  837. X     int yr;
  838. X{
  839. X  return legend[LEAP_YR_HEB(yr)][luach[((yr-1)/19+7)%13][(yr-1) %19]];
  840. X}
  841. X
  842. X#define LAST_INDEX(x) (sizeof x / sizeof x[0])
  843. X
  844. Xint daysInHebMonth(month, year) 
  845. X     int month, year;
  846. X{
  847. X  year_t theYear;
  848. X  
  849. X  theYear = yearData(year);
  850. X  if (month == CHESHVAN) 
  851. X    return theYear.daysInCheshvan;
  852. X  else if (month == KISLEV)
  853. X    return theYear.daysInKislev;
  854. X  else return hMonths[LEAP_YR_HEB(year)][month].length;
  855. X}
  856. X
  857. Xdate_t nextHebDate (dth) 
  858. X     date_t dth;
  859. X{
  860. X  dth.dd++;
  861. X  if (dth.dd > daysInHebMonth(dth.mm,dth.yy))
  862. X    if (dth.mm ==  MONTHS_IN_HEB(dth.yy)-1){
  863. X      dth.yy++;
  864. X      dth.mm =0;
  865. X      dth.dd =1;
  866. X    }
  867. X    else {
  868. X      dth.mm++;
  869. X      dth.dd =1;
  870. X    }
  871. X  return dth;
  872. X}
  873. X
  874. Xdate_t prevHebDate (dth) 
  875. X     date_t dth;
  876. X{
  877. X  dth.dd--;
  878. X  if (dth.dd == 0)
  879. X    if (dth.mm == 0) {
  880. X      dth.yy--;
  881. X      dth.mm = MONTHS_IN_HEB(dth.yy) -1 ;
  882. X      dth.dd = daysInHebMonth(dth.mm,dth.yy);
  883. X    }
  884. X    else {
  885. X      dth.mm--;
  886. X      dth.dd = daysInHebMonth(dth.mm,dth.yy);
  887. X    }
  888. X  return dth;
  889. X}
  890. X
  891. Xvoid addHoliday(theHoliday, holiList)
  892. X     holiday_t theHoliday, **holiList;
  893. X{
  894. X  
  895. X  holidayp_t newHol, currHol = *holiList;
  896. X  
  897. X  if (currHol) 
  898. X    while (currHol->next)    /* scan to the end of the list */
  899. X      currHol = currHol->next; /* now currhol points to the last */
  900. X  
  901. X  if (!(newHol = (holiday_t *) malloc(sizeof (holiday_t))))
  902. X    die("Mem allocation error in getHebHolidays routine.","");
  903. X  
  904. X  if (currHol)
  905. X    currHol->next = newHol;
  906. X  else *holiList = newHol;
  907. X  
  908. X  *newHol = theHoliday;
  909. X  newHol->next = NULL;
  910. X}
  911. X
  912. Xholidayp_t getHebHolidays (dt,weekday,theYear, holiList) /* returns a linked */
  913. X     date_t dt;            /* list of holidays for that date*/ 
  914. X     int weekday;        
  915. X     year_t theYear;
  916. X     holiday_t ** holiList; 
  917. X{
  918. X  int c, specialCounter=0;
  919. X  holidayp_t tmpholip;
  920. X  static int chanukah_day;
  921. X  
  922. X  *holiList = NULL;
  923. X  
  924. X#define CORRECTION(yy,mm) (LEAP_YR_HEB(yy) ? 0 : (((mm) > 4) ? 1: 0))
  925. X#define MATCH(X,Y) ((X.mm == (Y.mm + CORRECTION(Y.yy,Y.mm)) ) && (X.dd == Y.dd))
  926. X  
  927. X  for (c = 0; c < LAST_INDEX(holidays); c++) 
  928. X    {
  929. X      if (MATCH(holidays[c].date,dt))
  930. X    if (!(weekday == SAT && holidays[c].typeMask & NIDCHE) &&
  931. X        !(holidays[c].typeMask & MUKDAM &&
  932. X          (weekday == FRI || weekday == SAT)) &&
  933. X        !(holidays[c].typeMask & MUKDAM2 &&
  934. X          (weekday == THU || weekday == FRI)))
  935. X      {            /* do normal holidays*/
  936. X        addHoliday(holidays[c],holiList);
  937. X        if (!strcmp((*holiList)->name,PESACH2_STR)) omer++;
  938. X        if (omer && holiList && !strcmp((*holiList)->name,SHAVUOT_STR)) omer=0;
  939. X      }
  940. X      
  941. X      if (holidays[c].typeMask & NIDCHE &&    /* fast days which are */
  942. X      (MATCH(holidays[c].date,prevHebDate(dt))) && 
  943. X      (weekday ==SUN)){
  944. X    char *st;
  945. X    
  946. X    initStr(&st,NM_LEN);
  947. X    strncat(st,holidays[c].name,NM_LEN);
  948. X    strncat(st," [nidche]",NM_LEN);
  949. X    addHoliday(holidays[c],holiList); 
  950. X    (*holiList)->name = st;
  951. X      }
  952. X      
  953. X      if (holidays[c].typeMask & MUKDAM && /* if the date actually falls */
  954. X      (MATCH(holidays[c].date,nextHebDate(nextHebDate(dt))) ||
  955. X       MATCH(holidays[c].date,nextHebDate(dt))) &&
  956. X      (weekday == THU))                  /* on friday or shabbat*/
  957. X    addHoliday(holidays[c],holiList);
  958. X      
  959. X      if (holidays[c].typeMask & MUKDAM2 && /* if the date actually falls */
  960. X      (MATCH(holidays[c].date,nextHebDate(nextHebDate(dt))) ||
  961. X       MATCH(holidays[c].date,nextHebDate(dt))) && 
  962. X      (weekday == WED))                  /* on thursday or friday*/
  963. X    addHoliday(holidays[c],holiList);
  964. X    }
  965. X  
  966. X  /* Lag B'Omer Processing */
  967. X  if (omer == 33) {
  968. X    tmpholip = &special[specialCounter++];
  969. X    initStr(&tmpholip->name,NM_LEN); 
  970. X    strncpy(tmpholip->name,"Lag B'Omer",NM_LEN);
  971. X    addHoliday(*tmpholip,holiList);
  972. X  }
  973. X
  974. X  if (chanukah_day) {
  975. X    addHoliday(chanukah_arr[chanukah_day],holiList);
  976. X    if (chanukah_day == 4)
  977. X      chanukah_day = 0;
  978. X    else chanukah_day++;
  979. X  }
  980. X
  981. X  if ((dt.dd == 29) && (dt.mm == 2)) 
  982. X    chanukah_day = 1;
  983. X  
  984. X
  985. X  /* rosh Chodesh Processing... */
  986. X  if (dt.dd == 1 && dt.mm){    /* every 1st of the month except tishrei */
  987. X    tmpholip = &special[specialCounter++];
  988. X    initStr(&tmpholip->name,NM_LEN); 
  989. X    strcat(tmpholip->name,"Rosh Chodesh ");
  990. X    strncat(tmpholip->name,hMonths[LEAP_YR_HEB(dt.yy)][dt.mm].name,NM_LEN);
  991. X    addHoliday(*tmpholip,holiList);
  992. X  }
  993. X  if (dt.dd == 30){
  994. X    tmpholip = &special[specialCounter++];
  995. X    initStr(&tmpholip->name,NM_LEN);
  996. X    strcat(tmpholip->name,"Rosh Chodesh ");
  997. X    strncat(tmpholip->name,hMonths[LEAP_YR_HEB(dt.yy)][dt.mm+1].name,NM_LEN);
  998. X    addHoliday(*tmpholip,holiList);
  999. X  }
  1000. X  
  1001. X  
  1002. X  return *holiList;
  1003. X}
  1004. X
  1005. X
  1006. Xvoid incHebJulDate(dth,dtj,wkday)
  1007. X     date_t *dth, *dtj;
  1008. X     int *wkday;
  1009. X{
  1010. X  /* increments both hebrew and julian calendars */
  1011. X  
  1012. X  incDate (dtj,1);
  1013. X  *wkday = dayOfWeek(*dtj);
  1014. X  *dth = nextHebDate(*dth);
  1015. X}   
  1016. X
  1017. X#define JUL2HEB(x) ((x)+ 3760)
  1018. X
  1019. Xvoid PrintWeekday (dt) 
  1020. X     date_t dt;{
  1021. X       printf ("%s, ",ShortDayNames[dayOfWeek(dt)]);
  1022. X     }
  1023. X     
  1024. X     void PrintJulDate (dt) 
  1025. X     date_t dt;
  1026. X{
  1027. X  if (!suppressGreg_sw) 
  1028. X    if (euroDates_sw)
  1029. X      printf ("%d.%d.%d ",dt.dd,dt.mm+1,dt.yy);
  1030. X    else
  1031. X      printf ("%d/%d/%d ",dt.mm+1,dt.dd,dt.yy);
  1032. X}
  1033. X
  1034. X
  1035. Xchar *DoSedra (sedra, ydat)    /* returns a string "Parshat <parsha>" */
  1036. X     int *sedra;        /* based on the current parsha number */
  1037. X     year_t ydat;
  1038. X{
  1039. X#define PLENGTH 40
  1040. X  static char s[PLENGTH+1];
  1041. X  
  1042. X  *s = '\0';
  1043. X  strncat(s,"Parshat ",PLENGTH);
  1044. X  strncat(s,sedrot[*sedra],PLENGTH);
  1045. X  switch (*sedra) {
  1046. X  case VAYAKHEL :
  1047. X    if (ydat.vayakhelPikudei){
  1048. X      strncat(s,"-",PLENGTH);
  1049. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  1050. X      *sedra += 2;
  1051. X    }
  1052. X    else {
  1053. X      (*sedra)++;
  1054. X    }
  1055. X    break;
  1056. X  case TAZRIA:
  1057. X    if (ydat.tazriaMetzorah){
  1058. X      strncat(s,"-",PLENGTH);
  1059. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  1060. X      *sedra += 2;
  1061. X    }
  1062. X    else (*sedra)++;
  1063. X    break;
  1064. X  case ACHREI :
  1065. X    if (ydat.achreiKedoshim){
  1066. X      strncat(s,"-",PLENGTH);
  1067. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  1068. X      *sedra += 2;
  1069. X    }
  1070. X    else (*sedra)++;
  1071. X    break;
  1072. X  case BEHAR :
  1073. X    if (ydat.beharBech){
  1074. X      strncat(s,"-",PLENGTH);
  1075. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  1076. X      *sedra += 2;
  1077. X    }
  1078. X    else (*sedra)++;
  1079. X    break;
  1080. X  case CHUKAT :
  1081. X    if (ydat.chukatBalak){
  1082. X      strncat(s,"-",PLENGTH);
  1083. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  1084. X      *sedra += 2;
  1085. X    }
  1086. X    else (*sedra)++;
  1087. X    break;
  1088. X  case MATOT :
  1089. X    if (ydat.matotMasei){
  1090. X      strncat(s,"-",PLENGTH);
  1091. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  1092. X      *sedra += 2;
  1093. X    }
  1094. X    else (*sedra)++; 
  1095. X    break;
  1096. X  case NITZAVIM :
  1097. X    if (ydat.nitzavimVayelech){
  1098. X      strncat(s,"-",PLENGTH);
  1099. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  1100. X      *sedra += 2;
  1101. X    }
  1102. X    else (*sedra)++; 
  1103. X    break;
  1104. X  case LAST_INDEX(sedrot)-1:
  1105. X    *sedra = 0;
  1106. X    break;
  1107. X  default:
  1108. X    (*sedra)++;
  1109. X  }
  1110. X  strncat(s,"\n",PLENGTH);
  1111. X  return s;
  1112. X}
  1113. X
  1114. X#define CHAR2NUM(x) ((x) - '0')
  1115. X
  1116. X
  1117. Xvoid DoCalendar (roshDt,justMonth,justDay)
  1118. X     date_t roshDt;    /* rosh Hashana of preceeding year */
  1119. X     int justMonth,/* print this month  */
  1120. X       justDay; 
  1121. X{ /* print this day */
  1122. X     
  1123. X     
  1124. X  int sedra,weekday;
  1125. X     date_t todayj, todayh;
  1126. X     holiday_t *holip;
  1127. X     year_t theYear;
  1128. X     todayj = roshDt;
  1129. X     
  1130. X     todayh.mm = 0;
  1131. X     todayh.dd = 1;
  1132. X     todayh.yy = JUL2HEB(roshDt.yy)+1; /* because it's after R"H */
  1133. X     
  1134. X     
  1135. X     theYear = yearData(todayh.yy);
  1136. X     
  1137. X     if (CHAR2NUM(theYear.name[0]) != dayOfWeek(roshDt))
  1138. X       die ("Bad Day!\n","");  
  1139. X     
  1140. X     /* first scan forward to simchat Torah, keeping track of dates only. */
  1141. X     while (todayh.dd != SIMCHAT_DAY){
  1142. X       incHebJulDate(&todayh, &todayj,&weekday);
  1143. X     }
  1144. X     sedra = 0;        /* initialize sedra */
  1145. X     
  1146. X     /* then continue until january 1st. */
  1147. X     do {
  1148. X       getHebHolidays(todayj,weekday,theYear,&holip);
  1149. X       if ((weekday == SAT) && !(holip && holip->typeMask & OWNSEDRA)) 
  1150. X         DoSedra(&sedra,theYear);
  1151. X       
  1152. X       incHebJulDate(&todayh,&todayj,&weekday);
  1153. X     } while (!((todayj.mm==0) && (todayj.dd==1)));
  1154. X     
  1155. X     /* -------Main Year Loop-------*/
  1156. X     do {
  1157. X       if (hebDates_sw && 
  1158. X           (!specMonth_sw || (justMonth== todayj.mm)) &&
  1159. X           (!specDay_sw   || (justDay == todayj.dd))) {
  1160. X         PrintJulDate(todayj);
  1161. X         if (weekday_sw)
  1162. X           PrintWeekday(todayj);
  1163. X         printf ("%d of %s, %d\n",todayh.dd, /* print the hebrew date */
  1164. X             hMonths[LEAP_YR_HEB(todayh.yy)][todayh.mm].name,
  1165. X             todayh.yy);
  1166. X       }
  1167. X       getHebHolidays(todayh,weekday,theYear,&holip); 
  1168. X       
  1169. X       if ((todayh.mm == TISHREI) && (todayh.dd == 1))
  1170. X         theYear = yearData(todayh.yy); /* if R"H reset YearData */
  1171. X       
  1172. X       if (sedrot_sw && (weekday == SAT) && 
  1173. X           !(holip && holip->typeMask & OWNSEDRA)){
  1174. X         if ((!specMonth_sw || (justMonth == todayj.mm)) &&
  1175. X         (!specDay_sw   || (justDay == todayj.dd))){
  1176. X           PrintJulDate(todayj);    
  1177. X           printf("%s",DoSedra(&sedra,theYear));
  1178. X         }
  1179. X         else DoSedra(&sedra,theYear);
  1180. X       }
  1181. X       
  1182. X       if ((todayh.mm == TISHREI) && /* reset the sedra on simchat torah */
  1183. X           (todayh.dd == SIMCHAT_DAY)) sedra =0; 
  1184. X       
  1185. X       if (!suppressHolidays_sw &&
  1186. X           (!specMonth_sw || (justMonth == todayj.mm)) &&
  1187. X           (!specDay_sw   || (justDay == todayj.dd))) 
  1188. X         for (;holip;holip = holip->next) {
  1189. X           PrintJulDate(todayj);
  1190. X           if (weekday_sw)
  1191. X         PrintWeekday(todayj);
  1192. X           printf ("%s\n",holip->name);
  1193. X         }
  1194. X       
  1195. X       /* print the omer if desired */
  1196. X       if (omer && printOmer_sw && 
  1197. X           (!specMonth_sw || (justMonth == todayj.mm)) &&
  1198. X           (!specDay_sw   || (justDay == todayj.dd))) {
  1199. X         char *omerStr;
  1200. X         initStr(&omerStr,NM_LEN); 
  1201. X         strncat(omerStr,itoa(omer),NM_LEN);
  1202. X         strncat(omerStr,numSuffix(omer),NM_LEN);
  1203. X         strncat(omerStr," day of the Omer",NM_LEN);
  1204. X         PrintJulDate(todayj);
  1205. X         if (weekday_sw) PrintWeekday(todayj);
  1206. X         printf ("%s\n",omerStr);
  1207. X       }
  1208. X       if (omer) omer++;
  1209. X       
  1210. X       
  1211. X       incHebJulDate(&todayh,&todayj,&weekday);
  1212. X     } while (!((todayj.mm==0) && (todayj.dd==1))); /* continue to january 1st */
  1213. X     
  1214. X       }
  1215. X     
  1216. X     void RollBack(dtj,target) /* move rosh hashana dtj back until it's */
  1217. X     date_t *dtj;          /* in the year before target */
  1218. X     int target;{
  1219. X       
  1220. X       int days,theyear;
  1221. X       
  1222. X       for (days = 0,theyear = dtj->yy ;theyear > target -1; theyear--)
  1223. X     days +=yearData(JUL2HEB(theyear)).length;
  1224. X       decDate (dtj,days); 
  1225. X       
  1226. X     }
  1227. X     
  1228. X     void RollForward(dtj,target)   /* move rosh hashana dtj forward until it's*/
  1229. X     date_t *dtj;               /*  in the year before target*/
  1230. X     int target; {
  1231. X       int days,theyear;
  1232. X       
  1233. X       for (days = 0,theyear = dtj->yy ;theyear < target -1; theyear++)
  1234. X     days +=yearData(JUL2HEB(theyear+1)).length;
  1235. X       incDate (dtj,days); 
  1236. X       
  1237. X     }
  1238. X     
  1239. X     char * progname;
  1240. X     
  1241. X     int main (argc, argv)
  1242. X     int argc;
  1243. X     char *argv[];
  1244. X{
  1245. X  char *c;
  1246. X  date_t startDate,tempdt;
  1247. X  int theYear,theMonth,theDay,yearDirty=0;
  1248. X  
  1249. X  char * usage = "usage: hebcal [-dehostTw] [[month [day]] year]\n               hebcal help\n";  
  1250. X  progname = argv[0];
  1251. X  
  1252. X  startDate.dd = 28;
  1253. X  startDate.mm = SEP; /* any ol' rosh hashana */
  1254. X  startDate.yy = 1992;
  1255. X  
  1256. X  setDate(&tempdt);        /* do this year */
  1257. X  theYear = tempdt.yy;
  1258. X  
  1259. X  for (argv++, argc--; argc; argv++, argc--)
  1260. X    if (isAllNums(*argv))
  1261. X      if ((argc-1) && isAllNums(*(argv+1)) && !yearDirty) 
  1262. X    if ((argc-2) && isAllNums(*(argv+2))) {
  1263. X      specMonth_sw =1;
  1264. X      specDay_sw =1;
  1265. X      theMonth = atoi(*argv) -1; /* year and month specified */
  1266. X      theDay = atoi(*++argv); /* print theDay of theMonth */
  1267. X      theYear = atoi(*++argv); /* print theMonth of theYear */
  1268. X      yearDirty =1;
  1269. X      argc -=2;
  1270. X    }
  1271. X    else {
  1272. X      specMonth_sw =1;
  1273. X      theMonth = atoi(*argv) -1; /* year and month specified */
  1274. X      theYear = atoi(*++argv); /* print theMonth of theYear */
  1275. X      yearDirty =1;
  1276. X      argc--;
  1277. X    }
  1278. X      else if (!yearDirty) {
  1279. X    theYear = atoi(*argv);    /* just year specified */
  1280. X    yearDirty = 1;        /* print whole year */
  1281. X      }
  1282. X      else     die(usage,"");
  1283. X    else if (**argv == '-')
  1284. X      for (c = *argv,c++;*c;c++)
  1285. X    switch (*c) {
  1286. X    case 'd' :        /* print hebrew dates */
  1287. X      hebDates_sw = 1;
  1288. X      break;
  1289. X    case 'e':
  1290. X      euroDates_sw =1;
  1291. X      break;
  1292. X    case 'h':
  1293. X      suppressHolidays_sw =1;
  1294. X      break;
  1295. X    case 't':        /* do hebcal for today. */
  1296. X      specMonth_sw =1;
  1297. X      specDay_sw =1;
  1298. X      theMonth = tempdt.mm; /* year and month specified */
  1299. X      theDay = tempdt.dd; /* print theDay of theMonth */
  1300. X      yearDirty =1;
  1301. X      break;
  1302. X    case 'T':        /* do hebcal for today, omit gregorian date. */
  1303. X      suppressGreg_sw = 1;
  1304. X      specMonth_sw =1;
  1305. X      specDay_sw =1;
  1306. X      theMonth = tempdt.mm; /* year and month specified */
  1307. X      theDay = tempdt.dd; /* print theDay of theMonth */
  1308. X      yearDirty =1;
  1309. X      printOmer_sw =1;
  1310. X      break;
  1311. X    case 'o':
  1312. X      printOmer_sw =1;
  1313. X      break;
  1314. X    case 's' :        /* print sedrot */
  1315. X      sedrot_sw = 1;
  1316. X      break;
  1317. X    case 'w' :        /* print days of the week */
  1318. X      weekday_sw = 1;
  1319. X      break;
  1320. X    default: die(usage,"");
  1321. X    }
  1322. X    else if (!strcmp(*argv,"help")) {
  1323. X      printf ("Hebcal Version 1.3\n\n");
  1324. X      printf ("Hebcal prints out hebrew calendars one solar year at a time.\n");
  1325. X      printf ("Given one numeric argument, it will print out the calendar \n");
  1326. X      printf ("for that year.  Given two numeric argumetnts mm yyyy, it\n");
  1327. X      printf ("prints out the calendar for month mm of year yyyy. \n");
  1328. X      printf (usage);
  1329. X      printf ("\nOPTIONS:\n   -d : add hebrew dates\n");
  1330. X      printf ("   -e : use european dates for OUTPUT ONLY (input format the same)\n");
  1331. X      printf ("   -h : suppress holidays\n");
  1332. X      printf ("   -o : add days of the omer\n");
  1333. X      printf ("   -s : add weekly sedrot \n");
  1334. X      printf ("   -t : only output for today's date\n");
  1335. X      printf ("   -T : print today's pertinent information, no gregorian date\n");
  1336. X      printf ("   -w : add day of the week\n\n");
  1337. X      printf ("       hebcal help --- prints this message\n"); 
  1338. X      printf ("\nExample: \n");
  1339. X      printf ("   hebcal -ho\n");
  1340. X      printf ("will just print out the days of the omer for the current year.\n");
  1341. X      exit(0);
  1342. X    }
  1343. X    else die (usage,"");
  1344. X  
  1345. X  if (specDay_sw) hebDates_sw = 1;
  1346. X  
  1347. X  if (theYear < startDate.yy +1) /* go to R"H of the year before */
  1348. X    RollBack(&startDate,theYear);
  1349. X  else if (theYear > startDate.yy +1) /* start from there */
  1350. X    RollForward(&startDate,theYear);
  1351. X  
  1352. X  DoCalendar(startDate,theMonth,theDay);   
  1353. X  
  1354. X  return 0;
  1355. X}
  1356. END_OF_FILE
  1357.   if test 20147 -ne `wc -c <'hebcal.c'`; then
  1358.     echo shar: \"'hebcal.c'\" unpacked with wrong size!
  1359.   fi
  1360.   # end of 'hebcal.c'
  1361. fi
  1362. if test -f 'hebcal.l' -a "${1}" != "-c" ; then 
  1363.   echo shar: Will not clobber existing file \"'hebcal.l'\"
  1364. else
  1365.   echo shar: Extracting \"'hebcal.l'\" \(3378 characters\)
  1366.   sed "s/^X//" >'hebcal.l' <<'END_OF_FILE'
  1367. X.TH HEBCAL 1L "Hebcal Version 1.3" "Danny Sadinoff"
  1368. X.SH NAME
  1369. Xhebcal - a Jewish calendar generator
  1370. X.SH SYNOPSIS
  1371. X.B hebcal
  1372. X[ 
  1373. X\-dehostTw
  1374. X] [[
  1375. X.I month
  1376. X[
  1377. X.I day
  1378. X]]
  1379. X.I year
  1380. X]
  1381. X.br
  1382. X.B hebcal help
  1383. X.SH DESCRIPTION
  1384. XWith no arguments, 
  1385. X.B hebcal
  1386. Xwill print to stdout the 
  1387. Xdates of the Jewish holidays in the current
  1388. Xsecular year.  Each line is prefixed with a gregorian date of the form
  1389. Xmm/dd/yy.  
  1390. X.sp
  1391. XBy specifying 
  1392. X.I month,
  1393. X.I day,
  1394. Xor 
  1395. X.I year 
  1396. Xoutput can be limited to a particular month or date
  1397. Xin a particular year.  
  1398. X.sp
  1399. X.I year
  1400. Xis an integer (it can be negative).  So 92 is in the early Christian
  1401. Xera, not the late twentieth century.
  1402. X.sp
  1403. X.I month
  1404. Xis a number from 1..12.
  1405. X.sp
  1406. X.I day 
  1407. Xis a number from 1..31.
  1408. X.sp
  1409. XFor example, the command
  1410. X.nf
  1411. X
  1412. X    hebcal 10 1992
  1413. X
  1414. X.fi
  1415. Xwill print out the holidays occurring in October of 1992.
  1416. X.PP
  1417. XA few other bells and whistles include the weekly 
  1418. X.I sedrah
  1419. Xas well as the day of the week, the count of the 
  1420. X.I omer,
  1421. Xand the Hebrew date.
  1422. X.PP
  1423. XOutput from hebcal can be used to drive calendar(1).  
  1424. XDay\-to\-day use for hebcal is provided for in the 
  1425. X.B -T
  1426. X and 
  1427. X.B -t
  1428. Xswitches, which print out Jewish calendar entries for the current date.
  1429. X.PP
  1430. X.SH OPTIONS
  1431. X.TP 1.0i
  1432. X.B "  -d"
  1433. XAdd the Hebrew date to the output.
  1434. X.TP
  1435. X.B "  -e"
  1436. XChange the output format to European-style dates: dd/mm/yyyy
  1437. X.TP
  1438. X.B "  -h"
  1439. XSupress holidays in output.
  1440. X.TP
  1441. X.B "  -o"
  1442. XAdd the count of the 
  1443. X.I omer
  1444. Xto the output.
  1445. X.TP
  1446. X.B "  -s"
  1447. XAdd the weekly sedra to the output.  
  1448. X.TP
  1449. X.B "  -t"
  1450. XPrint calendar entry for today's date only.  -d is asserted with this option.
  1451. X.TP
  1452. X.B "  -T"
  1453. XSame as -t, only without the gregorian date.  This option is useful in
  1454. Xlogin scripts, just to see what's happening today in the Jewish calendar.
  1455. X.TP
  1456. X.B "  -w"
  1457. XAdd the day of the week to the output.
  1458. X.SH EXAMPLES
  1459. X.LP
  1460. XTo find the days of the 
  1461. X.I omer 
  1462. Xin 1997, printing the days of the week:
  1463. X.RS
  1464. X.nf
  1465. X.ft B
  1466. Xexample% hebcal -how 1997
  1467. X.br
  1468. X4/23/97 Wed, 1st day of the Omer
  1469. X.br
  1470. X4/24/97 Thu, 2nd day of the Omer
  1471. X.br
  1472. X4/25/97 Fri, 3rd day of the Omer
  1473. X.br
  1474. X .
  1475. X.br
  1476. X .
  1477. X.br
  1478. X .
  1479. X.br
  1480. X6/9/97 Mon, 48th day of the Omer
  1481. X.br
  1482. X6/10/97 Tue, 49th day of the Omer
  1483. X.RE
  1484. X.LP
  1485. XTo just print the weekly sedrot of December 2000
  1486. X.RS
  1487. X.nf
  1488. X.ft B
  1489. Xexample% hebcal -hp 12 2000
  1490. X.br
  1491. X12/2/00 Parshat Toldot
  1492. X.br
  1493. X12/9/00 Parshat Vayetzei
  1494. X.br
  1495. X12/16/00 Parshat Vayishlach
  1496. X.br
  1497. X12/23/00 Parshat Vayeshev
  1498. X.br
  1499. X12/30/00 Parshat Miketz
  1500. X.br
  1501. X.RE
  1502. X.LP 
  1503. XTo find out what's happening in the Jewish calendar today, use
  1504. X.RS
  1505. X.nf
  1506. X.ft B
  1507. Xexample% hebcal -T
  1508. X.br
  1509. X19 of Nisan, 5752
  1510. X.br
  1511. XPesach V (CH"M)
  1512. X.br
  1513. X4th day of the Omer
  1514. X.br
  1515. X.RE
  1516. X.SH AUTHOR
  1517. XDanny Sadinoff, University of Pennsylvania
  1518. X.SH SEE ALSO
  1519. Xcalendar(1), hcal(1), hdate(1), omer(1), rise(1)
  1520. X.sp
  1521. XThe motivation for the algorithms in this program is the
  1522. X.I "Tur Shulchan Aruch.  "
  1523. XA well written treatment of the Jewish calendar is given in 
  1524. X.I Understanding the Jewish Calendar
  1525. Xby Rabbi Nathan Bushwick.  A more complete bibliography on the topic
  1526. Xcan be found there.
  1527. X.SH BUGS
  1528. XThere are some omissions from the list of included holidays, including
  1529. X;Yom Yerushalayim. 
  1530. X.sp
  1531. XRight now, hebcal dosn't perform enough sanity checking on input
  1532. Xdates.
  1533. X.sp
  1534. XHebcal performs no checking for changes between the julian and
  1535. Xgregorian calendar, so secular dates before 1752 are untrustworthy.
  1536. X.sp 
  1537. XHebcal cannot currently handle date computations before 2 C.E.  sorry.
  1538. X.SH BUG REPORTS TO
  1539. XDanny Sadinoff    sadinoff@eniac.seas.upenn.edu
  1540. X
  1541. X
  1542. X
  1543. END_OF_FILE
  1544.   if test 3378 -ne `wc -c <'hebcal.l'`; then
  1545.     echo shar: \"'hebcal.l'\" unpacked with wrong size!
  1546.   fi
  1547.   # end of 'hebcal.l'
  1548. fi
  1549. if test -f 'test.c' -a "${1}" != "-c" ; then 
  1550.   echo shar: Will not clobber existing file \"'test.c'\"
  1551. else
  1552.   echo shar: Extracting \"'test.c'\" \(129 characters\)
  1553.   sed "s/^X//" >'test.c' <<'END_OF_FILE'
  1554. X#include <stdio.h>
  1555. X
  1556. Xmain()
  1557. X{
  1558. X  char d,c;
  1559. X  d = getchar ();
  1560. X  c =  getchar();
  1561. X  if (c == 'a' || d == 'b') printf ("success\n");
  1562. X}
  1563. END_OF_FILE
  1564.   if test 129 -ne `wc -c <'test.c'`; then
  1565.     echo shar: \"'test.c'\" unpacked with wrong size!
  1566.   fi
  1567.   # end of 'test.c'
  1568. fi
  1569. echo shar: End of archive 1 \(of 1\).
  1570. cp /dev/null ark1isdone
  1571. MISSING=""
  1572. for I in 1 ; do
  1573.     if test ! -f ark${I}isdone ; then
  1574.     MISSING="${MISSING} ${I}"
  1575.     fi
  1576. done
  1577. if test "${MISSING}" = "" ; then
  1578.     echo You have the archive.
  1579.     rm -f ark[1-9]isdone
  1580. else
  1581.     echo You still must unpack the following archives:
  1582.     echo "        " ${MISSING}
  1583. fi
  1584. exit 0
  1585. exit 0 # Just in case...
  1586.