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", ""); } }
/* 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, ""); } }