bin/113286: [patch] make output of calendar(1) properly sorted

Edwin Groothuis edwin at mavetju.org
Sun Jun 3 12:10:03 UTC 2007


>Number:         113286
>Category:       bin
>Synopsis:       [patch] make output of calendar(1) properly sorted
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sun Jun 03 12:10:03 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Edwin Groothuis
>Release:        FreeBSD 6.2-RELEASE-p4 i386
>Organization:
-
>Environment:
System: FreeBSD k7.mavetju 6.2-RELEASE-p4 FreeBSD 6.2-RELEASE-p4 #0: Thu Apr 26 17:55:55 UTC 2007 root at i386-builder.daemonology.net:/usr/obj/usr/src/sys/SMP i386

>Description:

The output of calendar isn't sorted by day, for example see the
output of "calendar -f /usr/share/calendar/calendar.all ":

Jun  3  Henry James born, 1811
Jun  3* Trinity Sunday (7 days after Pentecost)
Jun  4  Roquefort cheese developed, 1070
Jun  3  Confederate Memorial Day in Kentucky & Louisiana
Jun  3  Labor Day in Bahamas
Jun  3* Bank Holiday in Rep. of Ireland
[...]

With this patch it will sort it properly:

 3 ÉÀÎ* ôÒÏÉÃÉÎ äÅÎØ
Jún  3  Klotild
 3 Jun  Georges Bizet in Bougival bei Paris gestorben, 1875
 3 jui* S'il pleut à la Trinité,
        Il pleut tous les jours de l'année.
 3 jui  N'oubliez pas les Kévin !
Jun  3  Georges Bizet dies in Bougival, Paris, France, 1875
[...]


>How-To-Repeat:
>Fix:

The big change at day.c:378 is to improve on the patches earlier
submitted in bin/113250.

The rest all has to do with sorting.

Index: calendar.h
===================================================================
RCS file: /home/ncvs/src/usr.bin/calendar/calendar.h,v
retrieving revision 1.11
diff -u -r1.11 calendar.h
--- calendar.h	7 May 2007 11:18:30 -0000	1.11
+++ calendar.h	3 Jun 2007 12:05:56 -0000
@@ -42,6 +42,7 @@
 extern struct tm *tp;
 extern const char *calendarFile;
 extern int *cumdays;
+extern int yrdays;
 extern struct fixs neaster, npaskha;
 
 void	 cal(void);
@@ -68,7 +69,7 @@
 #define	F_ISDAYVAR	0x04 /* variables day of week, like SundayLast */
 #define	F_EASTER	0x08 /* Easter or easter depending days */
 
-extern int f_dayAfter; /* days after current date */
+extern int f_dayAfter;	/* days after current date */
 extern int f_dayBefore; /* days bevore current date */
 extern int Friday;	/* day before weekend */
 
@@ -77,3 +78,15 @@
 	int len;
 };
 
+
+struct event *event_add(struct event *events, int month, int day, char *date, int var, char *txt);
+void event_continue(struct event *events, char *txt);
+void event_print_all(FILE *fp, struct event *events);
+struct event {
+	int month;
+	int day;
+	int var;
+	char *date;
+	char *text;
+	struct event *next;
+};
Index: day.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/calendar/day.c,v
retrieving revision 1.26
diff -u -r1.26 day.c
--- day.c	3 Jun 2007 03:07:10 -0000	1.26
+++ day.c	3 Jun 2007 12:05:57 -0000
@@ -49,7 +49,7 @@
 
 struct tm *tp;
 static const struct tm tm0;
-int *cumdays, offset, yrdays;
+int *cumdays, yrdays;
 char dayname[10];
 
 
@@ -151,7 +151,8 @@
 		cumdays = daytab[0];
 	}
 	/* Friday displays Monday's events */
-	offset = tp->tm_wday == Friday ? 3 : 1;
+	if (f_dayAfter == 0 && f_dayBefore ==0)
+		f_dayAfter = tp->tm_wday == Friday ? 3 : 1;
 	header[5].iov_base = dayname;
 
 	oldl = NULL;
@@ -378,24 +379,6 @@
 	fprintf(stderr, "day2: day %d(%d-%d) yday %d\n", *dayp, day, cumdays[month], tp->tm_yday);
 #endif
 
-	/* when only today and tomorrow (or today and the next three days if
-	   it is friday) is needed */
-	if (f_dayBefore == 0 &&
-	    f_dayAfter == 0 ) {
-		/* no year rollover */
-		if (day >= tp->tm_yday &&
-		    day <= tp->tm_yday + offset)
-			return (1);
-		/* year rollover */
-		if (tp->tm_yday + offset >= yrdays) {
-			int end = tp->tm_yday + offset - yrdays;
-			if (day <= end)
-				return (1);
-		}
-
-		return (0);
-	}
-
 	/* When days before or days after is specified */
 	/* no year rollover */
 	if (day >= tp->tm_yday - f_dayBefore &&
Index: io.c
===================================================================
RCS file: /home/ncvs/src/usr.bin/calendar/io.c,v
retrieving revision 1.20
diff -u -r1.20 io.c
--- io.c	7 May 2007 11:18:30 -0000	1.20
+++ io.c	3 Jun 2007 12:05:57 -0000
@@ -96,6 +96,7 @@
 	int var;
 	static int d_first = -1;
 	char buf[2048 + 1];
+	struct event *events = NULL;
 
 	if ((fp = opencal()) == NULL)
 		return;
@@ -155,16 +156,98 @@
 				(void)strftime(dbuf, sizeof(dbuf),
 					       d_first ? "%e %b" : "%b %e",
 					       &tm);
-				(void)fprintf(fp, "%s%c%s\n", dbuf,
-				    var ? '*' : ' ', p);
+				events = event_add(events, month, day, dbuf, var, p);
 			}
 		}
 		else if (printing)
-			fprintf(fp, "%s\n", buf);
+			event_continue(events, buf);
 	}
+
+	event_print_all(fp, events);
 	closecal(fp);
 }
 
+struct event *
+event_add(struct event *events, int month, int day, char *date, int var, char *txt)
+{
+	struct event *e;
+
+	e = (struct event *)calloc(1, sizeof(struct event));
+	if (e == NULL)
+		errx(1, "event_add: cannot allocate memory");
+	e->month = month;
+	e->day = day;
+	e->var = var;
+	e->date = strdup(date);
+	if (e->date == NULL)
+		errx(1, "event_add: cannot allocate memory");
+	e->text = strdup(txt);
+	if (e->text == NULL)
+		errx(1, "event_add: cannot allocate memory");
+	e->next = events;
+
+	return e;
+}
+
+void
+event_continue(struct event *e, char *txt)
+{
+	char *text;
+
+	text = strdup(e->text);
+	if (text == NULL)
+		errx(1, "event_continue: cannot allocate memory");
+
+	free(e->text);
+	e->text = (char *)malloc(strlen(text) + strlen(txt) + 3);
+	if (e->text == NULL)
+		errx(1, "event_continue: cannot allocate memory");
+	strcpy(e->text, text);
+	strcat(e->text, "\n");
+	strcat(e->text, txt);
+	free(text);
+
+	return;
+}
+
+void
+event_print_all(FILE *fp, struct event *events)
+{
+	struct event *e, *e_next;
+	int daycount = f_dayAfter + f_dayBefore;
+	int daycounter;
+	int day, month;
+
+	for (daycounter = 0; daycounter <= daycount; daycounter++) {
+		day = tp->tm_yday - f_dayBefore + daycounter;
+		if (day < 0) day += yrdays;
+		if (day >= yrdays) day -= yrdays;
+
+		month = 1;
+		while (month <= 12) {
+			if (day <= cumdays[month])
+				break;
+			month++;
+		}
+		month--;
+		day -= cumdays[month];
+
+#ifdef DEBUG
+		fprintf(stderr,"event_print_allmonth: %d, day: %d\n",month,day);
+#endif
+
+		for (e = events; e != NULL; e = e_next ) {
+			e_next = e->next;
+
+			if (month != e->month || day != e->day) 
+				continue;
+
+			(void)fprintf(fp, "%s%c%s\n", e->date,
+			    e->var ? '*' : ' ', e->text);
+		}
+	}
+}
+
 int
 getfield(char *p, char **endp, int *flags)
 {
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list