svn commit: r204847 - user/edwin/ncal

Edwin Groothuis edwin at FreeBSD.org
Sun Mar 7 21:39:48 UTC 2010


Author: edwin
Date: Sun Mar  7 21:39:47 2010
New Revision: 204847
URL: http://svn.freebsd.org/changeset/base/204847

Log:
  - split highlighting-of-today code from the calculate-the-month code.
  - in case the output is not a terminal, use the _ backspace trick
    to highlight (keeps less(1) happy).

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

Modified: user/edwin/ncal/Makefile
==============================================================================
--- user/edwin/ncal/Makefile	Sun Mar  7 21:27:47 2010	(r204846)
+++ user/edwin/ncal/Makefile	Sun Mar  7 21:39:47 2010	(r204847)
@@ -4,7 +4,6 @@ PROG=	ncal
 
 DPADD=	${LIBCALENDAR} ${LIBTERMCAP}
 LDADD=	-lcalendar -ltermcap
-WARNS?=	6
 
 LINKS=	${BINDIR}/ncal ${BINDIR}/cal
 MLINKS=	ncal.1 cal.1

Modified: user/edwin/ncal/ncal.c
==============================================================================
--- user/edwin/ncal/ncal.c	Sun Mar  7 21:27:47 2010	(r204846)
+++ user/edwin/ncal/ncal.c	Sun Mar  7 21:39:47 2010	(r204847)
@@ -159,10 +159,10 @@ char jdaystr[] = "       1   2   3   4  
 		 " 350 351 352 353 354 355 356 357 358 359"
 		 " 360 361 362 363 364 365 366";
 
+int	flag_nohighlight;	/* user doesn't want a highlighted today */
 int     flag_weeks;		/* user wants number of week */
 int     nswitch;		/* user defined switch date */
 int	nswitchb;		/* switch date for backward compatibility */
-const char	*term_so, *term_se;
 int	today;
 
 char	*center(char *s, char *t, int w);
@@ -181,6 +181,7 @@ 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[])
@@ -204,15 +205,9 @@ main(int argc, char *argv[])
 	char	*flag_highlightdate = NULL;
 	int	before, after;
 	const char    *locale;		/* locale to get country code */
-	char tbuf[1024], cbuf[512], *b;
 
-	/* On how to highlight on this terminal */
-	term_se = term_so = NULL;
-	if (isatty(STDOUT_FILENO) && tgetent(tbuf, NULL) == 1) {
-		b = cbuf;
-		term_so = tgetstr("so", &b);
-		term_se = tgetstr("se", &b);
-	}
+	flag_nohighlight = 0;
+	flag_weeks = 0;
 
 	/*
 	 * Use locale to determine the country code,
@@ -283,7 +278,7 @@ main(int argc, char *argv[])
 			flag_highlightdate = optarg;
 			break;
 		case 'h':
-			term_so = term_se = NULL;
+			flag_nohighlight = 1;
 			break;
 		case 'e':
 			if (flag_backward)
@@ -723,27 +718,14 @@ mkmonthr(int y, int m, int jd_flag, stru
 	for (i = 0; i != 7; i++) {
 		l = 0;
 		for (j = firstm + i, k = 0; j < last; j += 7, k += dw) {
-			if (j == today &&
-			    (term_so != NULL && term_se != NULL)) {
-				l = strlen(term_so);
+			if (j == today && !flag_nohighlight) {
 				if (jd_flag)
 					dt.d = j - jan1 + 1;
 				else
 					sdater(j, &dt);
-				/* separator */
-				mlines->lines[i][k] = ' ';
-				/* the actual text */
-				memcpy(mlines->lines[i] + k + l,
-				    ds + dt.d * dw, dw);
-				/* highlight on */
-				memcpy(mlines->lines[i] + k + 1, term_so, l);
-				/* highlight off */
-				memcpy(mlines->lines[i] + k + l + dw, term_se,
-				    strlen(term_se));
-				l = strlen(term_se) + strlen(term_so);
-				continue;
-			}
-			if (j >= first) {
+				highlight(mlines->lines[i] + k, ds + dt.d * dw,
+				    dw, &l);
+			} else if (j >= first) {
 				if (jd_flag)
 					dt.d = j - jan1 + 1;
 				else
@@ -843,27 +825,14 @@ mkmonthb(int y, int m, int jd_flag, stru
 		l = 0;
 		for (j = firsts + 7 * i, k = 0; j < last && k != dw * 7;
 		    j++, k += dw) { 
-			if (j == today &&
-			    (term_so != NULL && term_se != NULL)) {
-				l = strlen(term_so);
+			if (j == today && !flag_nohighlight) {
 				if (jd_flag)
 					dt.d = j - jan1 + 1;
 				else
 					sdateb(j, &dt);
-				/* separator */
-				mlines->lines[i][k] = ' ';
-				/* the actual text */
-				memcpy(mlines->lines[i] + k + l,
-				    ds + dt.d * dw, dw);
-				/* highlight on */
-				memcpy(mlines->lines[i] + k + 1, term_so, l);
-				/* highlight off */
-				memcpy(mlines->lines[i] + k + l + dw, term_se,
-				    strlen(term_se));
-				l = strlen(term_se) + strlen(term_so);
-				continue;
-			}
-			if (j >= first) {
+				highlight(mlines->lines[i] + k, ds + dt.d * dw,
+				    dw, &l);
+			} else if (j >= first) {
 				if (jd_flag)
 					dt.d = j - jan1 + 1;
 				else
@@ -1037,3 +1006,70 @@ parsemonth(const char *s, int *m, int *y
 	}
 	return (1);
 }
+
+void
+highlight(char *dst, char *src, int len, int *extralen)
+{
+	static int first = 1;
+	static const char *term_so, *term_se;
+
+	if (first) {
+		char tbuf[1024], cbuf[512], *b;
+
+		term_se = term_so = NULL;
+
+		/* On how to highlight on this terminal */
+		if (isatty(STDOUT_FILENO) && tgetent(tbuf, NULL) == 1) {
+			b = cbuf;
+			term_so = tgetstr("so", &b);
+			term_se = tgetstr("se", &b);
+		}
+
+		first = 0;
+	}
+
+	/* This check is not necessary */
+	if (flag_nohighlight) {
+		memcpy(dst, src, len);
+		return;
+	}
+
+	/* If it is a real terminal, use the data from the termcap database. */
+	if (term_so != NULL && term_se != NULL) {
+		/* separator */
+		dst[0] = ' ';
+		dst++;
+		/* highlight on */
+		memcpy(dst, term_so, strlen(term_so));
+		dst += strlen(term_so);
+		/* the actual text (minus leading space) */
+		len--;
+		src++;
+		memcpy(dst, src, len);
+		dst += len;
+		/* highlight off */
+		memcpy(dst, term_se, strlen(term_se));
+		*extralen = strlen(term_so) + strlen(term_se);
+		return;
+	}
+
+	/*
+	 * Otherwise, print a _, backspace and the letter
+	 */
+	*extralen = 0;
+	/* skip leading space */
+	src++;
+	len--;
+	/* separator */
+	dst[0] = ' ';
+	dst++;
+	while (len > 0) {
+		/* _ and backspace */
+		memcpy(dst, "_\010", 2);
+		dst += 2;
+		*extralen += 2;
+		/* the character */
+		*dst++ = *src++;
+		len--;
+	}
+}


More information about the svn-src-user mailing list