home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume35 / hebcal / part01 next >
Text File  |  1993-02-21  |  53KB  |  1,944 lines

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