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