/* the return value is the | of all the typeMasks of the holidays */ int getHebHolidays( date_t dth, holstorep_t *holiList ) { int tmpMask; holstorep_t tmpholip, chp; /* current holiday pointer */ tmpMask = 0; *holiList = NULL; for (chp = holidays[dth.mm][dth.dd]; /* static holidays */ chp; chp = chp->next) { tmpMask |= PushHoliday (chp, holiList); } for (chp = var_holidays[dth.mm][dth.dd]; /* variable holidays */ chp; chp = chp->next) { tmpMask |= PushHoliday (chp, holiList); } if (dth.dd == 1) { if(dth.mm == TISHREI) /* special processing for rosh hashana */ { tmpholip = getHolstorep (); initStr (&tmpholip->name, 22); sprintf (tmpholip->name, "%s %d", _("Rosh Hashana"), dth.yy); PushHoliday (tmpholip, &var_holidays[TISHREI][1]); tmpMask |= PushHoliday (tmpholip, holiList); } else { if( ! suppress_rosh_chodesh_sw ) /* rosh Chodesh Processing... */ { tmpholip = getHolstorep(); initStr (&tmpholip->name, NM_LEN); sprintf (tmpholip->name, _("Rosh Chodesh %s"), LANGUAGE2(hMonths[LEAP_YR_HEB (dth.yy)][dth.mm].name)); tmpMask |= PushHoliday (tmpholip, holiList); } } } if (dth.dd == 30 && ! suppress_rosh_chodesh_sw) { tmpholip = getHolstorep (); initStr (&tmpholip->name, NM_LEN); sprintf (tmpholip->name, _("Rosh Chodesh %s"), LANGUAGE2(hMonths[LEAP_YR_HEB (dth.yy)][dth.mm + 1].name)); tmpMask |= PushHoliday (tmpholip, holiList); } return tmpMask; }
year_t yearData( int hebyr ) { date_t tempDate; year_t retYear; tempDate.yy = hebyr; tempDate.mm = TISHREI; tempDate.dd = 1; retYear.first_day_of_week = (int) (hebrew2abs (tempDate) % 7L); retYear.leap_p = LEAP_YR_HEB (hebyr); return retYear; }
void handleArgs(int argc, char *argv[]) { date_t greg_today; char **remain; size_t remain_count; char *cityNameArg = NULL; char *inFileName = NULL; char *tzid = NULL; char *yahrtzeitFileName = NULL; int today_sw = 0; int zemanim_sw = 0; int help_sw = 0; int version_sw = 0; int utf8_hebrew_sw = 0; char *latitudeStr = NULL; char *longitudeStr = NULL; char *langStr = NULL; static struct option long_options[] = { {"24hour", no_argument, 0, 'E'}, {"abbreviated", no_argument, 0, 'W'}, {"add-hebrew-dates", no_argument, 0, 'd'}, {"add-hebrew-dates-for-events", no_argument, 0, 'D'}, {"ashkenazi", no_argument, 0, 'a'}, {"candle-mins", required_argument, 0, 'b'}, {"candlelighting", no_argument, 0, 'c'}, {"city", required_argument, 0, 'C'}, {"daf-yomi", no_argument, 0, 'F'}, {"daily-sedra", no_argument, 0, 'S'}, {"euro-dates", no_argument, 0, 'e'}, {"format", required_argument, 0, 'f'}, {"havdalah-mins", required_argument, 0, 'm'}, {"hebrew-date", no_argument, 0, 'H'}, {"help", no_argument, 0, 0}, {"infile", required_argument, 0, 'I'}, {"israeli", no_argument, 0, 'i'}, {"latitude", required_argument, 0, 'l'}, {"lang", required_argument, 0, 0}, {"longitude", required_argument, 0, 'L'}, {"molad", no_argument, 0, 'M'}, {"no-holidays", no_argument, 0, 'h'}, {"no-modern", no_argument, 0, 0}, {"no-rosh-chodesh", no_argument, 0, 'x'}, {"omer", no_argument, 0, 'o'}, {"sedrot", no_argument, 0, 's'}, {"sunrise-and-sunset", no_argument, 0, 'O'}, {"tabs", no_argument, 0, 'r'}, {"timezone", required_argument, 0, 'z'}, {"today", no_argument, 0, 't'}, {"today-brief", no_argument, 0, 'T'}, {"version", no_argument, 0, 0}, {"weekday", no_argument, 0, 'w'}, {"yahrtzeit", required_argument, 0, 'Y'}, {"years", required_argument, 0, 0}, {"year-abbrev", no_argument, 0, 'y'}, {"zmanim", no_argument, 0, 'Z'}, {NULL, 0, NULL, 0} }; int c; int option_index = 0; setDate(&greg_today); /* keep the current greg. date here */ while ((c = getopt_long(argc, argv, "ab:cC:dDeEFhHI:il:L:m:MoOrsStTwWxyY:z:Z8", long_options, &option_index)) != -1) { switch (c) { case 0: /* long option without short alias */ if (0 == strcmp("version", long_options[option_index].name)) { version_sw = 1; } else if (0 == strcmp("help", long_options[option_index].name)) { help_sw = 1; } else if (0 == strcmp("lang", long_options[option_index].name)) { langStr = strdup(optarg); } else if (0 == strcmp("years", long_options[option_index].name)) { if (!(sscanf(optarg, "%d", &numYears) == 1)) { die("unable to read --years argument: %s", optarg); } } else if (0 == strcmp("no-modern", long_options[option_index].name)) { suppressModern_sw = 1; } else { shortUsage(); exit(1); } break; case 'a': ashkenazis_sw = 1; break; case '8': utf8_hebrew_sw = 1; break; case 'b': /* candle_lighting_minutes_before_sundown */ if (!(sscanf(optarg, "%d", &light_offset) == 1)) die("unable to read candle_lighting_minutes_before_sundown argument: %s", optarg); break; case 'c': /* calculate candlelighting times on fridays */ candleLighting_sw = 1; break; case 'C': cityNameArg = strdup(optarg); break; case 'd': /* print hebrew date */ printHebDates_sw = 1; break; case 'D': /* print hebrew date when there's */ /* something else to print */ printSomeHebDates_sw = 1; break; case 'I': /* input file */ inFileName = strdup(optarg); break; case 'e': /* european date format */ euroDates_sw = 1; break; case 'E': /* 24-hour time format */ twentyFourHour_sw = 1; break; case 'F': /* Daf Yomi */ dafYomi_sw = 1; break; case 'h': /* suppress internal holidays */ noHolidays_sw = 1; break; case 'H': /* suppress use hebrew range dates */ hebrewDates_sw = 1; break; case 'i': /* use Israeli sedra scheme */ israel_sw = 1; break; case 'l': /* latitude */ latitudeStr = strdup(optarg); break; case 'L': /* longitude */ longitudeStr = strdup(optarg); break; case 'm': /* havdalah_minutes */ if (!(sscanf(optarg, "%d", &havdalah_minutes) == 1)) die("unable to read havdalah_minutes argument: %s", optarg); break; case 'M': /* print the molad */ printMolad_sw = 1; break; case 'o': /* print the omer */ printOmer_sw = 1; break; case 'O': /* print sunrise and sunset */ printSunriseSunset_sw = 1; break; case 'r': /* Tab-delineated Format */ tabs_sw = 1; break; case 's': /* print sedrot */ sedrot_sw = 1; break; case 'S': /* print sedra every day. */ sedraAllWeek_sw = 1; break; case 'T': /* do hebcal for today, omit gregorian date. */ noGreg_sw = 1; break; case 't': /* do hebcal for today. */ today_sw = 1; break; case 'w': /* print days of the week */ weekday_sw = 1; break; case 'W': /* abbreviated week view */ abbrev_sw = 1; break; case 'y': /* Print only last 2 digits of year */ yearDigits_sw = 1; break; case 'Y': /* input file */ yahrtzeitFileName = strdup(optarg); break; case 'x': /* input file */ suppress_rosh_chodesh_sw = 1; break; case 'z': /* time zone */ tzid = strdup(optarg); break; case 'Z': zemanim_sw = 1; break; default: shortUsage(); exit(1); break; } } if (langStr != NULL) { hebcal_lang lang = hebcal_get_language(langStr); if (lang == HEBCAL_LANG_UNDEFINED) { warn("Unknown lang '%s'; using default", langStr); } else { hebcal_set_language(lang); } free(langStr); } else if (ashkenazis_sw) { hebcal_set_language(HEBCAL_LANG_ASHKENAZI); } else if (utf8_hebrew_sw) { hebcal_set_language(HEBCAL_LANG_HE); } else { hebcal_set_language(HEBCAL_LANG_DEFAULT); } if (help_sw) { displayHelp(); exit(0); } if (version_sw) { printf("Hebcal version %s\n", VERSION); exit(0); } errno = 0; if (light_offset > 0) { light_offset *= -1; } if (cityNameArg != NULL) { candleLighting_sw = 1; localize_to_city(cityNameArg); free(cityNameArg); } if (inFileName != NULL) { inputFile_sw = 1; if (!(inFile = fopen(inFileName, "r"))) { die("could not open input file %s.", inFileName); } free(inFileName); } if (noGreg_sw) { today_sw = 1; } if (today_sw) { printHebDates_sw = 1; rangeType = TODAY; theMonth = greg_today.mm; /* year and month specified */ theDay = greg_today.dd; /* printc theDay of theMonth */ yearDirty = 1; printOmer_sw = 1; } if (yahrtzeitFileName != NULL) { yahrtzeitFile_sw = 1; if (!(yFile = fopen(yahrtzeitFileName, "r"))) { die("could not open yahrtzeit input file %s.", yahrtzeitFileName); } free(yahrtzeitFileName); } if (latitudeStr != NULL) { if (sscanf(latitudeStr, "%d,%d", &latdeg, &latmin) < 2) { die("unable to read latitude argument: %s", latitudeStr); } latp = 1; if ((abs(latdeg) > 90) || latmin > 60 || latmin < 0) { die("Error, latitude argument out of range: %s", latitudeStr); } latmin = abs(latmin); if (latdeg < 0) { latmin = -latmin; } free(latitudeStr); } if (longitudeStr != NULL) { if (sscanf(longitudeStr, "%d,%d", &longdeg, &longmin) < 2) { die("unable to read longitude argument: %s", longitudeStr); } longp = 1; if ((abs(longdeg) > 180) || longmin > 60 || longmin < 0) { die("Error, longitude argument out of range: %s", longitudeStr); } longmin = abs(longmin); if (longdeg < 0) { longmin = -longmin; } free(longitudeStr); } if (tzid != NULL) { TZ_INFO = timelib_parse_tzfile(tzid, timelib_builtin_db()); if (TZ_INFO == NULL) { die("unable to read time zone argument: %s", tzid); } free(tzid); } if (zemanim_sw) { default_zemanim = (ZMAN_SUNRISE | ZMAN_SZKS | ZMAN_TEFILAH | ZMAN_CHATZOT | ZMAN_MINCHA_GEDOLA | ZMAN_MINCHA_KETANA | ZMAN_PLAG_HAMINCHA | ZMAN_SUNSET | ZMAN_TZAIT_42); } if (latp) cityName = "User Defined City"; if (latp ^ longp) die("You must enter BOTH the latitude and the longitude", ""); if( !strcmp(cityName, "Jerusalem" )) light_offset = -40; /* does everyone hold by this? */ remain_count = argc - optind; remain = argv + optind; switch (remain_count) /* suck up the date */ { case 0: /* process this year */ if (hebrewDates_sw) theYear = abs2hebrew(greg2abs(greg_today)).yy; else theYear = greg_today.yy; break; case 1: if (isAllNums(remain[0])) { theYear = atoi(remain[0]); /* just year specified */ yearDirty = 1; /* print whole year */ } else if (0 == istrncasecmp(5, remain[0], "help")) { displayHelp(); exit(0); } else if (0 == istrncasecmp(3, remain[0], "info")) { print_version_data(); exit(0); } else if (0 == istrncasecmp(3, remain[0], "cities")) { print_city_data(); exit(0); } else if (0 == istrncasecmp(3, remain[0], "copying")) { print_copying(); exit(0); } else if (0 == istrncasecmp(3, remain[0], "warranty")) { print_warranty(); exit(0); } else { printf("%s: unrecognized command '%s'\n", progname, remain[0]); shortUsage(); exit(1); } break; case 2: if (!isAllNums(remain[1])) { shortUsage(); exit(1); } theYear = atoi(remain[1]); /* print theMonth of theYear */ theMonth = lookup_hebrew_month(remain[0]); if (theMonth) { hebrewDates_sw = 1; /* automagically turn it on */ if (theMonth == ADAR_II && !LEAP_YR_HEB(theYear)) { theMonth = ADAR_I; /* silently fix this mistake */ } } else if (isAllNums(remain[0])) { if (hebrewDates_sw) { die("Don't use numbers to specify Hebrew months.", ""); } else { theMonth = atoi(remain[0]); /* gregorian month */ } } else if (hebrewDates_sw) { die("Unknown Hebrew month: %s", remain[0]); } else { die("bad gregorian month: %s", remain[0]); } yearDirty = 1; rangeType = MONTH; break; case 3: if (!(isAllNums(remain[1]) && isAllNums(remain[2]))) { shortUsage(); exit(1); } theDay = atoi(remain[1]); /* print theDay of theMonth */ theYear = atoi(remain[2]); /* print theMonth of theYear */ theMonth = lookup_hebrew_month(remain[0]); if (theMonth) { hebrewDates_sw = 1; /* automagically turn it on */ if (theMonth == ADAR_II && !LEAP_YR_HEB(theYear)) { theMonth = ADAR_I; /* silently fix this mistake */ } } else if (isAllNums(remain[0])) { if (hebrewDates_sw) { die("Don't use numbers to specify Hebrew months.", ""); } else { theMonth = atoi(remain[0]); /* gregorian month */ } } else if (hebrewDates_sw) { die("Unknown Hebrew month: %s", remain[0]); } else { die("bad gregorian month: %s", remain[0]); } if (theDay < 1) die("The day of the month must be greater than 0", ""); if (theMonth < 1) die("The month must be greater than 0", ""); if (hebrewDates_sw) { if (theDay > max_days_in_heb_month(theMonth, theYear)) die("Sorry, there aren't that many days in %s (then)", LANGUAGE2(hMonths[LEAP_YR_HEB(theYear)][theMonth].name)); } else { if (theMonth > 12) die("The month must be less than 13", ""); if (theDay > MonthLengths[LEAP(theYear)][theMonth]) die("Sorry, there aren't that many days in %s (then)", eMonths[theMonth]); } rangeType = DAY; yearDirty = 1; break; default: displayHelp(); exit(1); } if (numYears != 1 && rangeType != YEAR) { die("Sorry, --years option works only with entire-year calendars", ""); } }
/* sets static globals based on this year. */ void reset_sedra( int hebYr ) /* the hebrew year */ { date_t tempDt; int long_c, short_k, rosh_hashana_day, type; long int rosh_hashana; size_t theSedraArraySize; long_c = long_cheshvan (hebYr); short_k = short_kislev (hebYr); if (long_c && !short_k) type = COMPLETE; else if (!long_c && short_k) type = INCOMPLETE; else type = REGULAR; tempDt.dd = 1; tempDt.mm = TISHREI; tempDt.yy = hebYr; rosh_hashana = hebrew2abs (tempDt); rosh_hashana_day = (int) (rosh_hashana % 7L); /* find the first saturday on or after Rosh Hashana */ first_saturday = day_on_or_before (6, rosh_hashana + 6L); if (!LEAP_YR_HEB(hebYr)) { switch (rosh_hashana_day) { case SAT: if (type == INCOMPLETE) { theSedraArray = Sat_short; theSedraArraySize = sizeof(Sat_short); } else if (type == COMPLETE) { theSedraArray = Sat_long; theSedraArraySize = sizeof(Sat_long); } break; case MON: if (type == INCOMPLETE) { theSedraArray = Mon_short; theSedraArraySize = sizeof(Mon_short); } else if (type == COMPLETE) { theSedraArray = israel_sw ? Mon_short : Mon_long; theSedraArraySize = israel_sw ? sizeof(Mon_short) : sizeof(Mon_long); } break; case TUE: if (type == REGULAR) { theSedraArray = israel_sw ? Mon_short : Mon_long; theSedraArraySize = israel_sw ? sizeof(Mon_short) : sizeof(Mon_long); } break; case THU: if (type == REGULAR) { theSedraArray = israel_sw ? Thu_normal_Israel : Thu_normal; theSedraArraySize = israel_sw ? sizeof(Thu_normal_Israel) : sizeof(Thu_normal); } else if (type == COMPLETE) { theSedraArray = Thu_long; theSedraArraySize = sizeof(Thu_long); } break; default: die ("improper sedra year type calculated.", ""); } } else { /* leap year */ switch (rosh_hashana_day) { case SAT: if (type == INCOMPLETE) { theSedraArray = Sat_short_leap; theSedraArraySize = sizeof(Sat_short_leap); } else if (type == COMPLETE) { theSedraArray = israel_sw ? Sat_short_leap : Sat_long_leap; theSedraArraySize = israel_sw ? sizeof(Sat_short_leap) : sizeof(Sat_long_leap); } break; case MON: if (type == INCOMPLETE) { theSedraArray = israel_sw ? Mon_short_leap_Israel : Mon_short_leap; theSedraArraySize = israel_sw ? sizeof(Mon_short_leap_Israel) : sizeof(Mon_short_leap); } else if (type == COMPLETE) { theSedraArray = israel_sw ? Mon_long_leap_Israel : Mon_long_leap; theSedraArraySize = israel_sw ? sizeof(Mon_long_leap_Israel) : sizeof(Mon_long_leap); } break; case TUE: if (type == REGULAR) { theSedraArray = israel_sw ? Mon_long_leap_Israel : Mon_long_leap; theSedraArraySize = israel_sw ? sizeof(Mon_long_leap_Israel) : sizeof(Mon_long_leap); } break; case THU: if (type == INCOMPLETE) { theSedraArray = Thu_short_leap; theSedraArraySize = sizeof(Thu_short_leap); } else if (type == COMPLETE) { theSedraArray = Thu_long_leap; theSedraArraySize = sizeof(Thu_long_leap); } break; default: die ("improper sedra year type calculated.", ""); } } sedraNumWeeks = theSedraArraySize / sizeof(int); }
void init_yahrtzeits( int hyear ) { holstorep_t tmpholp; char *s, *monthStr, *eventStr, nextChar; int index, inMonth, inDay, inYear, lineNum = 1; date_t hDeath, gDeath; initStr (&s, MAX_LINE_LEN); initStr (&monthStr, MAX_LINE_LEN); rewind (yFile); nextChar = (char) getc (yFile); /* priming getc */ for (; !feof (yFile); lineNum++, nextChar = (char) getc (yFile)) { /* force an EOF */ ungetc (nextChar, yFile); if (!fgets (s, MAX_LINE_LEN, yFile)) { warn ("yahrtzeit file read error. Skipping line %s", hc_itoa (lineNum)); continue; } if (s[0] == '\n') /* blank line */ continue; if (sscanf (s, "%s %d %d%n", monthStr, &inDay, &inYear, &index) < 3) { warn ("Error in yahrtzeit file. Skipping line %s", hc_itoa (lineNum)); continue; } if (!isAllNums (monthStr)) { warn ("Non-numeric month in yahrtzeit file. Skipping line %s", hc_itoa (lineNum)); continue; } sscanf (monthStr, "%d", &inMonth); if (inMonth > 12 || inMonth < 1 || inDay < 1 || inDay > MonthLengths[LEAP (inYear)][inMonth]) { warn ("Date out of range in yahrtzeit file. Skipping line %s", hc_itoa (lineNum)); continue; } gDeath.dd = inDay; gDeath.mm = inMonth; gDeath.yy = inYear; hDeath = abs2hebrew (greg2abs (gDeath)); /* If it's Heshvan 30 it depends on the first anniversary; if that was not Heshvan 30, use the day before Kislev 1. */ if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !long_cheshvan (hDeath.yy + 1)) { hDeath.dd = 1; hDeath.mm = KISLEV; hDeath.yy = hyear; hDeath = abs2hebrew (hebrew2abs (hDeath) - 1L); } /* If it's Kislev 30 it depends on the first anniversary; if that was not Kislev 30, use the day before Teveth 1. */ else if (hDeath.mm == KISLEV && hDeath.dd == 30 && !short_kislev (hDeath.yy + 1)) { hDeath.dd = 1; hDeath.mm = TEVET; hDeath.yy = hyear; hDeath = abs2hebrew (hebrew2abs (hDeath) - 1L); } /* If it's Adar II, use the same day in last month of year (Adar or Adar II). */ else if (hDeath.mm == ADAR_II) { hDeath.mm = MONTHS_IN_HEB (hyear); } /* If it's the 30th in Adar I and year is not a leap year (so Adar has only 29 days), use the last day in Shevat. */ else if (hDeath.mm == ADAR_I && hDeath.dd == 30 && !LEAP_YR_HEB (hyear)) { hDeath.dd = 30; hDeath.mm = SHVAT; } /* In all other cases, use the normal anniversary of the date of death. */ /* advance day to rosh chodesh if needed */ if (hDeath.mm == CHESHVAN && hDeath.dd == 30 && !long_cheshvan(hyear)) { hDeath.mm = KISLEV; hDeath.dd = 1; } else if (hDeath.mm == KISLEV && hDeath.dd == 30 && short_kislev(hyear)) { hDeath.mm = TEVET; hDeath.dd = 1; } eventStr = s + index + 1; /* get the name of the event */ /* if (eventStr[strlen(eventStr)-1] == '\n') */ eventStr[strlen (eventStr) - 1] = '\0'; /* chop off the \n */ /* store the holiday in the LUT */ tmpholp = getHolstorep (); initStr (&tmpholp->name, MAX_LINE_LEN); strcpy (tmpholp->name, eventStr); /* load the user holiday into it. */ tmpholp->typeMask = USER_EVENT; PushHoliday (tmpholp, &var_holidays[hDeath.mm][hDeath.dd]); } }
void init_user_holidays( int hyear ) { holstorep_t tmpholp; char *s, *monthStr, *eventStr, nextChar; int index, inMonth, inDay, lineNum = 1; initStr (&s, MAX_LINE_LEN); initStr (&monthStr, MAX_LINE_LEN); rewind (inFile); nextChar = (char) getc (inFile); /* priming getc */ for (; !feof (inFile); lineNum++, nextChar = (char) getc (inFile)) { /* force an EOF */ ungetc (nextChar, inFile); if (!fgets (s, MAX_LINE_LEN, inFile)) { warn ("input file read error. Skipping line %s", hc_itoa (lineNum)); continue; } if (s[0] == '\n') /* blank line */ continue; if (!sscanf (s, "%s %d%n", monthStr, &inDay, &index)) { warn ("Error in input file. Skipping line %s", hc_itoa (lineNum)); continue; } if (isAllNums (monthStr)) { warn ("Numeric hebrew month in input file. Skipping line %s", hc_itoa (lineNum)); continue; } if (!(inMonth = lookup_hebrew_month (monthStr))) { warn ("Unrecognized hebrew month in input file. Skipping line %s", hc_itoa (lineNum)); continue; } if (inDay < 1 || inDay > 30) { warn ("Date out of range in input file. Skipping line %s", hc_itoa (lineNum)); continue; } if (inMonth == ADAR_II && !LEAP_YR_HEB (hyear)) inMonth = ADAR_I; eventStr = s + index + 1; /* get the name of the event */ if (eventStr[strlen (eventStr) - 1] == '\n') eventStr[strlen (eventStr) - 1] = '\0'; /* chop off the \n */ /* store the holiday in the LUT */ tmpholp = getHolstorep (); initStr (&tmpholp->name, MAX_LINE_LEN); strcpy (tmpholp->name, eventStr); /* load the user holiday into it. */ tmpholp->typeMask = USER_EVENT; PushHoliday (tmpholp, &var_holidays[inMonth][inDay]); } }
static void load_variable_holidays( int hYear ) { date_t tempDt; long int roshHashana, passover, tishaBav, tevet10; holstorep_t tmpholp; tempDt.yy = hYear; tempDt.mm = TISHREI; tempDt.dd = 1; roshHashana = hebrew2abs (tempDt); tempDt.yy = hYear; tempDt.mm = TEVET; tempDt.dd = 10; tevet10 = hebrew2abs (tempDt); tempDt.mm = NISAN; tempDt.dd = 15; passover = hebrew2abs (tempDt); tempDt.mm = AV; tempDt.dd = 9; tishaBav = hebrew2abs (tempDt); tmpholp = getHolstorep (); /* allocate hsnode */ tmpholp->name = HOLIDAY_TZOM_GEDALIAH; PushHoliday (tmpholp, &var_holidays[TISHREI] [roshHashana % 7L == THU ? 4 : 3]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHABBAT_SHUVA; tempDt = abs2hebrew (day_on_or_before (SAT, 7L + roshHashana)); PushHoliday (tmpholp, &var_holidays[TISHREI][tempDt.dd]); /* printf( "hyear is %d\n",hYear); */ if (short_kislev (hYear)) { tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_CHANUKAH_7_CANDLES; tmpholp->typeMask = CHANUKAH_CANDLES; PushHoliday (tmpholp, &var_holidays[TEVET][1]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_CHANUKAH_8_CANDLES; tmpholp->typeMask = CHANUKAH_CANDLES; PushHoliday (tmpholp, &var_holidays[TEVET][2]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_CHANUKAH_8TH_DAY; PushHoliday (tmpholp, &var_holidays[TEVET][3]); } else { tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_CHANUKAH_7_CANDLES; tmpholp->typeMask = CHANUKAH_CANDLES; PushHoliday (tmpholp, &var_holidays[KISLEV][30]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_CHANUKAH_8_CANDLES; tmpholp->typeMask = CHANUKAH_CANDLES; PushHoliday (tmpholp, &var_holidays[TEVET][1]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_CHANUKAH_8TH_DAY; PushHoliday (tmpholp, &var_holidays[TEVET][2]); } tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHABBAT_SHEKALIM; tempDt = abs2hebrew (day_on_or_before (SAT, passover - 43L)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHABBAT_ZACHOR; tempDt = abs2hebrew (day_on_or_before (SAT, passover - 30L)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_TA_ANIT_ESTHER; tempDt = abs2hebrew (passover - (passover % 7L == TUE ? 33L : 31)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); if (LEAP_YR_HEB (hYear)) { tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_PURIM_KATAN; PushHoliday (tmpholp, &var_holidays[ADAR_I][14]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_EREV_PURIM; PushHoliday (tmpholp, &var_holidays[ADAR_II][13]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_PURIM; PushHoliday (tmpholp, &var_holidays[ADAR_II][14]); } else { tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_EREV_PURIM; PushHoliday (tmpholp, &var_holidays[ADAR_I][13]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_PURIM; PushHoliday (tmpholp, &var_holidays[ADAR_I][14]); } tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHUSHAN_PURIM; tempDt = abs2hebrew (passover - (passover % 7L == SUN ? 28L : 29)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHABBAT_PARAH; tempDt = abs2hebrew (day_on_or_before (SAT, passover - 14L) - 7L); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHABBAT_HACHODESH; tempDt = abs2hebrew (day_on_or_before (SAT, passover - 14L)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_TA_ANIT_BECHOROT; if ((passover - 1L) % 7L == SAT) { /* if the fast falls on Shabbat, move to Thursday */ tempDt = abs2hebrew (day_on_or_before (THU, passover)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); } else PushHoliday (tmpholp, &var_holidays[NISAN][14]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHABBAT_HAGADOL; tempDt = abs2hebrew (day_on_or_before (SAT, passover - 1L)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); if (hYear >= 5711) { /* Yom HaShoah first observed in 1951 */ long int nisan27; int nisan_day = 27; tempDt.mm = NISAN; tempDt.dd = 27; nisan27 = hebrew2abs (tempDt); /* When the actual date of Yom Hashoah falls on a Friday, the * state of Israel observes Yom Hashoah on the preceding * Thursday. When it falls on a Sunday, Yom Hashoah is observed * on the following Monday. * http://www.ushmm.org/remembrance/dor/calendar/ */ if (nisan27 % 7L == FRI) nisan_day = 26; else if (nisan27 % 7L == SUN) nisan_day = 28; tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_YOM_HASHOAH; PushHoliday (tmpholp, &var_holidays[NISAN][nisan_day]); } if (hYear > 5708) { /* only really makes sense after 1948 */ tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_YOM_HAZIKARON; if (passover % 7L == SUN) tempDt.dd = 3; else if (passover % 7L == SAT) tempDt.dd = 4; else if( hYear < 5764 ) tempDt.dd = 5; else if( passover % 7L == TUE ) /* no Yom Hazikaron on motzei shabbat allowed after 5764*/ tempDt.dd = 6; else tempDt.dd = 5; PushHoliday (tmpholp, &var_holidays[IYYAR][tempDt.dd - 1]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_YOM_HAATZMA_UT; PushHoliday (tmpholp, &var_holidays[IYYAR][tempDt.dd]); } if (hYear > 5727) { /* only really makes sense after 1967 */ tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_YOM_YERUSHALAYIM; PushHoliday (tmpholp, &var_holidays[IYYAR][28]); } if (hYear >= 5769) { tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SIGD; PushHoliday (tmpholp, &var_holidays[CHESHVAN][29]); } tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_TZOM_TAMMUZ; if (tishaBav % 7L == SAT) tempDt = abs2hebrew (tishaBav - 20L); else tempDt = abs2hebrew (tishaBav - 21L); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHABBAT_CHAZON; tempDt = abs2hebrew (day_on_or_before (SAT, tishaBav)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_EREV_TISH_A_B_AV; PushHoliday (tmpholp, &var_holidays[AV] [tishaBav % 7L == SAT ? 9 : 8]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_TISH_A_B_AV; PushHoliday (tmpholp, &var_holidays[AV] [tishaBav % 7L == SAT ? 10 : 9]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_SHABBAT_NACHAMU; tempDt = abs2hebrew (day_on_or_before (SAT, tishaBav + 7L)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_ASARA_B_TEVET; if (tevet10 % 7L == SAT) PushHoliday (tmpholp, &var_holidays[TEVET][11]); else PushHoliday (tmpholp, &var_holidays[TEVET][10]); tempDt.mm = TISHREI; tempDt.dd = 1; tempDt.yy = hYear + 1; tmpholp = getHolstorep (); tmpholp->name = HOLIDAY_LEIL_SELICHOT; tempDt = abs2hebrew (day_on_or_before (SAT, hebrew2abs (tempDt) - 4L)); PushHoliday (tmpholp, &var_holidays[tempDt.mm][tempDt.dd]); }
void main_calendar( long todayAbs, long endAbs) /* the range of the desired printout */ { date_t todayGreg, todayHeb; holstorep_t holi_start,holip; /* a list of holidays for today */ year_t theYear; char *omerStr ; int omer, day_of_week, first_weekday, returnedMask; int omer_today, sedra_today, candle_today, holidays_today, molad_today; molad_t moladNext; int monthNext; int today_zemanim, i_zman; int num_zmanim = sizeof (zemanim) / sizeof (struct _zman); char buffer[80]; /* Used to decide whether a particular type of daily info should be included in the abbreviated view. In abbreviated mode things like sunrise, daf, omer are printed once a week. */ #define INCLUDE_TODAY(_sw) \ ( (_sw) && ((!abbrev_sw) || (first_weekday == day_of_week))) todayHeb = abs2hebrew (todayAbs); todayGreg = abs2greg (todayAbs); theYear = yearData (todayHeb.yy); /* plug in light_offset before starting the loop */ for (i_zman = 0; i_zman < num_zmanim; i_zman ++) if (zemanim[i_zman].flags == ZMAN_CANDLES_BEFORE) zemanim[i_zman].min_offset = light_offset; else if (zemanim[i_zman].flags == ZMAN_CANDLES_AFTER || zemanim[i_zman].flags == ZMAN_HAVDALAH ) zemanim[i_zman].min_offset = havdalah_minutes; /*============== Main Year Loop ==============*/ reset_Omer (todayHeb.yy); if (sedraAllWeek_sw || sedrot_sw) reset_sedra (todayHeb.yy); first_weekday = day_of_week = (int) (todayAbs % 7L); while (todayAbs <= endAbs) { /* get the holidays for today */ returnedMask = getHebHolidays (todayHeb, &holip); sedra_today = sedraAllWeek_sw || (sedrot_sw && (day_of_week == SAT)); omer_today = printOmer_sw && (todayAbs >= beginOmer) && (todayAbs <= endOmer); holidays_today = holip && (!noHolidays_sw || (returnedMask & USER_EVENT)); molad_today = printMolad_sw && (day_of_week == SAT) && (todayHeb.dd >= 23 && todayHeb.dd <= 29) && (todayHeb.mm != ELUL); /* no birkat hachodesh before rosh hashana */ today_zemanim = 0; if (INCLUDE_TODAY(default_zemanim)) today_zemanim |= default_zemanim; if (candleLighting_sw) { if (day_of_week == FRI) today_zemanim |= ZMAN_CANDLES_BEFORE; else { if (returnedMask & LIGHT_CANDLES) today_zemanim |= (day_of_week == SAT) ? ZMAN_CANDLES_AFTER : ZMAN_CANDLES_BEFORE; else if ((returnedMask & LIGHT_CANDLES_TZEIS) && ! (returnedMask & YOM_TOV_ENDS)) today_zemanim |= ZMAN_CANDLES_AFTER; } if (!(today_zemanim & (ZMAN_CANDLES_BEFORE | ZMAN_CANDLES_AFTER)) && (day_of_week == SAT || returnedMask & YOM_TOV_ENDS)) today_zemanim |= ZMAN_HAVDALAH; if (!(today_zemanim & (ZMAN_CANDLES_BEFORE)) && (returnedMask & CHANUKAH_CANDLES)) today_zemanim |= ZMAN_CANDLES_AFTER; /* even if havdalah */ } if (INCLUDE_TODAY(printHebDates_sw) || ((printSomeHebDates_sw || printHebDates_sw) && (holidays_today || sedra_today || omer_today || (today_zemanim & (ZMAN_CANDLES_BEFORE|ZMAN_CANDLES_AFTER|ZMAN_HAVDALAH))))) { PrintGregDate (todayGreg); printf ("%d%s of %s, %d\n", todayHeb.dd, /* print the hebrew date */ numSuffix( todayHeb.dd ), _(hMonths[LEAP_YR_HEB( todayHeb.yy )][todayHeb.mm].name), todayHeb.yy); } if (printSunriseSunset_sw) { print_sunrise_sunset(todayGreg); } /* print the sedra, if desired */ if (sedra_today) { char sedraStr[40]; int foundSedra = sedra( todayAbs, sedraStr, 40 ); if (foundSedra) { PrintGregDate( todayGreg ); printf( "%s %s\n", _("Parashat"), sedraStr ); } } /* print today's holidays */ holi_start=holip; /* store the head of the list for freeing */ for (; holip; holip = holip->next) { if (!noHolidays_sw || (holip->typeMask & USER_EVENT)) { PrintGregDate( todayGreg ); puts( holip->name ); } } /* Print the Omer */ if (INCLUDE_TODAY(omer_today)) { initStr (&omerStr, NM_LEN); omer = (int) (todayAbs - beginOmer + 1L); if (!tabs_sw) { strncat (omerStr, hc_itoa (omer), NM_LEN); strncat (omerStr, numSuffix (omer), NM_LEN); strncat (omerStr, " day of the Omer", NM_LEN); } else { strncat (omerStr, "Omer: ", NM_LEN); strncat (omerStr, hc_itoa (omer), NM_LEN); } PrintGregDate (todayGreg); printf ("%s\n", omerStr); free( omerStr ); } if (INCLUDE_TODAY(dafYomi_sw)) hebcal_dafyomi(&todayGreg); /* Print CandleLighting times */ if (today_zemanim) { print_candlelighting_times (today_zemanim, day_of_week, todayGreg); } /* Print Molad */ if (molad_today) { PrintGregDate (todayGreg); monthNext = (todayHeb.mm == MONTHS_IN_HEB(todayHeb.yy) ? 1 : todayHeb.mm + 1); moladNext = get_molad(todayHeb.yy, monthNext); printf ("Molad %s: %s, %d minutes and %d chalakim after %d %s\n", hMonths[LEAP_YR_HEB(todayHeb.yy)][monthNext].name, ShortDayNames[dayOfWeek(abs2greg(moladNext.day))], (int) moladNext.chalakim / 18, moladNext.chalakim % 18, (moladNext.hour > 12 ? moladNext.hour - 12 : moladNext.hour), (moladNext.hour > 12 ? "PM" : "AM") ); } incHebGregDate (&todayHeb, &todayGreg, &todayAbs, &day_of_week, &theYear); # ifdef PLUG_LEAKS free_holidays(*holip); # endif } #undef INCLUDE_TODAY }
/* FIX: this wants to become gnu-ish */ void handleArgs(int argc, char *argv[]) { char dummy[10]; date_t greg_today; int option; char *usage = /* not quite sure how compatible this is */ "usage: \n\ hebcal [-acdDehHiMoOrsStTwxy]\n\ [-b candle_lighting_minutes_before_sundown]\n\ [-I input_file]\n\ [-Y yahrtzeit_file]\n\ [-C city]\n\ [-L longitude -l latitude]\n\ [-m havdalah_minutes]\n\ [-z timezone]\n\ [-Z daylight_savings_scheme]\n\ [[month [day]] year]\n\ hebcal help\n\ hebcal info\n\ hebcal DST\n\ hebcal cities\n\ hebcal warranty\n\ hebcal copying\n"; setDate(&greg_today); /* keep the current greg. date here */ Getopt(argc, argv, "", 1); while (EOF != (option = Getopt(argc, argv, "ab:cC:dDeFf:hHI:il:L:m:MoOrsStTwxyY:z:Z:8", 0))) { switch ((char) option) { case 'a': /* ashkenazis hebrew */ ashkenazis_sw = 1; break; case '8': /* ashkenazis hebrew */ iso8859_8_sw = 1; break; case 'b': /* candle_lighting_minutes_before_sundown */ if (!(sscanf(Optarg, "%d", &light_offset) == 1)) die("unable to read candle_lighting_minutes_before_sundown argument: %s", Optarg); light_offset *= -1; break; case 'c': /* calculate candlelighting times on fridays */ candleLighting_sw = 1; break; case 'C': localize_to_city(Optarg); candleLighting_sw = 1; break; case 'd': /* print hebrew date */ printHebDates_sw = 1; break; case 'D': /* print hebrew date when there's */ /* something else to print */ printSomeHebDates_sw = 1; break; case 'I': /* input file */ inputFile_sw = 1; if (!(inFile = fopen(Optarg, "r"))) die("could not open input file %s.", Optarg); break; case 'e': /* european date format */ euroDates_sw = 1; break; case 'f': /* output format */ formatString = strdup(Optarg); break; case 'F': /* Daf Yomi */ dafYomi_sw = 1; break; case 'h': /* suppress internal holidays */ noHolidays_sw = 1; break; case 'H': /* suppress use hebrew range dates */ hebrewDates_sw = 1; break; case 'i': /* use Israeli sedra scheme */ israel_sw = 1; break; case 'l': /* latitude */ latdeg = latmin = 0; latp = 1; if (sscanf(Optarg, "%d,%d", &latdeg, &latmin) < 2) die("unable to read latitude argument: %s", Optarg); if ((abs(latdeg) > 90) || latmin > 60 || latmin < 0) die("latitude argument out of range", ""); latmin = abs(latmin); if (latdeg < 0) latmin = -latmin; break; case 'L': /* longitude */ longdeg = longmin = 0; longp = 1; if (sscanf(Optarg, "%d,%d", &longdeg, &longmin) < 2) die("unable to read longitude argument: %s", Optarg); if ((abs(longdeg) > 180) || longmin > 60 || longmin < 0) die("longitude argument out of range", ""); longmin = abs(longmin); if (longdeg < 0) longmin = -longmin; break; case 'm': /* havdalah_minutes */ if (!(sscanf(Optarg, "%d", &havdalah_minutes) == 1)) die("unable to read havdalah_minutes argument: %s", Optarg); break; case 'M': /* print the molad */ printMolad_sw = 1; break; case 'o': /* print the omer */ printOmer_sw = 1; break; case 'O': /* print sunrise and sunset */ printSunriseSunset_sw = 1; break; case 'r': /* Tab-delineated Format */ tabs_sw = 1; break; case 's': /* print sedrot */ sedrot_sw = 1; break; case 'S': /* print sedra every day. */ sedraAllWeek_sw = 1; break; case 'T': /* do hebcal for today, omit gregorian date. */ noGreg_sw = 1; /*** note this falls through to 't' case ***/ case 't': /* do hebcal for today. */ printHebDates_sw = 1; rangeType = TODAY; theMonth = greg_today.mm; /* year and month specified */ theDay = greg_today.dd; /* printc theDay of theMonth */ yearDirty = 1; printOmer_sw = 1; break; case 'w': /* print days of the week */ weekday_sw = 1; break; case 'y': /* Print only last 2 digits of year */ yearDigits_sw = 1; break; case 'Y': /* input file */ yahrtzeitFile_sw = 1; if (!(yFile = fopen(Optarg, "r"))) die("could not open yahrtzeit input file %s.", Optarg); break; case 'x': /* input file */ suppress_rosh_chodesh_sw = 1; break; case 'Z': schemep = 1; sscanf(Optarg, "%s", dummy); set_DST_scheme(dummy); break; case 'z': /* time zone */ if (!(sscanf(Optarg, "%d", &TZ) == 1)) die("unable to read time zone argument: %s", Optarg); if (!schemep) DST_scheme = DST_NONE; zonep = 1; break; default: die(usage, ""); } } if (latp) cityName = "User Defined City"; if (latp ^ longp) die("You must enter BOTH the latitude and the longitude", ""); if( !strcmp(cityName, "Jerusalem" )) light_offset = -40; /* does everyone hold by this? */ switch (argc - Optind) /* suck up the date */ { case 0: /* process this year */ if (hebrewDates_sw) theYear = abs2hebrew(greg2abs(greg_today)).yy; else theYear = greg_today.yy; break; case 1: if (isAllNums(argv[Optind])) { theYear = atoi(argv[Optind]); /* just year specified */ yearDirty = 1; /* print whole year */ } else if (0 == istrncasecmp(5, argv[Optind], "help")) { size_t lineNumber; for (lineNumber = 0; (lineNumber < sizeof(helpArray) / sizeof(char *)); lineNumber++) { puts(helpArray[lineNumber]); } exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "info")) { print_version_data(); exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "cities")) { print_city_data(); exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "DST")) { print_DST_data(); exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "copying")) { print_copying(); exit(0); } else if (0 == istrncasecmp(3, argv[Optind], "warranty")) { print_warranty(); exit(0); } else die(usage, ""); break; case 2: if (!isAllNums(argv[Optind + 1])) die(usage, ""); theYear = atoi(argv[Optind + 1]); /* print theMonth of theYear */ theMonth = lookup_hebrew_month(argv[Optind]); if (theMonth) { hebrewDates_sw = 1; /* automagically turn it on */ if (theMonth == ADAR_II && !LEAP_YR_HEB(theYear)) theMonth = ADAR_I; /* silently fix this mistake */ } else if (isAllNums(argv[Optind])) if (hebrewDates_sw) die("Don't use numbers to specify hebrew months.", ""); else theMonth = atoi(argv[Optind]); /* gregorian month */ else if (hebrewDates_sw) die("Unknown hebrew month: %s", argv[Optind]); else die(usage, ""); /* bad gregorian month. */ Optind++; yearDirty = 1; rangeType = MONTH; break; case 3: if (!(isAllNums(argv[Optind + 1]) && isAllNums(argv[Optind + 2]))) die(usage, ""); theDay = atoi(argv[Optind + 1]); /* print theDay of theMonth */ theYear = atoi(argv[Optind + 2]); /* print theMonth of theYear */ theMonth = lookup_hebrew_month(argv[Optind]); if (theMonth) { hebrewDates_sw = 1; /* automagically turn it on */ if (theMonth == ADAR_II && !LEAP_YR_HEB(theYear)) theMonth = ADAR_I; /* silently fix this mistake */ } else if (isAllNums(argv[Optind])) if (hebrewDates_sw) die("Don't use numbers to specify hebrew months.", ""); else theMonth = atoi(argv[Optind]); /* gregorian month */ else if (hebrewDates_sw) die("Unknown hebrew month: %s", argv[Optind]); else die("bad month.%s", usage); /* bad gregorian month. */ if (theDay < 1) die("The day of the month must be greater than 0", ""); if (theMonth < 1) die("The month must be greater than 0", ""); if (hebrewDates_sw) { if (theDay > max_days_in_heb_month(theMonth, theYear)) die("Sorry, there aren't that many days in %s (then)", LANGUAGE2(hMonths[LEAP_YR_HEB(theYear)][theMonth].name)); } else { if (theMonth > 12) die("The month must be less than 13", ""); if (theDay > MonthLengths[LEAP(theYear)][theMonth]) die("Sorry, there aren't that many days in %s (then)", eMonths[theMonth]); } rangeType = DAY; yearDirty = 1; break; default: die(usage, ""); } }