Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 2 Mar 2010 21:12:06 +0000 (UTC)
From:      Edwin Groothuis <edwin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r204603 - user/edwin/ncal
Message-ID:  <201003022112.o22LC6TQ044722@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: edwin
Date: Tue Mar  2 21:12:06 2010
New Revision: 204603
URL: http://svn.freebsd.org/changeset/base/204603

Log:
  To facilitate the features -3, -A and -B: Rewrite on the way ranges
  of months are displayed for ncal. (cal still pending).

Modified:
  user/edwin/ncal/Makefile
  user/edwin/ncal/ncal.1
  user/edwin/ncal/ncal.c

Modified: user/edwin/ncal/Makefile
==============================================================================
--- user/edwin/ncal/Makefile	Tue Mar  2 21:10:44 2010	(r204602)
+++ user/edwin/ncal/Makefile	Tue Mar  2 21:12:06 2010	(r204603)
@@ -4,9 +4,10 @@ PROG=	ncal
 
 DPADD=	${LIBCALENDAR} ${LIBTERMCAP}
 LDADD=	-lcalendar -ltermcap
+CFLAGS+= -I/usr/src/contrib/tzcode/libc/
 WARNS?=	1
 
-LINKS=	${BINDIR}/ncal ${BINDIR}/cal
+#LINKS=	${BINDIR}/ncal ${BINDIR}/cal
 MLINKS=	ncal.1 cal.1
 
 .include <bsd.prog.mk>

Modified: user/edwin/ncal/ncal.1
==============================================================================
--- user/edwin/ncal/ncal.1	Tue Mar  2 21:10:44 2010	(r204602)
+++ user/edwin/ncal/ncal.1	Tue Mar  2 21:12:06 2010	(r204603)
@@ -115,6 +115,16 @@ Switch to backwards compatibility mode (
 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
+Display the
+.Ar number
+of months after the current month.
+.It Fl B Ar number
+Display the
+.Ar number
+of months before the current month.
 .El
 .Pp
 A single parameter specifies the year (1\(en9999) to be displayed;

Modified: user/edwin/ncal/ncal.c
==============================================================================
--- user/edwin/ncal/ncal.c	Tue Mar  2 21:10:44 2010	(r204602)
+++ user/edwin/ncal/ncal.c	Tue Mar  2 21:12:06 2010	(r204603)
@@ -184,6 +184,8 @@ int     sndays(struct date * d);
 int     sndaysb(struct date * d);
 static void usage(void);
 int     weekdayb(int nd);
+void	monthrange(int year, int jd_flag, int m, int before, int after);
+void	monthrangeb(int year, int jd_flag, int m, int before, int after);
 
 int
 main(int argc, char *argv[])
@@ -204,6 +206,7 @@ main(int argc, char *argv[])
 	char	*cp;			/* character pointer */
 	char	*flag_month = NULL;	/* requested month as string */
 	char	*flag_date = NULL;
+	int	before, after;
 	const char    *locale;		/* locale to get country code */
 	char tbuf[1024], cbuf[512], *b;
 	time_t t;
@@ -265,8 +268,23 @@ main(int argc, char *argv[])
 	if (flag_backward)
 		nswitchb = ndaysj(&ukswitch);
 
-	while ((ch = getopt(argc, argv, "Jbd:ehjm:ops:wy")) != -1)
+	before = after = -1;
+
+	while ((ch = getopt(argc, argv, "A:B:3Jbd:ehjm:ops:wy")) != -1)
 		switch (ch) {
+		case '3':
+			before = after = 1;
+			break;
+		case 'A':
+			after = strtol(optarg, NULL, 10);
+			if (after < 0)
+				errx(1, "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");
+			break;
 		case 'J':
 			if (flag_backward)
 				usage();
@@ -343,6 +361,9 @@ main(int argc, char *argv[])
 		y = atoi(*argv++);
 		if (y < 1 || y > 9999)
 			errx(EX_USAGE, "year %d not in range 1..9999", y);
+		before = 0;
+		after = 11;
+		m = 1;
 		break;
 	case 0:
 		{
@@ -353,6 +374,10 @@ 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:
@@ -379,17 +404,11 @@ main(int argc, char *argv[])
 
 	if (flag_easter)
 		printeaster(y, flag_julian_cal, flag_orthodox);
-	else if (argc == 1 || flag_hole_year) {
-		if (flag_backward)
-			printyearb(y, flag_julian_day);
-		else
-			printyear(y, flag_julian_day);
-	} else
+	else
 		if (flag_backward)
-			printmonthb(y, m, flag_julian_day);
+			monthrangeb(y, flag_julian_day, m, before, after);
 		else
-			printmonth(y, m, flag_julian_day);
-
+			monthrange(y, flag_julian_day, m, before, after);
 	return (0);
 }
 
@@ -512,6 +531,113 @@ printmonthb(int y, int m, int jd_flag)
 }
 
 void
+monthrangeb(int y, int jd_flag, int m, int before, int after)
+{
+	printf("BUUURP\n");
+}
+
+#define	DECREASEMONTH(m, y) 		\
+		if (--m == 0) {		\
+			m = 12;		\
+			y--;		\
+		}
+#define	INCREASEMONTH(m, y)		\
+		if (++(m) == 13) {	\
+			(m) = 1;	\
+			(y)++;		\
+		}
+#define	M2Y(m)	((m) / 12)
+#define	M2M(m)	(1 + (m) % 12) 
+void
+monthrange(int y, int jd_flag, int m, int before, int after)
+{
+	struct monthlines year[12];
+	struct weekdays wds;
+	char    s[80], t[80];
+	int     i, j;
+	int     mpl;
+	int     mw;
+	int	m1, m2;
+	int	prevyear = -1;
+	int	printyearheader;
+
+	mpl = jd_flag ? 3 : 4;
+	mw = jd_flag ? MONTH_WIDTH_J : MONTH_WIDTH;
+
+	while (before != 0) {
+		DECREASEMONTH(m, y);
+		before--;
+		after++;
+	}
+	m1 = y * 12 + m - 1;
+	m2 = m1 + after;
+
+	mkweekdays(&wds);
+
+	/*
+	 * The year header is printed when there are more than 'mpl' months
+	 * and if the first month is a multitude of 'mpl'.
+	 * If not, it will print the year behind every month.
+	 */
+	printyearheader = (after >= mpl - 1) && (M2M(m1) - 1) % mpl == 0;
+
+	m = m1;
+	while (m <= m2) {
+		int count = 0;
+		for (i = 0; i != mpl && m + i <= m2; i++) {
+			mkmonth(M2Y(m + i), M2M(m + i) - 1, jd_flag, year + i);
+			count++;
+		}
+
+#define MW(mw, ms, ml) \
+	strlen(ms) > (ml) ? (mw) + 9 : (mw)
+
+		/* Empty line between two months */
+		if (m != m1)
+			printf("\n");
+
+		/* Year at the top, only for calendars which start at January */
+		if (printyearheader && M2Y(m) != prevyear) {
+			sprintf(s, "%d", M2Y(m));
+			printf("%s\n", center(t, s, mpl * mw));
+			prevyear = M2Y(m);
+		}
+
+		/* Month names */
+		wprintf(L"    ");
+		for (i = 0; i < count; i++)
+			if (printyearheader)
+				wprintf(L"%-*ls", mw, year[i].name);
+			else
+				wprintf(L"%-ls %-*d", year[i].name,
+				    mw - wcslen(year[i].name) - 1, M2Y(m + i));
+		printf("\n");
+
+		for (i = 0; i != 7; i++) {
+			/* Week day */
+			wprintf(L"%.2ls", wds.names[i]);
+
+			/* Full months */
+			for (j = 0; j < count; j++)
+				printf("%-*s",
+				    MW(mw, year[j].lines[i],
+					year[j].linelen[i]), year[j].lines[i]);
+			printf("\n");
+		}
+
+		if (flag_weeks) {
+			printf("  ");
+			for (i = 0; i < count; i++)
+				printf("%-*s", mw, year[i].weeks);
+			printf("\n");
+		}
+
+		m += mpl;
+	}
+	return;
+}
+
+void
 printyear(int y, int jd_flag)
 {
 	struct monthlines year[12];



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201003022112.o22LC6TQ044722>