Example #1
0
/*
 * Compute the number of days from date, obey the switch from
 * Julian to Gregorian as used by UK and her colonies.
 */
int
sndaysb(struct date *d)
{

	if (nswitchb < ndaysj(d))
		return (ndaysg(d));
	else
		return (ndaysj(d));
}
Example #2
0
/*
 * Compute the number of days from date, obey the local switch from
 * Julian to Gregorian if specified by the user.
 */
int
sndaysr(struct date *d)
{

	if (nswitch != 0)
		if (nswitch < ndaysj(d))
			return (ndaysg(d));
		else
			return (ndaysj(d));
	else
		return ndaysg(d);
}
Example #3
0
/* Compute the day number of Easter Sunday in Julian Calendar */
static int
easterodn(int y)
{
	/*
	 * Table for the easter limits in one metonic (19-year) cycle. 21
	 * to 31 is in March, 1 through 18 in April. Easter is the first
	 * sunday after the easter limit.
	 */
	int     mc[] = {5, 25, 13, 2, 22, 10, 30, 18, 7, 27, 15, 4,
		    24, 12, 1, 21, 9, 29, 17};

	/* Offset from a weekday to next sunday */
	int     ns[] = {6, 5, 4, 3, 2, 1, 7};
	date	dt;
	int     dn;

	/* Assign the easter limit of y to dt */
	dt.d = mc[y % 19];

	if (dt.d < 21)
		dt.m = 4;
	else
		dt.m = 3;

	dt.y = y;

	/* Return the next sunday after the easter limit */
	dn = ndaysj(&dt);
	return (dn + ns[weekday(dn)]);
}
Example #4
0
int
main(int argc, char *argv[])
{
	struct  djswitch *p, *q;	/* to search user defined switch date */
	date	never = {10000, 1, 1};	/* outside valid range of dates */
	date	ukswitch = {1752, 9, 2};/* switch date for Great Britain */
	date	dt;
	int     ch;			/* holds the option character */
	int     m = 0;			/* month */
	int	y = 0;			/* year */
	int     flag_backward = 0;	/* user called cal--backward compat. */
	int     flag_wholeyear = 0;	/* user wants the whole year */
	int	flag_julian_cal = 0;	/* user wants Julian Calendar */
	int     flag_julian_day = 0;	/* user wants the Julian day numbers */
	int	flag_orthodox = 0;	/* user wants Orthodox easter */
	int	flag_easter = 0;	/* user wants easter date */
	int	flag_3months = 0;	/* user wants 3 month display (-3) */
	int	flag_after = 0;		/* user wants to see months after */
	int	flag_before = 0;	/* user wants to see months before */
	int	flag_specifiedmonth = 0;/* user wants to see this month (-m) */
	int	flag_givenmonth = 0;	/* user has specified month [n] */
	int	flag_givenyear = 0;	/* user has specified year [n] */
	char	*cp;			/* character pointer */
	char	*flag_today = NULL;	/* debug: use date as being today */
	char	*flag_month = NULL;	/* requested month as string */
	char	*flag_highlightdate = NULL; /* debug: date to highlight */
	int	before, after;
	const char    *locale;		/* locale to get country code */

	flag_nohighlight = 0;
	flag_weeks = 0;

	/*
	 * Use locale to determine the country code,
	 * and use the country code to determine the default
	 * switchdate and date format from the switches table.
	 */
	if (setlocale(LC_ALL, "") == NULL)
		warn("setlocale");
	locale = setlocale(LC_TIME, NULL);
	if (locale == NULL ||
	    strcmp(locale, "C") == 0 ||
	    strcmp(locale, "POSIX") == 0 ||
	    strcmp(locale, "ASCII") == 0 ||
	    strcmp(locale, "US-ASCII") == 0)
		locale = "_US";
	q = switches + sizeof(switches) / sizeof(struct djswitch);
	for (p = switches; p != q; p++)
		if ((cp = strstr(locale, p->cc)) != NULL && *(cp - 1) == '_')
			break;
	if (p == q) {
		nswitch = ndaysj(&dftswitch->dt);
	} else {
		nswitch = ndaysj(&p->dt);
		dftswitch = p;
	}


	/*
	 * Get the filename portion of argv[0] and set flag_backward if
	 * this program is called "cal".
	 */
	if (strncmp(basename(argv[0]), "cal", strlen("cal")) == 0)
		flag_backward = 1;

	/* Set the switch date to United Kingdom if backwards compatible */
	if (flag_backward)
		nswitchb = ndaysj(&ukswitch);

	before = after = -1;

	while ((ch = getopt(argc, argv, "3A:B:Cd:eH:hjJm:Nops:wy")) != -1)
		switch (ch) {
		case '3':
			flag_3months = 1;
			break;
		case 'A':
			if (flag_after > 0)
				errx(EX_USAGE, "Double -A specified");
			flag_after = strtol(optarg, NULL, 10);
			if (flag_after <= 0)
				errx(EX_USAGE,
				    "Argument to -A must be positive");
			break;
		case 'B':
			if (flag_before > 0)
				errx(EX_USAGE, "Double -A specified");
			flag_before = strtol(optarg, NULL, 10);
			if (flag_before <= 0)
				errx(EX_USAGE,
				    "Argument to -B must be positive");
			break;
		case 'J':
			if (flag_backward)
				usage();
			nswitch = ndaysj(&never);
			flag_julian_cal = 1;
			break;
		case 'C':
			flag_backward = 1;
			break;
		case 'N':
			flag_backward = 0;
			break;
		case 'd':
			flag_today = optarg;
			break;
		case 'H':
			flag_highlightdate = optarg;
			break;
		case 'h':
			flag_nohighlight = 1;
			break;
		case 'e':
			if (flag_backward)
				usage();
			flag_easter = 1;
			break;
		case 'j':
			flag_julian_day = 1;
			break;
		case 'm':
			if (flag_specifiedmonth)
				errx(EX_USAGE, "Double -m specified");
			flag_month = optarg;
			flag_specifiedmonth = 1;
			break;
		case 'o':
			if (flag_backward)
				usage();
			flag_orthodox = 1;
			flag_easter = 1;
			break;
		case 'p':
			if (flag_backward)
				usage();
			printcc();
			return (0);
			break;
		case 's':
			if (flag_backward)
				usage();
			q = switches +
			    sizeof(switches) / sizeof(struct djswitch);
			for (p = switches;
			     p != q && strcmp(p->cc, optarg) != 0; p++)
				;
			if (p == q)
				errx(EX_USAGE,
				    "%s: invalid country code", optarg);
			nswitch = ndaysj(&(p->dt));
			break;
		case 'w':
			if (flag_backward)
				usage();
			flag_weeks = 1;
			break;
		case 'y':
			flag_wholeyear = 1;
			break;
		default:
			usage();
		}

	argc -= optind;
	argv += optind;

	switch (argc) {
	case 2:
		if (flag_easter)
			usage();
		flag_month = *argv++;
		flag_givenmonth = 1;
		m = strtol(flag_month, NULL, 10);
		/* FALLTHROUGH */
	case 1:
		y = atoi(*argv);
		if (y < 1 || y > 9999)
			errx(EX_USAGE, "year `%s' not in range 1..9999", *argv);
		argv++;
		flag_givenyear = 1;
		break;
	case 0:
		if (flag_today != NULL) {
			y = strtol(flag_today, NULL, 10);
			m = strtol(flag_today + 5, NULL, 10);
		} else {
			time_t t;
			struct tm *tm;

			t = time(NULL);
			tm = localtime(&t);
			y = tm->tm_year + 1900;
			m = tm->tm_mon + 1;
		}
		break;
	default:
		usage();
	}

	if (flag_month != NULL) {
		if (parsemonth(flag_month, &m, &y)) {
			errx(EX_USAGE,
			    "%s is neither a month number (1..12) nor a name",
			    flag_month);
		}
	}

	/*
	 * What is not supported:
	 * -3 with -A or -B
	 *	-3 displays 3 months, -A and -B change that behaviour.
	 * -3 with -y
	 *	-3 displays 3 months, -y says display a whole year.
	 * -3 with a given year but no given month or without -m
	 *	-3 displays 3 months, no month specified doesn't make clear
	 *      which three months.
	 * -m with a given month
	 *	conflicting arguments, both specify the same field.
	 * -y with -m
	 *	-y displays the whole year, -m displays a single month.
	 * -y with a given month
	 *	-y displays the whole year, the given month displays a single
	 *	month.
	 * -y with -A or -B
	 *	-y displays the whole year, -A and -B display extra months.
	 */

	/* -3 together with -A or -B. */
	if (flag_3months && (flag_after || flag_before))
		errx(EX_USAGE, "-3 together with -A and -B is not supported.");
	/* -3 together with -y. */
	if (flag_3months && flag_wholeyear)
		errx(EX_USAGE, "-3 together with -y is not supported.");
	/* -3 together with givenyear but no givenmonth. */
	if (flag_3months && flag_givenyear &&
	    !(flag_givenmonth || flag_specifiedmonth))
		errx(EX_USAGE,
		    "-3 together with a given year but no given month is "
		    "not supported.");
	/* -m together with xx xxxx. */
	if (flag_specifiedmonth && flag_givenmonth)
		errx(EX_USAGE,
		    "-m together with a given month is not supported.");
	/* -y together with -m. */
	if (flag_wholeyear && flag_specifiedmonth)
		errx(EX_USAGE, "-y together with -m is not supported.");
	/* -y together with xx xxxx. */
	if (flag_wholeyear && flag_givenmonth)
		errx(EX_USAGE, "-y together a given month is not supported.");
	/* -y together with -A or -B. */
	if (flag_wholeyear && (flag_before > 0 || flag_after > 0))
		errx(EX_USAGE, "-y together a -A or -B is not supported.");
	/* The rest should be fine. */

	/* Select the period to display, in order of increasing priority .*/
	if (flag_wholeyear ||
	    (flag_givenyear && !(flag_givenmonth || flag_specifiedmonth))) {
		m = 1;
		before = 0;
		after = 11;
	}
	if (flag_givenyear && flag_givenmonth) {
		before = 0;
		after = 0;
	}
	if (flag_specifiedmonth) {
		before = 0;
		after = 0;
	}
	if (flag_before) {
		before = flag_before;
	}
	if (flag_after) {
		after = flag_after;
	}
	if (flag_3months) {
		before = 1;
		after = 1;
	}
	if (after == -1)
		after = 0;
	if (before == -1)
		before = 0;

	/* Highlight a specified day or today .*/
	if (flag_highlightdate != NULL) {
		dt.y = strtol(flag_highlightdate, NULL, 10);
		dt.m = strtol(flag_highlightdate + 5, NULL, 10);
		dt.d = strtol(flag_highlightdate + 8, NULL, 10);
	} else {
		time_t t;
		struct tm *tm1;

		t = time(NULL);
		tm1 = localtime(&t);
		dt.y = tm1->tm_year + 1900;
		dt.m = tm1->tm_mon + 1;
		dt.d = tm1->tm_mday;
	}
	highlightdate = sndaysb(&dt);

	/* And now we finally start to calculate and output calendars. */
	if (flag_easter)
		printeaster(y, flag_julian_cal, flag_orthodox);
	else
		if (flag_backward)
			monthrangeb(y, m, flag_julian_day, before, after);
		else
			monthranger(y, m, flag_julian_day, before, after);
	return (0);
}