Example #1
0
int
main(int argc, char *argv[])
{
	struct tm *local_time;
	time_t now;
	int ch, month, year, yflag;
	const char *errstr;

	yflag = year = 0;
	while ((ch = getopt(argc, argv, "jmwy")) != -1)
		switch(ch) {
		case 'j':
			julian = 1;
			break;
		case 'm':
			mflag = 1;
			break;
		case 'w':
			wflag = 1;
			break;
		case 'y':
			yflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (julian && wflag)
		usage();

	day_headings = DAY_HEADINGS_S;
	sep1752 = sep1752s;
	if (mflag && julian) {
		sep1752 = sep1752jm;
		day_headings = DAY_HEADINGS_JM;
	} else if (mflag) {
		sep1752 = sep1752m;
		day_headings = DAY_HEADINGS_M;
	} else if (julian) {
		sep1752 = sep1752js;
		day_headings = DAY_HEADINGS_JS;
	}

	month = 0;
	switch(argc) {
	case 2:
		month = parsemonth(*argv++);
		if (!month)
			errx(1, "Unable to parse month");
		/* FALLTHROUGH */
	case 1:
		if (argc == 1 && !isdigit((unsigned char)*argv[0])) {
			month = parsemonth(*argv);
			if (!month)
				errx(1, "illegal year value: use 1-9999");
			(void)time(&now);
			local_time = localtime(&now);
			year = local_time->tm_year + TM_YEAR_BASE;
		} else {
			year = strtonum(*argv, 1, 9999, &errstr);
			if (errstr)
				errx(1, "illegal year value: use 1-9999");
		}
		break;
	case 0:
		(void)time(&now);
		local_time = localtime(&now);
		year = local_time->tm_year + TM_YEAR_BASE;
		if (!yflag)
			month = local_time->tm_mon + 1;
		break;
	default:
		usage();
	}

	if (month)
		monthly(month, year);
	else if (julian)
		j_yearly(year);
	else
		yearly(year);
	exit(0);
}
Example #2
0
int
main(int argc, char **argv) {
	struct tm *local_time;
	time_t now;
	int ch, day, month, year, yflag;
	char *progname, *p;
	int num_months = NUM_MONTHS;

	progname = argv[0];
	if ((p = strrchr(progname, '/')) != NULL)
		progname = p+1;
	__progname = progname;

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

#if defined(HAVE_LIBNCURSES) || defined(HAVE_LIBNCURSESW) || defined(HAVE_LIBTERMCAP)
	if ((term = getenv("TERM"))) {
		int ret;
		my_setupterm(term, 1, &ret);
		if (ret > 0) {
			Senter = my_tgetstr("so","smso");
			Sexit = my_tgetstr("se","rmso");
			Slen = strlen(Senter) + strlen(Sexit);
		}
	}
#endif

/*
 * The traditional Unix cal utility starts the week at Sunday,
 * while ISO 8601 starts at Monday. We read the start day from
 * the locale database, which can be overridden with the
 * -s (Sunday) or -m (Monday) options.
 */
#if HAVE_DECL__NL_TIME_WEEK_1STDAY
	/*
	 * You need to use 2 locale variables to get the first day of the week.
	 * This is needed to support first_weekday=2 and first_workday=1 for
	 * the rare case where working days span across 2 weeks.
	 * This shell script shows the combinations and calculations involved:

	 for LANG in en_US ru_RU fr_FR csb_PL POSIX; do
	   printf "%s:\t%s + %s -1 = " $LANG $(locale week-1stday first_weekday)
	   date -d"$(locale week-1stday) +$(($(locale first_weekday)-1))day" +%w
	 done

	 en_US:  19971130 + 1 -1 = 0  #0 = sunday
	 ru_RU:  19971130 + 2 -1 = 1
	 fr_FR:  19971201 + 1 -1 = 1
	 csb_PL: 19971201 + 2 -1 = 2
	 POSIX:  19971201 + 7 -1 = 0
	 */
	{
		int wfd;
		union { unsigned int word; char *string; } val;
		val.string = nl_langinfo(_NL_TIME_WEEK_1STDAY);

		wfd = val.word;
		wfd = day_in_week(wfd % 100, (wfd / 100) % 100, wfd / (100 * 100));
		weekstart = (wfd + *nl_langinfo(_NL_TIME_FIRST_WEEKDAY) - 1) % 7;
	}
#endif

	yflag = 0;
	while ((ch = getopt(argc, argv, "13mjsyV")) != -1)
		switch(ch) {
		case '1':
			num_months = 1;		/* default */
			break;
		case '3':
			num_months = 3;
			break;
		case 's':
			weekstart = 0;		/* default */
			break;
		case 'm':
			weekstart = 1;
			break;
		case 'j':
			julian = 1;
			break;
		case 'y':
			yflag = 1;
			break;
		case 'V':
			printf(_("%s from %s\n"),
			       progname, PACKAGE_STRING);
			return 0;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	time(&now);
	local_time = localtime(&now);

	day = month = year = 0;
	switch(argc) {
	case 3:
		if ((day = atoi(*argv++)) < 1 || day > 31)
			errx(1, _("illegal day value: use 1-%d"), 31);
		/* FALLTHROUGH */
	case 2:
		if ((month = atoi(*argv++)) < 1 || month > 12)
			errx(1, _("illegal month value: use 1-12"));
		/* FALLTHROUGH */
	case 1:
		if ((year = atoi(*argv)) < 1 || year > 9999)
			errx(1, _("illegal year value: use 1-9999"));
		if (day) {
			int dm = days_in_month[leap_year(year)][month];
			if (day > dm)
				errx(1, _("illegal day value: use 1-%d"), dm);
			day = day_in_year(day, month, year);
		} else if ((local_time->tm_year + 1900) == year) {
			day = local_time->tm_yday + 1;
		}
		if (!month)
			yflag=1;
		break;
	case 0:
		day = local_time->tm_yday + 1;
		year = local_time->tm_year + 1900;
		month = local_time->tm_mon + 1;
		break;
	default:
		usage();
	}
	headers_init();

	if (!isatty(1))
		day = 0; /* don't highlight */

	if (yflag && julian)
		j_yearly(day, year);
	else if (yflag)
		yearly(day, year);
	else if (num_months == 1)
		monthly(day, month, year);
	else if (num_months == 3)
		monthly3(day, month, year);
	exit(0);
}