svn commit: r205071 - head/usr.bin/ncal

Edwin Groothuis edwin at FreeBSD.org
Fri Mar 12 06:57:53 UTC 2010


Author: edwin
Date: Fri Mar 12 06:57:53 2010
New Revision: 205071
URL: http://svn.freebsd.org/changeset/base/205071

Log:
  - With the introduction of -A, -B and -3, not all combinations of
    arguments makes sense anymore. For example, what would a combination
    of -3 (show three months) and -y (show the whole year) do?
    We will abort on these cases.
  - Move the debug option -d to -H (from highlight), while -d is now
    used for setting the day of "today" so that -y and friends can
    be tested.

Modified:
  head/usr.bin/ncal/ncal.1
  head/usr.bin/ncal/ncal.c

Modified: head/usr.bin/ncal/ncal.1
==============================================================================
--- head/usr.bin/ncal/ncal.1	Fri Mar 12 06:56:51 2010	(r205070)
+++ head/usr.bin/ncal/ncal.1	Fri Mar 12 06:57:53 2010	(r205071)
@@ -117,12 +117,6 @@ Britain and her colonies switched to the
 Print the number of the week below each week column.
 .It Fl y
 Display a calendar for the specified year.
-.It Fl b
-Switch to backwards compatibility mode (for debugging).
-.It Fl d Ar yyyy-mm-dd
-Use
-.Ar yyyy-mm-dd
-as the current date (for debugging of highlighting).
 .It Fl 3
 Display the previous, current and next month surrounding today.
 .It Fl A Ar number
@@ -133,6 +127,16 @@ of months after the current month.
 Display the
 .Ar number
 of months before the current month.
+.It Fl b
+Switch to backwards compatibility mode (for debugging).
+.It Fl d Ar yyyy-mm
+Use
+.Ar yyyy-mm
+as the current date (for debugging of date selection).
+.It Fl H Ar yyyy-mm-dd
+Use
+.Ar yyyy-mm-dd
+as the current date (for debugging of highlighting).
 .El
 .Pp
 A single parameter specifies the year (1\(en9999) to be displayed;
@@ -148,6 +152,14 @@ year default to those of the current sys
 will display a calendar for the month of August in the current
 year).
 .Pp
+Not all options can be used together. For example
+.Dq Li -3 -A 2 -B 3 -y -m 7
+would mean:
+show me the three months around the seventh month, three before
+that, two after that and the whole year.
+.Nm ncal
+will warn about these combinations.
+.Pp
 A year starts on January 1.
 .Sh SEE ALSO
 .Xr calendar 3 ,

Modified: head/usr.bin/ncal/ncal.c
==============================================================================
--- head/usr.bin/ncal/ncal.c	Fri Mar 12 06:56:51 2010	(r205070)
+++ head/usr.bin/ncal/ncal.c	Fri Mar 12 06:57:53 2010	(r205071)
@@ -163,25 +163,25 @@ int	flag_nohighlight;	/* user doesn't wa
 int     flag_weeks;		/* user wants number of week */
 int     nswitch;		/* user defined switch date */
 int	nswitchb;		/* switch date for backward compatibility */
-int	today;
+int	highlightdate;
 
 char	*center(char *s, char *t, int w);
 wchar_t *wcenter(wchar_t *s, wchar_t *t, int w);
+int	firstday(int y, int m);
+void	highlight(char *dst, char *src, int len, int *extraletters);
 void	mkmonthr(int year, int month, int jd_flag, struct monthlines * monthl);
 void	mkmonthb(int year, int month, int jd_flag, struct monthlines * monthl);
 void	mkweekdays(struct weekdays * wds);
+void	monthranger(int year, int m, int jd_flag, int before, int after);
+void	monthrangeb(int year, int m, int jd_flag, int before, int after);
 int	parsemonth(const char *s, int *m, int *y);
 void	printcc(void);
 void	printeaster(int year, int julian, int orthodox);
-int	firstday(int y, int m);
 date	*sdater(int ndays, struct date * d);
 date	*sdateb(int ndays, struct date * d);
 int	sndaysr(struct date * d);
 int	sndaysb(struct date * d);
 static void	usage(void);
-void	monthranger(int year, int jd_flag, int m, int before, int after);
-void	monthrangeb(int year, int jd_flag, int m, int before, int after);
-void	highlight(char *dst, char *src, int len, int *extraletters);
 
 int
 main(int argc, char *argv[])
@@ -194,15 +194,21 @@ main(int argc, char *argv[])
 	int     m = 0;			/* month */
 	int	y = 0;			/* year */
 	int     flag_backward = 0;	/* user called cal--backward compat. */
-	int     flag_hole_year = 0;	/* user wants the whole year */
+	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;	/* use wants Orthodox easter */
-	int	flag_easter = 0;	/* use wants easter date */
+	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;
+	char	*flag_highlightdate = NULL; /* debug: date to highlight */
 	int	before, after;
 	const char    *locale;		/* locale to get country code */
 
@@ -250,20 +256,26 @@ main(int argc, char *argv[])
 
 	before = after = -1;
 
-	while ((ch = getopt(argc, argv, "A:B:3Jbd:ehjm:ops:wy")) != -1)
+	while ((ch = getopt(argc, argv, "A:B:3Jbd:eH:hjm:ops:wy")) != -1)
 		switch (ch) {
 		case '3':
-			before = after = 1;
+			flag_3months = 1;
 			break;
 		case 'A':
-			after = strtol(optarg, NULL, 10);
-			if (after < 0)
-				errx(1, "Argument to -A must be positive");
+			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':
-			before = strtol(optarg, NULL, 10);
-			if (before < 0)
-				errx(1, "Argument to -B must be positive");
+			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)
@@ -275,6 +287,9 @@ main(int argc, char *argv[])
 			flag_backward = 1;
 			break;
 		case 'd':
+			flag_today = optarg;
+			break;
+		case 'H':
 			flag_highlightdate = optarg;
 			break;
 		case 'h':
@@ -289,9 +304,10 @@ main(int argc, char *argv[])
 			flag_julian_day = 1;
 			break;
 		case 'm':
+			if (flag_specifiedmonth)
+				errx(EX_USAGE, "Double -m specified");
 			flag_month = optarg;
-			before = 0;
-			after = 0;
+			flag_specifiedmonth = 1;
 			break;
 		case 'o':
 			if (flag_backward)
@@ -324,7 +340,7 @@ main(int argc, char *argv[])
 			flag_weeks = 1;
 			break;
 		case 'y':
-			flag_hole_year = 1;
+			flag_wholeyear = 1;
 			break;
 		default:
 			usage();
@@ -338,22 +354,21 @@ main(int argc, char *argv[])
 		if (flag_easter)
 			usage();
 		flag_month = *argv++;
-		before = 0;
-		after = 0;
+		flag_givenmonth = 1;
 		m = strtol(flag_month, NULL, 10);
 		/* FALLTHROUGH */
 	case 1:
-		y = atoi(*argv++);
+		y = atoi(*argv);
 		if (y < 1 || y > 9999)
-			errx(EX_USAGE, "year %d not in range 1..9999", y);
-		if (before == -1 && after == -1) {
-			before = 0;
-			after = 11;
-			m = 1;
-		}
+			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;
 
@@ -361,22 +376,12 @@ main(int argc, char *argv[])
 			tm = localtime(&t);
 			y = tm->tm_year + 1900;
 			m = tm->tm_mon + 1;
-			if (before == -1)
-				before = 0;
-			if (after == -1)
-				after = 0;
 		}
 		break;
 	default:
 		usage();
 	}
 
-	if (flag_hole_year) {
-		m = 1;
-		before = 0;
-		after = 11;
-	}
-
 	if (flag_month != NULL) {
 		if (parsemonth(flag_month, &m, &y)) {
 			errx(EX_USAGE,
@@ -385,6 +390,84 @@ main(int argc, char *argv[])
 		}
 	}
 
+	/*
+	 * 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);
@@ -399,15 +482,16 @@ main(int argc, char *argv[])
 		dt.m = tm1->tm_mon + 1;
 		dt.d = tm1->tm_mday;
 	}
-	today = sndaysb(&dt);
+	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, flag_julian_day, m, before, after);
+			monthrangeb(y, m, flag_julian_day, before, after);
 		else
-			monthranger(y, flag_julian_day, m, before, after);
+			monthranger(y, m, flag_julian_day, before, after);
 	return (0);
 }
 
@@ -420,12 +504,12 @@ usage(void)
 	    "       cal [-hj] [-m month] [year]\n"
 	    "       ncal [-hJjpwy] [-s country_code] [[month] year]\n"
 	    "       ncal [-hJeo] [year]\n"
-	    "for debug the highlighting: [-b] [-d yyyy-mm-dd]\n",
+	    "for debug the highlighting: [-b] [-H yyyy-mm-dd] [-d yyyy-mm]\n",
 	    stderr);
 	exit(EX_USAGE);
 }
 
-/* print the assumed switches for all countries */
+/* Print the assumed switches for all countries. */
 void
 printcc(void)
 {
@@ -446,7 +530,7 @@ printcc(void)
 		printf(FSTR"\n", FSTRARG(p));
 }
 
-/* print the date of easter sunday */
+/* Print the date of easter sunday. */
 void
 printeaster(int y, int julian, int orthodox)
 {
@@ -491,8 +575,9 @@ printeaster(int y, int julian, int ortho
 #define	M2Y(m)	((m) / 12)
 #define	M2M(m)	(1 + (m) % 12) 
 
+/* Print all months for the period in the range [ before .. y-m .. after ]. */
 void
-monthrangeb(int y, int jd_flag, int m, int before, int after)
+monthrangeb(int y, int m, int jd_flag, int before, int after)
 {
 	struct monthlines year[12];
 	struct weekdays wds;
@@ -539,14 +624,14 @@ monthrangeb(int y, int jd_flag, int m, i
 		if (m != m1)
 			printf("\n");
 
-		/* Year at the top */
+		/* Year at the top. */
 		if (printyearheader && M2Y(m) != prevyear) {
 			sprintf(s, "%d", M2Y(m));
 			printf("%s\n", center(t, s, mpl * mw));
 			prevyear = M2Y(m);
 		}
 
-		/* Month names */
+		/* Month names. */
 		for (i = 0; i < count; i++)
 			if (printyearheader)
 				wprintf(L"%-*ls  ",
@@ -558,7 +643,7 @@ monthrangeb(int y, int jd_flag, int m, i
 			}
 		printf("\n");
 
-		/* Day of the week names */
+		/* Day of the week names. */
 		for (i = 0; i < count; i++) {
 			wprintf(L"%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls%s%ls ",
 				wdss, wds.names[6], wdss, wds.names[0],
@@ -568,6 +653,7 @@ monthrangeb(int y, int jd_flag, int m, i
 		}
 		printf("\n");
 
+		/* And the days of the month. */
 		for (i = 0; i != 6; i++) {
 			for (j = 0; j < count; j++)
 				printf("%-*s  ",
@@ -581,7 +667,7 @@ monthrangeb(int y, int jd_flag, int m, i
 }
 
 void
-monthranger(int y, int jd_flag, int m, int before, int after)
+monthranger(int y, int m, int jd_flag, int before, int after)
 {
 	struct monthlines year[12];
 	struct weekdays wds;
@@ -621,18 +707,18 @@ monthranger(int y, int jd_flag, int m, i
 			count++;
 		}
 
-		/* Empty line between two rows of months */
+		/* Empty line between two rows of months. */
 		if (m != m1)
 			printf("\n");
 
-		/* Year at the top */
+		/* Year at the top. */
 		if (printyearheader && M2Y(m) != prevyear) {
 			sprintf(s, "%d", M2Y(m));
 			printf("%s\n", center(t, s, mpl * mw));
 			prevyear = M2Y(m);
 		}
 
-		/* Month names */
+		/* Month names. */
 		wprintf(L"    ");
 		for (i = 0; i < count; i++)
 			if (printyearheader)
@@ -642,6 +728,7 @@ monthranger(int y, int jd_flag, int m, i
 				    mw - wcslen(year[i].name) - 1, M2Y(m + i));
 		printf("\n");
 
+		/* And the days of the month. */
 		for (i = 0; i != 7; i++) {
 			/* Week day */
 			wprintf(L"%.2ls", wds.names[i]);
@@ -654,6 +741,7 @@ monthranger(int y, int jd_flag, int m, i
 			printf("\n");
 		}
 
+		/* Week numbers. */
 		if (flag_weeks) {
 			printf("  ");
 			for (i = 0; i < count; i++)
@@ -709,7 +797,7 @@ mkmonthr(int y, int m, int jd_flag, stru
 	 */
 	firstm = first - weekday(first);
 
-	/* Set ds (daystring) and dw (daywidth) according to the jd_flag */
+	/* Set ds (daystring) and dw (daywidth) according to the jd_flag. */
 	if (jd_flag) {
 		ds = jdaystr;
 		dw = 4;
@@ -731,7 +819,7 @@ mkmonthr(int y, int m, int jd_flag, stru
 					dt.d = j - jan1 + 1;
 				else
 					sdater(j, &dt);
-				if (j == today && !flag_nohighlight)
+				if (j == highlightdate && !flag_nohighlight)
 					highlight(mlines->lines[i] + k,
 					    ds + dt.d * dw, dw, &l);
 				else
@@ -744,7 +832,7 @@ mkmonthr(int y, int m, int jd_flag, stru
 		mlines->extralen[i] = l;
 	}
 
-	/* fill the weeknumbers */
+	/* fill the weeknumbers. */
 	if (flag_weeks) {
 		for (j = firstm, k = 0; j < last;  k += dw, j += 7)
 			if (j <= nswitch)
@@ -781,7 +869,7 @@ mkmonthb(int y, int m, int jd_flag, stru
 		dw = 3;
 	}
 
-	/* Set name of month centered */
+	/* Set name of month centered. */
 	memset(&tm, 0, sizeof(tm));
 	tm.tm_mon = m;
 	wcsftime(mlines->name, sizeof(mlines->name) / sizeof(mlines->name[0]),
@@ -835,7 +923,7 @@ mkmonthb(int y, int m, int jd_flag, stru
 					dt.d = j - jan1 + 1;
 				else
 					sdateb(j, &dt);
-				if (j == today && !flag_nohighlight)
+				if (j == highlightdate && !flag_nohighlight)
 					highlight(mlines->lines[i] + k,
 					    ds + dt.d * dw, dw, &l);
 				else
@@ -852,7 +940,7 @@ mkmonthb(int y, int m, int jd_flag, stru
 	}
 }
 
-/* Put the local names of weekdays into the wds */
+/* Put the local names of weekdays into the wds. */
 void
 mkweekdays(struct weekdays *wds)
 {
@@ -878,9 +966,8 @@ mkweekdays(struct weekdays *wds)
 }
 
 /*
- * Compute the day number of the first
- * existing date after the first day in month.
- * (the first day in month and even the month might not exist!)
+ * Compute the day number of the first existing date after the first day in
+ * month. (the first day in month and even the month might not exist!)
  */
 int
 firstday(int y, int m)
@@ -933,7 +1020,7 @@ sndaysb(struct date *d)
 		return (ndaysj(d));
 }
 
-/* Inverse of sndays */
+/* Inverse of sndays. */
 struct date *
 sdater(int nd, struct date *d)
 {
@@ -944,7 +1031,7 @@ sdater(int nd, struct date *d)
 		return (jdate(nd, d));
 }
 
-/* Inverse of sndaysb */
+/* Inverse of sndaysb. */
 struct date *
 sdateb(int nd, struct date *d)
 {
@@ -955,7 +1042,7 @@ sdateb(int nd, struct date *d)
 		return (jdate(nd, d));
 }
 
-/* Center string t in string s of length w by putting enough leading blanks */
+/* Center string t in string s of length w by putting enough leading blanks. */
 char *
 center(char *s, char *t, int w)
 {
@@ -966,7 +1053,7 @@ center(char *s, char *t, int w)
 	return (s);
 }
 
-/* Center string t in string s of length w by putting enough leading blanks */
+/* Center string t in string s of length w by putting enough leading blanks. */
 wchar_t *
 wcenter(wchar_t *s, wchar_t *t, int w)
 {
@@ -1021,7 +1108,7 @@ highlight(char *dst, char *src, int len,
 
 		term_se = term_so = NULL;
 
-		/* On how to highlight on this type of terminal (if any) */
+		/* On how to highlight on this type of terminal (if any). */
 		if (isatty(STDOUT_FILENO) && tgetent(tbuf, NULL) == 1) {
 			b = cbuf;
 			term_so = tgetstr("so", &b);
@@ -1040,42 +1127,45 @@ highlight(char *dst, char *src, int len,
 		return;
 	}
 
-	/* If it is a real terminal, use the data from the termcap database. */
+	/*
+	 * If it is a real terminal, use the data from the termcap database.
+	 */
 	if (term_so != NULL && term_se != NULL) {
-		/* separator */
+		/* separator. */
 		dst[0] = ' ';
 		dst++;
-		/* highlight on */
+		/* highlight on. */
 		memcpy(dst, term_so, strlen(term_so));
 		dst += strlen(term_so);
-		/* the actual text (minus leading space) */
+		/* the actual text. (minus leading space) */
 		len--;
 		src++;
 		memcpy(dst, src, len);
 		dst += len;
-		/* highlight off */
+		/* highlight off. */
 		memcpy(dst, term_se, strlen(term_se));
 		*extralen = strlen(term_so) + strlen(term_se);
 		return;
 	}
 
 	/*
-	 * Otherwise, print a _, backspace and the letter
+	 * Otherwise, print a _, backspace and the letter.
 	 */
 	*extralen = 0;
-	/* skip leading space */
+	/* skip leading space. */
 	src++;
 	len--;
-	/* separator */
+	/* separator. */
 	dst[0] = ' ';
 	dst++;
 	while (len > 0) {
-		/* _ and backspace */
+		/* _ and backspace. */
 		memcpy(dst, "_\010", 2);
 		dst += 2;
 		*extralen += 2;
-		/* the character */
+		/* the character. */
 		*dst++ = *src++;
 		len--;
 	}
+	return;
 }


More information about the svn-src-head mailing list