home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / hebcal / part01 < prev    next >
Encoding:
Text File  |  1992-11-03  |  35.6 KB  |  1,261 lines

  1. Newsgroups: comp.sources.misc,soc.culture.jewish
  2. From: sadinoff@unagi.cis.upenn.edu (Danny Sadinoff)
  3. Subject:  v33i034:  hebcal - A Jewish calendar generator, Part01/01
  4. Message-ID: <1992Nov4.143505.10918@sparky.imd.sterling.com>
  5. X-Md4-Signature: d4f77fc558f4307f42fd6ee9dfe3ed94
  6. Date: Wed, 4 Nov 1992 14:35:05 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: sadinoff@unagi.cis.upenn.edu (Danny Sadinoff)
  10. Posting-number: Volume 33, Issue 34
  11. Archive-name: hebcal/part01
  12. Environment: UNIX
  13.  
  14. [ Freeware, shareware .. and now distribu-ware ? I'm not crazy about ]
  15. [ the minor conditions below but what the hey...             -Kent+  ]
  16.  
  17. Here is version 1.0 of hebcal, a Jewish calendar generator for unix
  18. machines.  (It's not called jucal since that sounds like something you
  19. step on if you see it indoors)  It's probably not hard to adapt it to
  20. any C environment
  21.  
  22. Hebcal is somewhat more sophisticated than other freely distributed
  23. Jewish calendar programs I've seen, notably hcal.  Hebcal is fairly
  24. flexible in terms of which events in the Jewish calendar it displays.
  25. Each of the following can be individualy turned on or off:
  26.  
  27.   The Hebrew date
  28.   Jewish Holdiays (including Yom Ha'atzmaut and Yom HaShoah etc.)
  29.   The weekly Sedrah
  30.   The day of the week
  31.   The days of the Omer
  32.  
  33. This program is DISTRIBU-WARE. 
  34. It may be distributed freely, with a few conditions:
  35.    1) The package must be distributed INTACT with ALL source code, as
  36.    well as this file.  You are welcome to modify the code,
  37.    but DON'T distribute it modified.  This disclaimer should certainly
  38.    appear with every distributed copy.
  39.    
  40.    2) You can use this program for free for one week.  After that
  41.    trial period, if you wish to use this program, drop me a line.
  42.    I'd like to know who you are, how you're using hebcal, and any
  43.    thing else you'd like to tell me.  
  44.  
  45.    I am NOT asking for monetary payment for the use of my program, but
  46.    if you use my program for more than one week without letting me
  47.    know about it, I'd rather you didn't use it. 
  48.  
  49.    send US Mail to:        send email to:
  50.     Danny Sadinoff       sadinoff@eniac.seas.upenn.edu
  51.     1 Cove La. 
  52.     Great Neck, NY 11024
  53.  
  54.    Email respondents will receive new versions of the program as they
  55.    come out, as will US Mail responents (if they send me postage for a disk).
  56.  
  57.    If you do not mail me or email me after one week, please don't
  58.    use the program, although you may feel free to distribute it further.
  59.  
  60. #! /bin/sh
  61. # This is a shell archive.  Remove anything before this line, then feed it
  62. # into a shell via "sh file" or similar.  To overwrite existing files,
  63. # type "sh file -c".
  64. # Contents:  README Makefile danlib.c danlib.h error.c error.h greg.c
  65. #   greg.h hebcal.c
  66. # Wrapped by kent@sparky on Wed Nov  4 08:23:41 1992
  67. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  68. echo If this archive is complete, you will see the following message:
  69. echo '          "shar: End of archive 1 (of 1)."'
  70. if test -f 'README' -a "${1}" != "-c" ; then 
  71.   echo shar: Will not clobber existing file \"'README'\"
  72. else
  73.   echo shar: Extracting \"'README'\" \(4104 characters\)
  74.   sed "s/^X//" >'README' <<'END_OF_FILE'
  75. XHebcal 1.0 - a program for printing Jewish calendars
  76. X  by Danny Sadinoff
  77. X
  78. XDESCRIPTION
  79. XHebcal is a program which prints out the days in the Jewish calendar
  80. Xfor a given gregorian year.  Hebcal is fairly flexible in terms of which
  81. Xevents in the Jewish calendar it displays.  Each of the following can
  82. Xbe individualy turned on or off:
  83. X
  84. X  The Hebrew date
  85. X  Jewish Holdiays (including Yom Ha'atzmaut and Yom HaShoah etc.)
  86. X  The weekly Sedrah
  87. X  The day of the week
  88. X  The days of the Omer
  89. X
  90. XOPERATION:
  91. XThe operation of hebcal is fairly simple.  Hebcal defaults to printing
  92. Xout the holidays for the current gregorian year.  With the
  93. Xcommand-line options, a specific gregorian year, month or date can be
  94. Xspecified.  
  95. X
  96. XGiven one numeric argument, hebcal will print out the calendar 
  97. Xfor that year.  Given two numeric argumetnts mm yyyy, it
  98. Xprints out the calendar for month mm of year yyyy.  Given three
  99. Xnumeric arguments mm dd yyyy, it will print out the hebrew calendar
  100. Xentries for day dd of month mm of year yyyy.
  101. X
  102. Xusage: hebcal [-dhoptw] [[month [day]] year]  
  103. X       hebcal help --- prints this message. 
  104. X
  105. XOPTIONS:   -d : add hebrew dates
  106. X   -h : suppress holidays
  107. X   -t : only output for today's date
  108. X   -o : add days of the omer
  109. X   -p : add weekly parshiot, including hachodesh, etc 
  110. X   -w : add day of the week
  111. X
  112. X
  113. XExamples: 
  114. Xexample% hebcal -ho
  115. X4/19/1992 1st day of the Omer
  116. X4/20/1992 2nd day of the Omer
  117. X4/21/1992 3rd day of the Omer
  118. X4/22/1992 4th day of the Omer
  119. X4/23/1992 5th day of the Omer
  120. X4/24/1992 6th day of the Omer
  121. X.
  122. X.
  123. X6/5/1992 48th day of the Omer
  124. X6/6/1992 49th day of the Omer
  125. X
  126. Xto print out all of the data pertaining to today's date, use
  127. Xexample% hebcal -tdwo
  128. X10/26/1992 Mon, 29 of Tishrei, 5753
  129. X
  130. XCOMPILATION
  131. XSome versions of cc will not compile hebcal as it is written now.  Use
  132. Xgcc if you can.  If nothing seems to work, let me know and I'll try to
  133. Xcome up with something.
  134. X
  135. XDISCLAIMER
  136. XI tried to make this program as accurate as possible.  However, I
  137. Xtake no responsibility for any horrible consequences which may come
  138. Xabout as a result of faulty output from this program.  Remember: never
  139. Xtrust a program with a zero at the end of its revision number.
  140. X
  141. XThe secular dates before 1522 are meaningless, as I made no correction
  142. Xfor the changeover from julian to gregorian calendars; but the Hebrew
  143. Xdates and years are correct.
  144. X
  145. XThis program is DISTRIBU-WARE. 
  146. XIt may be distributed freely, with a few conditions:
  147. X   1) The package must be distributed INTACT with ALL source code, as
  148. X   well as this file.  You are welcome to modify the code,
  149. X   but DON'T distribute it modified.  This disclaimer should certainly
  150. X   appear with every distributed copy.
  151. X   
  152. X   2) You can use this program for free for one week.  After that
  153. X   trial period, if you wish to use this program, drop me a line.
  154. X   I'd like to know who you are, how you're using hebcal, and any
  155. X   thing else you'd like to tell me.  
  156. X
  157. X   I am NOT asking for monetary payment for the use of my program, but
  158. X   if you use my program for more than one week without letting me
  159. X   know about it, I'd rather you didn't use it. 
  160. X
  161. X   send US Mail to:        send email to:
  162. X    Danny Sadinoff       sadinoff@eniac.seas.upenn.edu
  163. X    1 Cove La. 
  164. X    Great Neck, NY 11024
  165. X
  166. X   Email respondents will receive new versions of the program as they
  167. X   come out, as will US Mail responents (if they send me postage for a disk).
  168. X
  169. X   If you do not mail me or email me after one week, please don't
  170. X   use the program, although you may feel free to distribute it further.
  171. X
  172. XCOMING SOON
  173. XFeatures to be included in future versions:
  174. X  - A manpage
  175. X  - The ability to specify and output a particular HEBREW year, month
  176. X    or date.   The absence of this feature is a serious drawback to
  177. X    hebcal as it now stands.
  178. X  - the ability to supress gregorian date output
  179. X  - calendar-like operation with user specified "holidays", 
  180. X       e.g. birthdays, yahrtzeits.
  181. X  - yahrtzeit lists: calculate a list of dates in successive gregorian
  182. X       years with the same Hebrew date.
  183. X
  184. X
  185. XGRIPES
  186. Xsend questions, comments or complaints to:
  187. XDanny Sadinoff
  188. Xsadinoff@eniac.seas.upenn.edu
  189. END_OF_FILE
  190.   if test 4104 -ne `wc -c <'README'`; then
  191.     echo shar: \"'README'\" unpacked with wrong size!
  192.   fi
  193.   # end of 'README'
  194. fi
  195. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  196.   echo shar: Will not clobber existing file \"'Makefile'\"
  197. else
  198.   echo shar: Extracting \"'Makefile'\" \(135 characters\)
  199.   sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  200. X#you may have to de-comment the following line.
  201. X#CC= gcc
  202. XOBJ= hebcal.o greg.o error.o danlib.o
  203. Xhebcal:  $(OBJ)
  204. X    $(CC) -o hebcal $(OBJ)
  205. END_OF_FILE
  206.   if test 135 -ne `wc -c <'Makefile'`; then
  207.     echo shar: \"'Makefile'\" unpacked with wrong size!
  208.   fi
  209.   # end of 'Makefile'
  210. fi
  211. if test -f 'danlib.c' -a "${1}" != "-c" ; then 
  212.   echo shar: Will not clobber existing file \"'danlib.c'\"
  213. else
  214.   echo shar: Extracting \"'danlib.c'\" \(1158 characters\)
  215.   sed "s/^X//" >'danlib.c' <<'END_OF_FILE'
  216. X#include "danlib.h"
  217. X
  218. X/* Some generally useful routines */
  219. X  
  220. Xvoid initStr(char **s, int size){
  221. X  /* allocate space for a string */
  222. X  if ((*s = (char *)malloc((size + 1) * sizeof(char))) == NULL)
  223. X    die("\n Memory Error: Couldn't allocate string\n","");
  224. X
  225. X  **s = '\0';
  226. X}
  227. X
  228. Xint isAllNums(char * s){
  229. X/* returns true if a string contains only digits, dashes and newlines */
  230. X  int n = 0, len = strlen(s);
  231. X  
  232. X  for(n=0;
  233. X      (n < len)
  234. X      &&  (isdigit(s[n])) || (s[n] == '-') || (s[n] == '\n');
  235. X      n++);
  236. X  return (n == len);
  237. X}
  238. X
  239. Xchar * numSuffix(int i){
  240. X/* returns a pointer to the proper ordinal suffix of a number */
  241. X  switch (i % 10) {
  242. X  case 1 : return "st";
  243. X  case 2 : return "nd";
  244. X  case 3 : return "rd";
  245. X  default: return "th";
  246. X  }
  247. X}
  248. X
  249. Xchar * itoa(int i) {
  250. X  static char ret[7];
  251. X  int c = 0;
  252. X  char tmp;
  253. X
  254. X  if (i < 0) {            /* is i negative? */
  255. X    ret[c++] = '-';        /* then put a minus */
  256. X    i = abs(i);
  257. X  }
  258. X  
  259. X  while (i >0) {        /* compose the number */
  260. X    ret[c++] = (i % 10) + '0';
  261. X    i /= 10;
  262. X  }
  263. X  i = c-1;
  264. X  
  265. X  for (c =0; c < i; c++) {    /* reverse the number */
  266. X    tmp = ret[c];
  267. X    ret[c] = ret[i-c];
  268. X    ret[i-c] = tmp;
  269. X  } 
  270. X
  271. X  return ret;
  272. X}
  273. X
  274. END_OF_FILE
  275.   if test 1158 -ne `wc -c <'danlib.c'`; then
  276.     echo shar: \"'danlib.c'\" unpacked with wrong size!
  277.   fi
  278.   # end of 'danlib.c'
  279. fi
  280. if test -f 'danlib.h' -a "${1}" != "-c" ; then 
  281.   echo shar: Will not clobber existing file \"'danlib.h'\"
  282. else
  283.   echo shar: Extracting \"'danlib.h'\" \(176 characters\)
  284.   sed "s/^X//" >'danlib.h' <<'END_OF_FILE'
  285. X#include <stdio.h>
  286. X#include "error.h"
  287. X
  288. X#define CHAR2NUM(x) ((x) - '0')
  289. X
  290. Xint isAllNums(char * s);
  291. Xvoid initStr(char **s, int size);
  292. Xchar * numSuffix(int i);
  293. Xchar * itoa(int i);
  294. END_OF_FILE
  295.   if test 176 -ne `wc -c <'danlib.h'`; then
  296.     echo shar: \"'danlib.h'\" unpacked with wrong size!
  297.   fi
  298.   # end of 'danlib.h'
  299. fi
  300. if test -f 'error.c' -a "${1}" != "-c" ; then 
  301.   echo shar: Will not clobber existing file \"'error.c'\"
  302. else
  303.   echo shar: Extracting \"'error.c'\" \(613 characters\)
  304.   sed "s/^X//" >'error.c' <<'END_OF_FILE'
  305. X#include <stdio.h>
  306. X#include "error.h"
  307. X
  308. X
  309. Xextern int errno, sys_nerr;
  310. Xextern char *sys_errlist[], *progname;
  311. X
  312. Xvoid die (char * s1, char *s2){    /* print error message and die */
  313. X  if (progname)
  314. X    fprintf(stderr, "%s: ", progname);
  315. X  fprintf(stderr, s1, s2);
  316. X  if (errno > 0 && errno < sys_nerr)
  317. X    fprintf(stderr, " (%s)\n", sys_errlist[errno]);
  318. X  exit(1);
  319. X}
  320. X
  321. Xvoid warn (char * s1, char *s2){    /* print error message */
  322. X  if (progname)                /* but don't die*/
  323. X    fprintf(stderr, "%s: ", progname);
  324. X  fprintf(stderr, s1, s2);
  325. X  if (errno > 0 && errno < sys_nerr)
  326. X    fprintf(stderr, " (%s)\n", sys_errlist[errno]);
  327. X}
  328. END_OF_FILE
  329.   if test 613 -ne `wc -c <'error.c'`; then
  330.     echo shar: \"'error.c'\" unpacked with wrong size!
  331.   fi
  332.   # end of 'error.c'
  333. fi
  334. if test -f 'error.h' -a "${1}" != "-c" ; then 
  335.   echo shar: Will not clobber existing file \"'error.h'\"
  336. else
  337.   echo shar: Extracting \"'error.h'\" \(85 characters\)
  338.   sed "s/^X//" >'error.h' <<'END_OF_FILE'
  339. X#include <errno.h>
  340. X
  341. Xvoid die (char * s1, char *s2);
  342. Xvoid warn (char * s1, char *s2);
  343. END_OF_FILE
  344.   if test 85 -ne `wc -c <'error.h'`; then
  345.     echo shar: \"'error.h'\" unpacked with wrong size!
  346.   fi
  347.   # end of 'error.h'
  348. fi
  349. if test -f 'greg.c' -a "${1}" != "-c" ; then 
  350.   echo shar: Will not clobber existing file \"'greg.c'\"
  351. else
  352.   echo shar: Extracting \"'greg.c'\" \(2719 characters\)
  353.   sed "s/^X//" >'greg.c' <<'END_OF_FILE'
  354. X#include <stdio.h>
  355. X#include <stdlib.h>
  356. X#include "greg.h"
  357. X
  358. X/* greg.c gregorian calendar module for hebrew calendar program
  359. X   By Danny Sadinoff
  360. X
  361. X   $Date: 92/10/26 20:26:37 $
  362. X   $Revision: 1.0 $
  363. X
  364. X*/ 
  365. X
  366. Xchar * eMonths[] = { 
  367. X  "January","February","March","April","May","June","July",
  368. X  "August","September","October","November","December"
  369. X  };
  370. X              
  371. Xint MonthLengths[][12] ={ 
  372. X  {31,28,31,30,31,30,31,31,30,31,30,31},
  373. X  {31,29,31,30,31,30,31,31,30,31,30,31}
  374. X};
  375. X
  376. Xchar * DayNames[] = {
  377. X  "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
  378. X  };
  379. X
  380. Xchar * ShortDayNames[] = {
  381. X  "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
  382. X  };
  383. X
  384. Xstatic int checkRange (date_t dt,char * routine) {
  385. X  if ((dt.mm > 13)||(dt.dd > 31) || (dt.yy > 7000) || 
  386. X      (dt.mm <0)  ||(dt.dd <0  ) || (dt.yy < -7000))
  387. X    die("Date out of range from routine %s.",routine);
  388. X}
  389. X
  390. Xstatic long int daysSinceOrigin (date_t dt){
  391. X  int m,y,days = 0;
  392. X
  393. X  checkRange(dt,"daysSinceOrigin");
  394. X
  395. X  for (y =1; y < dt.yy; y++)
  396. X    days += DAYS_IN(y);
  397. X  y = dt.yy;
  398. X  for (m= JAN; m < dt.mm; m++)
  399. X    days += MonthLengths[LEAP(y)][m];
  400. X  days += dt.dd -1;
  401. X  return days;
  402. X}
  403. X
  404. Xint diffDays(date_t d1, date_t d2){
  405. X  return (int) (daysSinceOrigin(d1) - daysSinceOrigin(d2));
  406. X}
  407. X
  408. Xint exceeds (date_t d1, date_t d2) {
  409. X  if (d1.yy > d2.yy)
  410. X    return 1;
  411. X  else if (d1.yy < d2.yy)
  412. X    return 0;
  413. X  else if (d1.mm > d2.mm)
  414. X    return 1;
  415. X  else if (d1.mm < d2.mm)
  416. X    return 0;
  417. X  else if (d1.dd > d2.dd)
  418. X    return 1;
  419. X  else return 0;
  420. X}
  421. X
  422. Xvoid decDate (date_t *dt, int n){ /* decrements dt by n days */
  423. X/*under construction*/
  424. X/*  while (n > 365) {
  425. X    n -= DAYS_IN(dt->yy -1);
  426. X    dt ->yy--;
  427. X  }
  428. X
  429. X
  430. X  if ((dt->mm == FEB) && (dt->dd == 29) && !LEAP(dt->yy))
  431. X    dt->dd--;
  432. X*/
  433. X  
  434. X  while (n--) 
  435. X    if (dt->dd ==1) {
  436. X      if (dt->mm == JAN) {
  437. X    dt->yy--;
  438. X    dt->mm = DEC;
  439. X    dt->dd = 31;
  440. X      }
  441. X      else {
  442. X    dt->mm--;
  443. X    dt->dd = MonthLengths[LEAP(dt->yy)][dt->mm];
  444. X      }
  445. X    }
  446. X    else dt->dd--;
  447. X}
  448. X
  449. Xvoid incDate(date_t *dt, int n)    { /* increments dt by n days */
  450. X
  451. X/*  while (n > 365) {
  452. X    n -= DAYS_IN(dt->yy);
  453. X    dt->yy++;
  454. X  }
  455. X
  456. X  if ((dt->mm == FEB) && (dt->dd == 29) && !LEAP(dt->yy) ) {
  457. X    dt-> mm = MAR;
  458. X    dt-> dd = 1;
  459. X  }
  460. X*/
  461. X  while (n--) 
  462. X   if ((dt->dd + 1) > MonthLengths[LEAP(dt->yy)][dt->mm]) 
  463. X     if (dt->mm == DEC) {
  464. X       dt->yy++;
  465. X       dt->mm = JAN;
  466. X       dt->dd = 1;
  467. X     }
  468. X     else {
  469. X       dt->mm++;
  470. X       dt->dd =1;
  471. X     }
  472. X   else 
  473. X     dt->dd ++;
  474. X}
  475. X
  476. Xint dayOfWeek(date_t d1) {    /* sunday = 0 */
  477. X  return (int) ((daysSinceOrigin(d1) + 1) % 7 ) ;
  478. X}
  479. X
  480. Xvoid setDate (date_t *d) {
  481. X  time_t secs;
  482. X  struct tm *loctm;
  483. X
  484. X  secs = time(NULL);
  485. X  loctm = localtime(&secs);
  486. X  d->yy = 1900 + loctm->tm_year;
  487. X  d->mm = loctm->tm_mon;
  488. X  d->dd = loctm->tm_mday;
  489. X}
  490. X
  491. X
  492. END_OF_FILE
  493.   if test 2719 -ne `wc -c <'greg.c'`; then
  494.     echo shar: \"'greg.c'\" unpacked with wrong size!
  495.   fi
  496.   # end of 'greg.c'
  497. fi
  498. if test -f 'greg.h' -a "${1}" != "-c" ; then 
  499.   echo shar: Will not clobber existing file \"'greg.h'\"
  500. else
  501.   echo shar: Extracting \"'greg.h'\" \(705 characters\)
  502.   sed "s/^X//" >'greg.h' <<'END_OF_FILE'
  503. X#include <time.h>
  504. X
  505. X#define LEAP(x) (!((x) % 4) && ( ((x) % 100) || !((x) % 400)))
  506. X#define DAYS_IN(x) (LEAP((x))?366:365)
  507. X
  508. Xenum {JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV,DEC};
  509. Xenum {SUN,MON,TUE,WED,THU,FRI,SAT};
  510. Xextern char * eMonths[];
  511. Xextern int MonthLengths[][12] ;
  512. Xextern char * DayNames[] ;
  513. Xextern char * ShortDayNames[];
  514. Xextern char * eDays[] ;
  515. X
  516. Xtypedef struct {
  517. X  int mm;    /* months since january 0,11*/
  518. X  int dd;    /* day of month 1,31 */
  519. X  int yy;    /* years since year 1 BCE i.e. -1 = 2 BCE */
  520. X  } date_t;
  521. X
  522. Xint diffDays(date_t d1, date_t d2);
  523. Xint exceeds (date_t d1, date_t d2);
  524. Xvoid decDate (date_t *dt, int n);
  525. Xvoid incDate(date_t *dt, int n);
  526. Xint dayOfWeek(date_t d1);
  527. Xvoid setDate (date_t *d);
  528. END_OF_FILE
  529.   if test 705 -ne `wc -c <'greg.h'`; then
  530.     echo shar: \"'greg.h'\" unpacked with wrong size!
  531.   fi
  532.   # end of 'greg.h'
  533. fi
  534. if test -f 'hebcal.c' -a "${1}" != "-c" ; then 
  535.   echo shar: Will not clobber existing file \"'hebcal.c'\"
  536. else
  537.   echo shar: Extracting \"'hebcal.c'\" \(19232 characters\)
  538.   sed "s/^X//" >'hebcal.c' <<'END_OF_FILE'
  539. X#include <stdio.h>
  540. X#include <stdlib.h>
  541. X#include <time.h>
  542. X#include "error.h"
  543. X#include "danlib.h"
  544. X#include "greg.h"
  545. X/* hebcal.c main module for hebrew calendar program
  546. X   By Danny Sadinoff
  547. X
  548. X   $Date: 92/10/26 20:13:23 $
  549. X   $Revision: 1.0 $
  550. X
  551. X*/ 
  552. X
  553. X  int parshiot_sw, hebDates_sw, specMonth_sw,specDay_sw,
  554. X  weekday_sw, supressHolidays_sw, printOmer_sw, omer;
  555. X
  556. Xtypedef struct {
  557. X  
  558. X  char * name;
  559. X  int length;
  560. X  
  561. X  int daysInCheshvan;
  562. X  int daysInKislev;
  563. X  
  564. X  int vayakhelPikudei;    /* double parsha flags */
  565. X  int tazriaMetzorah;
  566. X  int achreiKedoshim;
  567. X  int beharBech;
  568. X  int chukatBalak; 
  569. X  int matotMasei;
  570. X  int nitzavimVayelech;
  571. X  
  572. X} year_t;
  573. X
  574. X
  575. Xyear_t legend[2][8] = {
  576. X  {                /* stam years */
  577. X    {"1BX",353,29,29,1,1,1,1,0,1,1},    /* BX */
  578. X    {"1BS",355,30,30,1,1,1,1,1,1,1},    /* BS */
  579. X    {"2GC",354,29,30,1,1,1,1,1,1,1},    /* GC */
  580. X    {"4HC",354,29,30,1,1,1,1,0,1,0},    /* HC */ 
  581. X    {"0error - HX",354,29,29,1,1,1,1,0,1,0},    /* error! hx */
  582. X    {"4HS",355,30,30,0,1,1,1,0,1,0},    /* HS */
  583. X    {"6ZX",353,29,29,1,1,1,1,0,1,0},    /* ZX */
  584. X    {"6ZS",355,30,30,1,1,1,1,0,1,1},    /* ZS */
  585. X  },
  586. X  {                /* leap years */
  587. X    {"1BX",383,29,29,0,0,0,0,1,1,1},    /* BX */
  588. X    {"1BS",385,30,30,0,0,0,0,0,1,0},    /* BS */
  589. X    {"2GC",384,29,30,0,0,0,0,0,1,0},    /* GC */
  590. X    {"0error - HC",383,29,30,0,0,0,0,0,0,0},    /* error ! hc */
  591. X    {"4HX",383,29,29,0,0,0,0,0,0,0},    /* HX */
  592. X    {"4HS",385,30,30,0,0,0,0,0,0,1},    /* HS */
  593. X    {"6ZX",383,29,29,0,0,0,0,0,1,1},    /* ZX */
  594. X    {"6ZS",385,30,30,0,0,0,0,1,1,1},    /* ZS */
  595. X  }
  596. X};
  597. X
  598. Xint leapYears[] = {0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1};
  599. X
  600. Xenum {BX,BS,GC,HC,HX,HS,ZX,ZS};
  601. X
  602. Xint luach[][19] = 
  603. X{
  604. X  {HC,BX,HS,HC,BS,ZX,HC,BS,BX,HS,GC,BS,ZX,GC,BS,ZS,HX,GC,ZS},
  605. X  {ZS,HC,BX,ZS,HC,BX,ZS,HS,HC,BX,HS,HC,BS,ZX,HC,BS,ZX,HS,GC},
  606. X  {BS,ZX,GC,BS,ZS,HX,GC,ZS,ZS,HC,BX,ZS,HC,BS,BX,HC,BS,BS,ZX},
  607. X  {HC,HS,ZX,HC,HS,ZS,ZX,GC,BS,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BX},
  608. X  {ZS,HC,BS,BX,HC,BS,BS,ZX,HC,BS,ZX,HS,GC,ZS,ZS,HC,BX,ZS,HX},
  609. X  {GC,ZS,HS,HC,BX,HS,HC,BX,ZS,HC,BS,BX,HS,GC,BS,ZX,GC,BS,ZS},
  610. X  {ZX,GC,ZS,ZS,HC,BX,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BS,ZX,HC,BS},
  611. X  {BS,ZX,GC,BS,ZS,HX,GC,ZS,ZX,GC,ZS,ZS,HC,BX,ZS,HC,BS,BX,HS},
  612. X  {HC,BS,ZX,HC,BS,ZX,HS,GC,BS,ZX,GC,BS,ZS,HX,GC,ZS,HS,HC,BX},
  613. X  {ZS,HC,BX,ZS,HC,BS,BX,HS,HC,BS,ZX,HC,BS,ZX,HS,GC,ZS,ZX,GC},
  614. X  {BS,ZS,HX,GC,ZS,HS,HC,BX,ZS,HC,BX,ZS,HC,BS,BX,HS,GC,BS,ZX}, /* 10,11 GX? */
  615. X  {HC,BS,ZS,ZX,GC,ZS,ZS,HX,GC,ZS,HX,GC,ZS,HS,HC,BX,HS,HC,BS},
  616. X  {BX,HC,BS,BS,ZX,GC,BS,ZX,HS,GC,ZS,ZS,HC,BX,ZS,HC,BX,ZS,HS}
  617. X};
  618. X
  619. Xstruct {
  620. X  char * name;
  621. X  int length;
  622. X}hMonths[][14] = {
  623. X  {  
  624. X    {"Tishrei",30}, {"Cheshvan",29}, {"Kislev",30},
  625. X    {"Tevet",29}, {"Shvat",30}, {"Adar",29},
  626. X    {"Nisan",30}, {"Iyyar",29}, {"Sivan",30},
  627. X    {"Tamuz",29}, {"Av",30},{"Elul",29},{"Tishrei",30}},
  628. X  {
  629. X    {"Tishrei",30}, {"Cheshvan",29}, {"Kislev",30},
  630. X    {"Tevet",29}, {"Shvat",30}, {"Adar I",29}, {"Adar II",30},
  631. X    {"Nisan",30}, {"Iyyar",29}, {"Sivan",30},
  632. X    {"Tamuz",29}, {"Av",30},{"Elul",29},{"Tishrei",30}}    
  633. X};
  634. X
  635. Xenum {TISHREI, CHESHVAN, KISLEV, ADAR_2 = 6};
  636. X
  637. Xchar * sedrot[] = { 
  638. X  
  639. X  "Bereshit", "Noach", "Lech Lecha", "Vayera", "Chayei Sara",
  640. X  "Toldot", "Vayetzei", "Vayishlach", "Vayeshev", "Miketz", "Vayigash",
  641. X  "Vayechi",
  642. X  
  643. X  "Sh'mot", "Vaera", "Bo", "Beshalach", "Yitro", "Mishpatim",
  644. X  "Terumah", "Tetzaveh", "Ki Tisa", "Vayakhel", "Pekudei",
  645. X  
  646. X  "Vayikra", "Tzav", "Shmini", "Tazria", "Metzora", "Achrei Mot",
  647. X  "Kedoshim", "Emor", "Behar", "Bechukosai",
  648. X  
  649. X  "Bamidbar", "Nasso", "Beha'aloscha", "Sh'lach", "Korach", "Chukat",
  650. X  "Balak", "Pinchas", "Matot", "Masei",
  651. X  
  652. X  "Devarim", "Vaetchanan", "Eikev", "Re'eh", "Shoftim", 
  653. X  "Ki Teitzei", "Ki Tavo", "Nitzavim", "Vayeilech", "Ha'Azinu", 
  654. X  "V'Zot Habracha"
  655. X  };
  656. X
  657. Xenum { VAYAKHEL = 21, 
  658. X     TAZRIA = 26, ACHREI = 28,
  659. X     BEHAR = 31,
  660. X     CHUKAT = 38, MATOT= 41, 
  661. X     NITZAVIM = 50};
  662. X
  663. X#define NM_LEN 30
  664. Xtypedef struct hnode{
  665. X  date_t date;
  666. X  char *name;
  667. X  int ownSedra;
  668. X  int nidche;
  669. X  int mukdam;
  670. X  int mukdam2;
  671. X  struct hnode *next;
  672. X} holiday_t, *holidayp_t;
  673. X
  674. Xholiday_t special[100];
  675. X
  676. Xholiday_t holidays[] = {    /* 5 = Adar I */
  677. X  /* 6 = Adar = Adar II */
  678. X  {{0,1},"Rosh Hashana I",1},{{0,2},"Rosh Hashana II",1},
  679. X  {{0,3},"Tzom Gedalia",0,1},
  680. X  {{0,9},"Erev Yom Kippur"},
  681. X  {{0,10},"Yom Kippur",1},
  682. X  
  683. X  {{0,15},"Sukkot I",1},{{0,16},"Sukkot II",1},
  684. X  {{0,17},"Sukkot III (CH\"M)",1},{{0,18},"Sukkot IV (CH\"M)",1},
  685. X  {{0,19},"Sukkot V (CH\"M)",1},{{0,20},"Sukkot VI (CH\"M)",1},
  686. X  {{0,21},"Sukkot VII (Hoshana Raba)",1},
  687. X  {{0,22},"Shmini Atzeret",1},{{0,23},"Simchat Torah",1},
  688. X  
  689. X  {{2,25},"Chanukah"},
  690. X  {{3,10},"Asara B'Tevet",0,1},
  691. X  {{4,15},"Tu B'Shevat"}  /*,0,1}?*/,
  692. X  
  693. X  {{5,15},"Purim katan"},
  694. X  {{6,14},"Ta'anit Esther",0,0,1},{{6,15},"Purim"},
  695. X  {{6,16},"Shushan Purim"}, 
  696. X  
  697. X  {{7,14},"Erev Pesach - Taanit B'chorot",0},
  698. X#define PESACH2_STR "Pesach II"
  699. X  {{7,15},"Pesach I",1},{{7,16},PESACH2_STR,1},
  700. X  {{7,17},"Pesach III (CH\"M)",1},{{7,18},"Pesach IV (CH\"M)",1},
  701. X  {{7,19},"Pesach V (CH\"M)",1},{{7,20},"Pesach VI (CH\"M)",1},
  702. X  {{7,21},"Pesach VII",1},
  703. X  {{7,22},"Pesach VIII",1},
  704. X  
  705. X  {{7,27},"Yom HaShoah"},
  706. X  {{8,4},"Yom HaZikaron",0,0,0,1},
  707. X  {{8,5},"Yom Ha'atzmaut",0,0,1},
  708. X#define SHAVUOT_STR "Shavuot I"
  709. X  {{9,6},SHAVUOT_STR,1},{{9,7},"Shavuot II",1},
  710. X  {{10,17},"Shiva Assar B'Tamuz",0,1},
  711. X  {{11,9},"Tish'a B'Av",0,1},
  712. X  {{12,29},"Erev Rosh Hashana"}
  713. X};
  714. X
  715. Xenum {SIMCHAT_DAY = 23};
  716. X/* = {
  717. X   {{0,0},"Shabbat Shekalim"},
  718. X   {{0,0},"Shabbat Zachor"},
  719. X   {{0,0},"Parshat HaChodesh"},
  720. X   {{0,0},"Parshat Parah"},
  721. X   {{0,0},"Yom Yerushalayim"}
  722. X   };*/
  723. X
  724. X
  725. X#define LEAP_YR_HEB(x) (leapYears[((x) -1) % 19])
  726. X#define MONTHS_IN_HEB(x) (LEAP_YR_HEB(x) ? 13 :12)
  727. X
  728. Xyear_t yearData(int yr){
  729. X  return legend[LEAP_YR_HEB(yr)][luach[((yr-1)/19+7)%13][(yr-1) %19]];
  730. X}
  731. X
  732. X#define LAST_INDEX(x) (sizeof x / sizeof x[0])
  733. X
  734. Xint daysInHebMonth(int month, int year) {
  735. X  year_t theYear;
  736. X  
  737. X  theYear = yearData(year);
  738. X  if (month == CHESHVAN) 
  739. X    return theYear.daysInCheshvan;
  740. X  else if (month == KISLEV)
  741. X    return theYear.daysInKislev;
  742. X  else return hMonths[LEAP_YR_HEB(year)][month].length;
  743. X}
  744. X
  745. Xdate_t nextHebDate (date_t dth) {
  746. X  dth.dd++;
  747. X  if (dth.dd > daysInHebMonth(dth.mm,dth.yy))
  748. X    if (dth.mm ==  MONTHS_IN_HEB(dth.yy)-1){
  749. X      dth.yy++;
  750. X      dth.mm =0;
  751. X      dth.dd =1;
  752. X    }
  753. X    else {
  754. X      dth.mm++;
  755. X      dth.dd =1;
  756. X    }
  757. X  return dth;
  758. X}
  759. X
  760. Xdate_t prevHebDate (date_t dth) {
  761. X  dth.dd--;
  762. X  if (dth.dd == 0)
  763. X    if (dth.mm == 0) {
  764. X      dth.yy--;
  765. X      dth.mm = MONTHS_IN_HEB(dth.yy) -1 ;
  766. X      dth.dd = daysInHebMonth(dth.mm,dth.yy);
  767. X    }
  768. X    else {
  769. X      dth.mm--;
  770. X      dth.dd = daysInHebMonth(dth.mm,dth.yy);
  771. X    }
  772. X  return dth;
  773. X}
  774. X
  775. XaddHoliday(holiday_t theHoliday, holiday_t **holiList){
  776. X  holidayp_t newHol, currHol = *holiList;
  777. X  
  778. X  if (currHol) 
  779. X    while (currHol->next)    /* scan to the end of the list */
  780. X      currHol = currHol->next; /* now currhol points to the last */
  781. X  
  782. X  if (!(newHol = (holiday_t *) malloc(sizeof (holiday_t))))
  783. X    die("Mem allocation error in getHebHolidays routine.","");
  784. X  
  785. X  if (currHol)
  786. X    currHol->next = newHol;
  787. X  else *holiList = newHol;
  788. X  
  789. X  *newHol = theHoliday;
  790. X  newHol->next = NULL;
  791. X}
  792. X
  793. Xholidayp_t getHebHolidays (date_t dt,   /* returns a linked list */
  794. X               int weekday, /* of holidays for that date. */
  795. X               year_t theYear, 
  796. X               holiday_t ** holiList) {
  797. X  int c, specialCounter=0;
  798. X  holidayp_t tmpholip;
  799. X  
  800. X  *holiList = NULL;
  801. X  
  802. X#define CORRECTION(yy,mm) (LEAP_YR_HEB(yy) ? 0 : (((mm) > 4) ? 1: 0))
  803. X#define MATCH(X,Y) ((X.mm == (Y.mm + CORRECTION(Y.yy,Y.mm)) ) && (X.dd == Y.dd))
  804. X  
  805. X  for (c = 0; c < LAST_INDEX(holidays); c++) {
  806. X    if (MATCH(holidays[c].date,dt))
  807. X      if (!((weekday == SAT) && (holidays[c].nidche)) &&
  808. X      !(holidays[c].mukdam &&
  809. X        ((weekday == FRI) || (weekday == SAT))) &&
  810. X      !(holidays[c].mukdam2 &&
  811. X        ((weekday == THU) || (weekday == FRI)))){/* do normal holidays*/
  812. X    addHoliday(holidays[c],holiList);
  813. X    if (!strcmp((*holiList)->name,PESACH2_STR)) omer++;
  814. X    if (omer && holiList && !strcmp((*holiList)->name,SHAVUOT_STR)) omer=0;
  815. X      }
  816. X    
  817. X    
  818. X    if (holidays[c].nidche &&    /* fast days which are */
  819. X    (MATCH(holidays[c].date,prevHebDate(dt))) && 
  820. X    (weekday ==SUN)){
  821. X      char *st;
  822. X      
  823. X      initStr(&st,NM_LEN);
  824. X      strncat(st,holidays[c].name,NM_LEN);
  825. X      strncat(st," [nidche]",NM_LEN);
  826. X      addHoliday(holidays[c],holiList); 
  827. X      (*holiList)->name = st;
  828. X    }
  829. X    
  830. X    if (holidays[c].mukdam &&    /* if the date actually falls */
  831. X    (MATCH(holidays[c].date,nextHebDate(nextHebDate(dt))) ||
  832. X     MATCH(holidays[c].date,nextHebDate(dt))) &&
  833. X    (weekday == THU))                  /* on friday or shabbat*/
  834. X      addHoliday(holidays[c],holiList);
  835. X    
  836. X    if (holidays[c].mukdam2 && /* if the date actually falls */
  837. X    (MATCH(holidays[c].date,nextHebDate(nextHebDate(dt))) ||
  838. X     MATCH(holidays[c].date,nextHebDate(dt))) && 
  839. X    (weekday == WED))                  /* on thursday or friday*/
  840. X      addHoliday(holidays[c],holiList);
  841. X  }
  842. X  
  843. X  /* Lag B'Omer Processing */
  844. X  if (omer == 33) {
  845. X    tmpholip = &special[specialCounter++];
  846. X    initStr(&tmpholip->name,NM_LEN); 
  847. X    strncat(tmpholip->name,"Lag B'Omer",NM_LEN);
  848. X    addHoliday(*tmpholip,holiList);
  849. X  }
  850. X  
  851. X  /* rosh Chodesh Processing... */
  852. X  if ((dt.dd == 1)&& dt.mm){    /* every 1st of the month except tishrei */
  853. X    tmpholip = &special[specialCounter++];
  854. X    initStr(&tmpholip->name,NM_LEN); 
  855. X    strcat(tmpholip->name,"Rosh Chodesh ");
  856. X    strncat(tmpholip->name,hMonths[LEAP_YR_HEB(dt.yy)][dt.mm].name,NM_LEN);
  857. X    addHoliday(*tmpholip,holiList);
  858. X  }
  859. X  if (dt.dd == 30){
  860. X    tmpholip = &special[specialCounter++];
  861. X    initStr(&tmpholip->name,NM_LEN);
  862. X    strcat(tmpholip->name,"Rosh Chodesh ");
  863. X    strncat(tmpholip->name,hMonths[LEAP_YR_HEB(dt.yy)][dt.mm+1].name,NM_LEN);
  864. X    addHoliday(*tmpholip,holiList);
  865. X  }
  866. X  
  867. X  
  868. X  return *holiList;
  869. X}
  870. X
  871. X
  872. Xvoid incHebJulDate(date_t *dth, date_t *dtj, int *wkday){
  873. X  /* increments both hebrew and julian calendars */
  874. X  
  875. X  incDate (dtj,1);
  876. X  *wkday = dayOfWeek(*dtj);
  877. X  *dth = nextHebDate(*dth);
  878. X}   
  879. X
  880. X#define JUL2HEB(x) ((x) + 3760)
  881. X
  882. Xvoid PrintWeekday (date_t dt) {
  883. X  printf ("%s, ",ShortDayNames[dayOfWeek(dt)]);
  884. X}
  885. X
  886. Xvoid PrintJulDate (date_t dt) {
  887. X  printf ("%d/%d/%d ",dt.mm+1,dt.dd,dt.yy);
  888. X}
  889. X
  890. X
  891. Xchar *DoSedra (int *sedra,year_t ydat) {
  892. X#define PLENGTH 40
  893. X  static char s[PLENGTH+1];
  894. X  
  895. X  *s = '\0';
  896. X  strncat(s,"Parshat ",PLENGTH);
  897. X  strncat(s,sedrot[*sedra],PLENGTH);
  898. X  switch (*sedra) {
  899. X  case VAYAKHEL :
  900. X    if (ydat.vayakhelPikudei){
  901. X      strncat(s,"-",PLENGTH);
  902. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  903. X      *sedra += 2;
  904. X    }
  905. X    else {
  906. X      (*sedra)++;
  907. X    }
  908. X    break;
  909. X  case TAZRIA:
  910. X    if (ydat.tazriaMetzorah){
  911. X      strncat(s,"-",PLENGTH);
  912. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  913. X      *sedra += 2;
  914. X    }
  915. X    else {
  916. X      (*sedra)++;
  917. X    }
  918. X    break;
  919. X  case ACHREI :
  920. X    if (ydat.achreiKedoshim){
  921. X      strncat(s,"-",PLENGTH);
  922. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  923. X      *sedra += 2;
  924. X    }
  925. X    else {
  926. X      (*sedra)++;
  927. X    }
  928. X    break;
  929. X  case BEHAR :
  930. X    if (ydat.beharBech){
  931. X      strncat(s,"-",PLENGTH);
  932. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  933. X      *sedra += 2;
  934. X    }
  935. X    else {
  936. X      (*sedra)++;
  937. X    }
  938. X    break;
  939. X  case CHUKAT :
  940. X    if (ydat.chukatBalak){
  941. X      strncat(s,"-",PLENGTH);
  942. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  943. X      *sedra += 2;
  944. X    }
  945. X    else {
  946. X      (*sedra)++;
  947. X    }
  948. X    break;
  949. X  case MATOT :
  950. X    if (ydat.matotMasei){
  951. X      strncat(s,"-",PLENGTH);
  952. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  953. X      *sedra += 2;
  954. X    }
  955. X    else {
  956. X      (*sedra)++;
  957. X    }
  958. X    break;
  959. X  case NITZAVIM :
  960. X    if (ydat.nitzavimVayelech){
  961. X      strncat(s,"-",PLENGTH);
  962. X      strncat(s,sedrot[*sedra+1],PLENGTH);
  963. X      *sedra += 2;
  964. X    }
  965. X    else {
  966. X      (*sedra)++;
  967. X    }
  968. X    break;
  969. X  case LAST_INDEX(sedrot)-1:
  970. X    *sedra = 0;
  971. X    break;
  972. X  default:
  973. X    (*sedra)++;
  974. X  }
  975. X  strncat(s,"\n",PLENGTH);
  976. X  return s;
  977. X}
  978. X
  979. X#define CHAR2NUM(x) ((x) - '0')
  980. X
  981. X
  982. Xvoid DoCalendar (date_t roshDt,    /* rosh Hashana of preceeding year */
  983. X         int justMonth,/* print this month  */
  984. X         int justDay ){ /* print this day */
  985. X  
  986. X  
  987. X  int sedra,weekday;
  988. X  date_t todayh, todayj = roshDt;
  989. X  holiday_t *holip;
  990. X  year_t theYear;
  991. X  
  992. X  todayh.mm = 0;
  993. X  todayh.dd = 1;
  994. X  todayh.yy = JUL2HEB(roshDt.yy)+1; /* because it's after R"H */
  995. X  
  996. X  
  997. X  theYear = yearData(todayh.yy);
  998. X  
  999. X  if (CHAR2NUM(theYear.name[0]) != dayOfWeek(roshDt))
  1000. X    die ("Bad Day!\n","");  
  1001. X  
  1002. X  /* first scan forward to simchat Torah, keeping track of dates only. */
  1003. X  while (todayh.dd != SIMCHAT_DAY){
  1004. X#if defined(DEBUG)
  1005. X    PrintJulDate(todayj);
  1006. X    if (weekday_sw)
  1007. X      PrintWeekday(todayj);
  1008. X    printf ("%d of %s, %d\n",todayh.dd, /* print the hebrew date */
  1009. X        hMonths[LEAP_YR_HEB(todayh.yy)][todayh.mm].name,
  1010. X        todayh.yy);
  1011. X    
  1012. X#endif
  1013. X    incHebJulDate(&todayh, &todayj,&weekday);
  1014. X  }
  1015. X  sedra = 0;        /* initialize sedra */
  1016. X  
  1017. X  /* then continue until january 1st. */
  1018. X  do {
  1019. X    getHebHolidays(todayj,weekday,theYear,&holip);
  1020. X#if defined(DEBUG)
  1021. X    PrintJulDate(todayj);
  1022. X    if (weekday_sw)
  1023. X      PrintWeekday(todayj);
  1024. X    printf ("%d of %s, %d\n",todayh.dd, /* print the hebrew date */
  1025. X        hMonths[LEAP_YR_HEB(todayh.yy)][todayh.mm].name,
  1026. X        todayh.yy);
  1027. X    for (;holip;holip = holip->next) {
  1028. X      PrintJulDate(todayj);
  1029. X      if (weekday_sw)
  1030. X    PrintWeekday(todayj);
  1031. X      printf ("%s\n",holip->name);
  1032. X      }
  1033. X   
  1034. X    if ((weekday == SAT) && !(holip && holip->ownSedra)) 
  1035. X      printf("%s",DoSedra(&sedra,theYear));
  1036. X#else
  1037. X    if ((weekday == SAT) && !(holip && holip->ownSedra)) 
  1038. X      DoSedra(&sedra,theYear);
  1039. X#endif    
  1040. X    
  1041. X    incHebJulDate(&todayh,&todayj,&weekday);
  1042. X  } while (!((todayj.mm==0) && (todayj.dd==1)));
  1043. X  
  1044. X  /* -------Main Year Loop-------*/
  1045. X  do {
  1046. X    if (hebDates_sw && 
  1047. X    (!specMonth_sw || (justMonth== todayj.mm)) &&
  1048. X    (!specDay_sw   || (justDay == todayj.dd))) {
  1049. X      PrintJulDate(todayj);
  1050. X      if (weekday_sw)
  1051. X    PrintWeekday(todayj);
  1052. X      printf ("%d of %s, %d\n",todayh.dd, /* print the hebrew date */
  1053. X          hMonths[LEAP_YR_HEB(todayh.yy)][todayh.mm].name,
  1054. X          todayh.yy);
  1055. X    }
  1056. X    getHebHolidays(todayh,weekday,theYear,&holip);
  1057. X    
  1058. X    if ((todayh.mm == TISHREI) && (todayh.dd == 1))
  1059. X      theYear = yearData(todayh.yy); /* if R"H reset YearData */
  1060. X    
  1061. X    if (parshiot_sw && (weekday == SAT) && !(holip && holip->ownSedra)){
  1062. X      if ((!specMonth_sw || (justMonth == todayj.mm)) &&
  1063. X      (!specDay_sw   || (justDay == todayj.dd))){
  1064. X    PrintJulDate(todayj);    
  1065. X    printf("%s",DoSedra(&sedra,theYear));
  1066. X      }
  1067. X      else DoSedra(&sedra,theYear);
  1068. X    }
  1069. X    
  1070. X    if ((todayh.mm == TISHREI) && /* reset the sedra on simchat torah */
  1071. X    (todayh.dd == SIMCHAT_DAY)) sedra =0; 
  1072. X    
  1073. X    if (!supressHolidays_sw &&
  1074. X    (!specMonth_sw || (justMonth == todayj.mm)) &&
  1075. X    (!specDay_sw   || (justDay == todayj.dd))) 
  1076. X      for (;holip;holip = holip->next) {
  1077. X    PrintJulDate(todayj);
  1078. X    if (weekday_sw)
  1079. X      PrintWeekday(todayj);
  1080. X    printf ("%s\n",holip->name);
  1081. X      }
  1082. X    
  1083. X                /* print the omer if desired */
  1084. X    if (omer && printOmer_sw && 
  1085. X    (!specMonth_sw || (justMonth == todayj.mm)) &&
  1086. X    (!specDay_sw   || (justDay == todayj.dd))) {
  1087. X      char *omerStr;
  1088. X      initStr(&omerStr,NM_LEN); 
  1089. X      strncat(omerStr,itoa(omer),NM_LEN);
  1090. X      strncat(omerStr,numSuffix(omer),NM_LEN);
  1091. X      strncat(omerStr," day of the Omer",NM_LEN);
  1092. X      PrintJulDate(todayj);
  1093. X      if (weekday_sw) PrintWeekday(todayj);
  1094. X      printf ("%s\n",omerStr);
  1095. X      }
  1096. X    if (omer) omer++;
  1097. X
  1098. X
  1099. X    incHebJulDate(&todayh,&todayj,&weekday);
  1100. X  } while (!((todayj.mm==0) && (todayj.dd==1))); /* continue to january 1st */
  1101. X  
  1102. X}
  1103. X
  1104. Xvoid getDate (date_t *d) {
  1105. X  printf ("Enter the date (mm dd yy): ");
  1106. X  scanf ("%d %d %d",&d->mm,&d->dd,&d->yy);
  1107. X  d->yy += 1900;
  1108. X  d->mm -= 1;
  1109. X}
  1110. X
  1111. Xvoid PrintDate(date_t dt) {
  1112. X  printf ("%d/%d/%d ",dt.mm,dt.dd,dt.yy);
  1113. X}
  1114. X
  1115. XRollBack(date_t *dtj, int target){ /* move rosh hashana dtj back until it's */
  1116. X  /* in the year before target*/
  1117. X  int days,theyear;
  1118. X  
  1119. X  for (days = 0,theyear = dtj->yy ;theyear > target -1; theyear--)
  1120. X    days +=yearData(JUL2HEB(theyear)).length;
  1121. X  decDate (dtj,days); 
  1122. X  
  1123. X}
  1124. X
  1125. XRollForward(date_t *dtj,int target){ /* move rosh hashana dtj forward until it's*/
  1126. X  /* in the year before target*/
  1127. X  int days,theyear;
  1128. X  
  1129. X  for (days = 0,theyear = dtj->yy ;theyear < target -1; theyear++)
  1130. X    days +=yearData(JUL2HEB(theyear+1)).length;
  1131. X  incDate (dtj,days); 
  1132. X  
  1133. X}
  1134. X
  1135. Xchar * progname;
  1136. X
  1137. Xmain(int argc, char * argv[]) {
  1138. X  char *c;
  1139. X  date_t startDate,tempdt;
  1140. X  int theYear,theMonth,theDay,yearDirty=0;
  1141. X
  1142. X  char * usage = "usage: hebcal [-dhoptw] [[month [day]] year]\n               hebcal help\n";  
  1143. X  progname = argv[0];
  1144. X  
  1145. X  startDate.dd = 28;
  1146. X  startDate.mm = SEP; /* any ol' rosh hashana */
  1147. X  startDate.yy = 1992;
  1148. X  
  1149. X  setDate(&tempdt);        /* do this year */
  1150. X  theYear = tempdt.yy;
  1151. X  
  1152. X  for (argv++, argc--; argc; argv++, argc--)
  1153. X    if (isAllNums(*argv))
  1154. X      if ((argc-1) && isAllNums(*(argv+1)) && !yearDirty) 
  1155. X    if ((argc-2) && isAllNums(*(argv+2))) {
  1156. X      specMonth_sw =1;
  1157. X      specDay_sw =1;
  1158. X      theMonth = atoi(*argv) -1; /* year and month specified */
  1159. X      theDay = atoi(*++argv); /* print theDay of theMonth */
  1160. X      theYear = atoi(*++argv); /* print theMonth of theYear */
  1161. X      yearDirty =1;
  1162. X      argc -=2;
  1163. X    }
  1164. X    else {
  1165. X      specMonth_sw =1;
  1166. X      theMonth = atoi(*argv) -1; /* year and month specified */
  1167. X      theYear = atoi(*++argv); /* print theMonth of theYear */
  1168. X      yearDirty =1;
  1169. X      argc--;
  1170. X    }
  1171. X      else if (!yearDirty) {
  1172. X    theYear = atoi(*argv);    /* just year specified */
  1173. X    yearDirty = 1;        /* print whole year */
  1174. X      }
  1175. X      else     die(usage,"");
  1176. X    else if (**argv == '-')
  1177. X      for (c = *argv,c++;*c;c++)
  1178. X    switch (*c) {
  1179. X    case 'd' :        /* print hebrew dates */
  1180. X      hebDates_sw = 1;
  1181. X      break;
  1182. X    case 'h':
  1183. X      supressHolidays_sw =1;
  1184. X      break;
  1185. X    case 't':        /* do hebcal for today. */
  1186. X      specMonth_sw =1;
  1187. X      specDay_sw =1;
  1188. X      theMonth = tempdt.mm; /* year and month specified */
  1189. X      theDay = tempdt.dd; /* print theDay of theMonth */
  1190. X      yearDirty =1;
  1191. X      break;
  1192. X    case 'o':
  1193. X      printOmer_sw =1;
  1194. X      break;
  1195. X    case 'p' :        /* print parshiot */
  1196. X      parshiot_sw = 1;
  1197. X      break;
  1198. X    case 'w' :        /* print days of the week */
  1199. X      weekday_sw = 1;
  1200. X      break;
  1201. X    default: die(usage,"");
  1202. X    }
  1203. X    else if (!strcmp(*argv,"help")) {
  1204. X      printf ("Hebcal Version 1.0\n\n");
  1205. X      printf ("Hebcal prints out hebrew calendars one solar year at a time.\n");
  1206. X      printf ("Given one numeric argument, it will print out the calendar \n");
  1207. X      printf ("for that year.  Given two numeric argumetnts mm yyyy, it\n");
  1208. X      printf ("prints out the calendar for month mm of year yyyy. \n");
  1209. X      printf ("usage: hebcal [-dhoptw] [[month [day]] year]\n");  
  1210. X      printf ("\nOPTIONS:\n   -d : add hebrew dates\n");
  1211. X      printf ("   -h : suppress holidays\n");
  1212. X      printf ("   -t : only output for today's date\n");
  1213. X      printf ("   -o : add days of the omer\n");
  1214. X      printf ("   -p : add weekly parshiot, including hachodesh, etc \n");
  1215. X      printf ("   -w : add day of the week\n\n");
  1216. X      printf ("       hebcal help --- prints this message\n"); 
  1217. X      printf ("\nExample: \n");
  1218. X      printf ("   hebcal -ho\n");
  1219. X      printf ("will just print out the days of the omer for the current year.\n");
  1220. X      exit(0);
  1221. X    }
  1222. X    else die (usage,"");
  1223. X    
  1224. X  if (specDay_sw) hebDates_sw = 1;
  1225. X
  1226. X  if (theYear < startDate.yy +1) /* go to R"H of the year before */
  1227. X    RollBack(&startDate,theYear);
  1228. X  else if (theYear > startDate.yy +1) /* start from there */
  1229. X    RollForward(&startDate,theYear);
  1230. X  
  1231. X  DoCalendar(startDate,theMonth,theDay);   
  1232. X  
  1233. X  exit(0);
  1234. X}
  1235. X
  1236. END_OF_FILE
  1237.   if test 19232 -ne `wc -c <'hebcal.c'`; then
  1238.     echo shar: \"'hebcal.c'\" unpacked with wrong size!
  1239.   fi
  1240.   # end of 'hebcal.c'
  1241. fi
  1242. echo shar: End of archive 1 \(of 1\).
  1243. cp /dev/null ark1isdone
  1244. MISSING=""
  1245. for I in 1 ; do
  1246.     if test ! -f ark${I}isdone ; then
  1247.     MISSING="${MISSING} ${I}"
  1248.     fi
  1249. done
  1250. if test "${MISSING}" = "" ; then
  1251.     echo You have the archive.
  1252.     rm -f ark[1-9]isdone
  1253. else
  1254.     echo You still must unpack the following archives:
  1255.     echo "        " ${MISSING}
  1256. fi
  1257. exit 0
  1258. exit 0 # Just in case...
  1259.