home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #26 / NN_1992_26.iso / spool / comp / sources / misc / 4076 < prev    next >
Encoding:
Text File  |  1992-11-10  |  42.3 KB  |  1,585 lines

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