Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 29 Dec 2009 13:14:14 +0000 (UTC)
From:      Edwin Groothuis <edwin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r201195 - user/edwin/calendar
Message-ID:  <200912291314.nBTDEEOG025172@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: edwin
Date: Tue Dec 29 13:14:13 2009
New Revision: 201195
URL: http://svn.freebsd.org/changeset/base/201195

Log:
  Be able to process strict dates (d/m), all dates (*/m, d/*) and dow
  per month or year.

Modified:
  user/edwin/calendar/calendar.c
  user/edwin/calendar/calendar.h
  user/edwin/calendar/dates.c
  user/edwin/calendar/day.c
  user/edwin/calendar/io.c
  user/edwin/calendar/parsedata.c

Modified: user/edwin/calendar/calendar.c
==============================================================================
--- user/edwin/calendar/calendar.c	Tue Dec 29 12:47:47 2009	(r201194)
+++ user/edwin/calendar/calendar.c	Tue Dec 29 13:14:13 2009	(r201195)
@@ -131,7 +131,6 @@ main(int argc, char *argv[])
 
 	settimes(f_time, f_dayBefore, f_dayAfter, &tp1, &tp2);
 	generatedates(&tp1, &tp2);
-	dumpdates();
 
 	if (doall)
 		while ((pw = getpwent()) != NULL) {

Modified: user/edwin/calendar/calendar.h
==============================================================================
--- user/edwin/calendar/calendar.h	Tue Dec 29 12:47:47 2009	(r201194)
+++ user/edwin/calendar/calendar.h	Tue Dec 29 13:14:13 2009	(r201195)
@@ -74,6 +74,7 @@ extern int	debug;		/* show parsing of th
 extern int	f_dayAfter;	/* days after current date */
 extern int	f_dayBefore;	/* days before current date */
 extern int	Friday;		/* day before weekend */
+extern int	year1, year2;
 
 /* events.c */
 /*
@@ -118,7 +119,7 @@ void	settimes(time_t,int, int, struct tm
 time_t	Mktime(char *);
 
 /* parsedata.c */
-int	parsedaymonth(char *, int *, int *, int *);
+int	parsedaymonth(char *, int *, int *, int *, int *);
 
 /* io.c */
 void	cal(void);
@@ -131,5 +132,11 @@ int	easter(int);
 
 /* dates.c */
 extern int cumdaytab[][14];
+extern int mondaytab[][14];
+extern int debug_remember;
 void	generatedates(struct tm *tp1, struct tm *tp2);
 void	dumpdates(void);
+int	remember_ymd(int y, int m, int d);
+int	remember_yd(int y, int d, int *rm, int *rd);
+int	first_dayofweek_of_year(int y);
+int	first_dayofweek_of_month(int y, int m);

Modified: user/edwin/calendar/dates.c
==============================================================================
--- user/edwin/calendar/dates.c	Tue Dec 29 12:47:47 2009	(r201194)
+++ user/edwin/calendar/dates.c	Tue Dec 29 13:14:13 2009	(r201195)
@@ -29,11 +29,12 @@ struct cal_day {
 	int julianday;			/* 000 .. 366 */
 	int dayofweek;			/* 0 .. 6 */
 	struct cal_day *nextday;
-	struct cal_month *month;
-	struct cal_year	*year;
+	struct cal_month *month;	/* points back */
+	struct cal_year	*year;		/* points back */
 	struct event *events;
 } cal_day;
 
+int debug_remember = 0;
 struct cal_year	*hyear = NULL;
 
 /* 1-based month, 0-based days, cumulative */
@@ -224,3 +225,115 @@ dumpdates(void)
 		y = y->nextyear;
 	}
 }
+
+int
+remember_ymd(int yy, int mm, int dd)
+{
+	struct cal_year *y;
+	struct cal_month *m;
+	struct cal_day *d;
+
+	if (debug_remember)
+		printf("remember_ymd: %d - %d - %d\n", yy, mm, dd);
+
+	y = hyear;
+	while (y != NULL) {
+		if (y->year != yy) {
+			y = y->nextyear;
+			continue;
+		}
+		m = y->months;
+		while (m != NULL) {
+			if (m->month != mm) {
+				m = m->nextmonth;
+				continue;
+			}
+			d = m->days;
+			while (d != NULL) {
+				if (d->dayofmonth == dd)
+					return (1);
+				d = d->nextday;
+				continue;;
+			}
+			return (0);
+		}
+		return (0);
+	}
+	return (0);
+}
+
+int
+remember_yd(int yy, int dd, int *rm, int *rd)
+{
+	struct cal_year *y;
+	struct cal_month *m;
+	struct cal_day *d;
+
+	if (debug_remember)
+		printf("remember_yd: %d - %d\n", yy, dd);
+
+	y = hyear;
+	while (y != NULL) {
+		if (y->year != yy) {
+			y = y->nextyear;
+			continue;
+		}
+		m = y->months;
+		while (m != NULL) {
+			d = m->days;
+			while (d != NULL) {
+				if (d->julianday == dd) {
+					*rm = m->month;
+					*rd = d->dayofmonth;
+					return (1);
+				}
+				d = d->nextday;
+			}
+			m = m->nextmonth;
+		}
+		return (0);
+	}
+	return (0);
+}
+
+int
+first_dayofweek_of_year(int yy)
+{
+	struct cal_year *y;
+
+	y = hyear;
+	while (y != NULL) {
+		if (y->year == yy)
+			return (y->firstdayofweek);
+		y = y->nextyear;
+	}
+
+	/* Should not happen */
+	return (-1);
+}
+
+int
+first_dayofweek_of_month(int yy, int mm)
+{
+	struct cal_year *y;
+	struct cal_month *m;
+
+	y = hyear;
+	while (y != NULL) {
+		if (y->year != yy) {
+			y = y->nextyear;
+			continue;
+		}
+		m = y->months;
+		while (m != NULL) {
+			if (m->month == mm)
+				return (m->firstdayofweek);
+			m = m->nextmonth;
+		}
+		/* Should not happen */
+		return (-1);
+	}
+
+	/* Should not happen */
+	return (-1);
+}

Modified: user/edwin/calendar/day.c
==============================================================================
--- user/edwin/calendar/day.c	Tue Dec 29 12:47:47 2009	(r201194)
+++ user/edwin/calendar/day.c	Tue Dec 29 13:14:13 2009	(r201195)
@@ -47,6 +47,7 @@ struct tm		tp1, tp2;
 time_t			time1, time2;
 const struct tm		tm0;
 char			dayname[10];
+int			year1, year2;
 
 
 void
@@ -63,8 +64,10 @@ settimes(time_t now, int before, int aft
 
 	time1 = now - SECSPERDAY * f_dayBefore;
 	localtime_r(&time1, tp1);
+	year1 = 1900 + tp1->tm_year;
 	time2 = now + SECSPERDAY * f_dayAfter;
 	localtime_r(&time2, tp2);
+	year2 = 1900 + tp2->tm_year;
 
 	header[5].iov_base = dayname;
 

Modified: user/edwin/calendar/io.c
==============================================================================
--- user/edwin/calendar/io.c	Tue Dec 29 12:47:47 2009	(r201194)
+++ user/edwin/calendar/io.c	Tue Dec 29 13:14:13 2009	(r201195)
@@ -91,6 +91,7 @@ cal(void)
 	int count, i;
 	int month[MAXCOUNT];
 	int day[MAXCOUNT];
+	int year[MAXCOUNT];
 	int flags;
 	static int d_first = -1;
 	char buf[2048 + 1];
@@ -168,16 +169,16 @@ cal(void)
 			pp--;
 		p = *pp;
 		*pp = '\0';
-		if ((count = parsedaymonth(buf, month, day, &flags)) == 0)
+		if ((count = parsedaymonth(buf, year, month, day, &flags)) == 0)
 			continue;
+		printf("%s - count: %d\n", buf, count);
 		*pp = p;
 		/* Find the last tab */
 		while (pp[1] == '\t')
 			pp++;
 
 		if (d_first < 0)
-			d_first =
-			    (*nl_langinfo(D_MD_ORDER) == 'd');
+			d_first = (*nl_langinfo(D_MD_ORDER) == 'd');
 
 		for (i = 0; i < count; i++) {
 			tm.tm_mon = month[i] - 1;

Modified: user/edwin/calendar/parsedata.c
==============================================================================
--- user/edwin/calendar/parsedata.c	Tue Dec 29 12:47:47 2009	(r201194)
+++ user/edwin/calendar/parsedata.c	Tue Dec 29 13:14:13 2009	(r201195)
@@ -125,7 +125,7 @@ determinestyle(char *date, int *flags,
 	}
 
 	/*
-	 * After this, leave by goto-ing to "allfine" or "fail" to restore the
+	 * AFTER this, leave by goto-ing to "allfine" or "fail" to restore the
 	 * original data in `date'.
 	 */
 	pold = *p;
@@ -241,6 +241,42 @@ allfine:
 	
 }
 
+static void
+remember(int index, int *y, int *m, int *d, int yy, int mm, int dd)
+{
+
+	y[index] = yy;
+	m[index] = mm;
+	d[index] = dd;
+}
+
+void
+debug_determinestyle(int dateonly, char *date, int flags, char *month,
+    int imonth, char *dayofmonth, int idayofmonth, char *dayofweek,
+    int idayofweek, char *modifieroffset, char *modifierindex, char *specialday)
+{
+
+	if (dateonly != 0) {
+		printf("-------\ndate: |%s|\n", date);
+		if (dateonly == 1)
+			return;
+	}
+	printf("flags: %x - %s\n", flags, showflags(flags));
+	if (modifieroffset[0] != '\0')
+		printf("modifieroffset: |%s|\n", modifieroffset);
+	if (modifierindex[0] != '\0')
+		printf("modifierindex: |%s|\n", modifierindex);
+	if (month[0] != '\0')
+		printf("month: |%s| (%d)\n", month, imonth);
+	if (dayofmonth[0] != '\0')
+		printf("dayofmonth: |%s| (%d)\n", dayofmonth, idayofmonth);
+	if (dayofweek[0] != '\0')
+		printf("dayofweek: |%s| (%d)\n", dayofweek, idayofweek);
+	if (specialday[0] != '\0')
+		printf("specialday: |%s|\n", specialday);
+}
+
+
 /*
  * Possible date formats include any combination of:
  *	3-charmonth			(January, Jan, Jan)
@@ -252,11 +288,13 @@ allfine:
  * along with the matched line.
  */
 int
-parsedaymonth(char *date, int *monthp, int *dayp, int *flags)
+parsedaymonth(char *date, int *yearp, int *monthp, int *dayp, int *flags)
 {
 	char month[100], dayofmonth[100], dayofweek[100], modifieroffset[100];
 	char modifierindex[100], specialday[100];
-	int idayofweek, imonth, idayofmonth;
+	int idayofweek, imonth, idayofmonth, year, index;
+
+	int *mondays, d, m, dow, rm, rd;
 
 	/*
 	 * CONVENTION
@@ -271,7 +309,9 @@ parsedaymonth(char *date, int *monthp, i
 	*flags = 0;
 
 	if (debug)
-		printf("-------\ndate: |%s|\n", date);
+		debug_determinestyle(1, date, *flags, month, imonth,
+		    dayofmonth, idayofmonth, dayofweek, idayofweek,
+		    modifieroffset, modifierindex, specialday);
 	if (determinestyle(date, flags, month, &imonth, dayofmonth,
 	    &idayofmonth, dayofweek, &idayofweek, modifieroffset,
 	    modifierindex, specialday) == 0) {
@@ -280,27 +320,92 @@ parsedaymonth(char *date, int *monthp, i
 		return (0);
 	}
 
-	if (debug) {
-		printf("flags: %x - %s\n", *flags, showflags(*flags));
-		if (modifieroffset[0] != '\0')
-			printf("modifieroffset: |%s|\n", modifieroffset);
-		if (modifierindex[0] != '\0')
-			printf("modifierindex: |%s|\n", modifierindex);
-		if (month[0] != '\0')
-			printf("month: |%s| (%d)\n", month, imonth);
-		if (dayofmonth[0] != '\0')
-			printf("dayofmonth: |%s| (%d)\n", dayofmonth,
-			    idayofmonth);
-		if (dayofweek[0] != '\0')
-			printf("dayofweek: |%s| (%d)\n", dayofweek, idayofweek);
-		if (specialday[0] != '\0')
-			printf("specialday: |%s|\n", specialday);
-	}
+	if (debug)
+		debug_determinestyle(0, date, *flags, month, imonth,
+		    dayofmonth, idayofmonth, dayofweek, idayofweek,
+		    modifieroffset, modifierindex, specialday);
+
+	index = 0;
+	for (year = year1; year <= year2; year++) {
+		mondays = mondaytab[isleap(year)];
+
+		/* Same day every year */
+		if (*flags == (F_MONTH | F_DAYOFMONTH)) {
+			if (!remember_ymd(year, imonth, idayofmonth))
+				continue;
+			remember(index++, yearp, monthp, dayp,
+			    year, imonth, idayofmonth);
+			continue;
+		}
+
+		/* Same day every month */
+		if (*flags == (F_ALLMONTH | F_DAYOFMONTH)) {
+			for (m = 1; m <= 12; m++) {
+				if (!remember_ymd(year, m, idayofmonth))
+					continue;
+				remember(index++, yearp, monthp, dayp,
+				    year, m, idayofmonth);
+			}
+			continue;
+		}
+
+		/* Every day of a month */
+		if (*flags == (F_ALLDAY | F_MONTH)) {
+			for (d = 1; d <= mondays[imonth]; d++) {
+				if (!remember_ymd(year, imonth, d))
+					continue;
+				remember(index++, yearp, monthp, dayp,
+				    year, imonth, d);
+			}
+			continue;
+		}
+
+		/* One day of every month */
+		if (*flags == (F_ALLMONTH | F_DAYOFWEEK)) {
+			for (m = 1; m <= 12; m++) {
+				if (!remember_ymd(year, m, idayofmonth))
+					continue;
+				remember(index++, yearp, monthp, dayp,
+				    year, m, idayofmonth);
+			}
+			continue;
+		}
+
+		/* Every dayofweek of the year */
+		if (*flags == (F_DAYOFWEEK | F_VARIABLE)) {
+			dow = first_dayofweek_of_year(year);
+			d = (idayofweek - dow + 8) % 7;
+			while (d <= 366) {
+				if (remember_yd(year, d, &rm, &rd))
+					remember(index++, yearp, monthp, dayp,
+					    year, rm, rd);
+				d += 7;
+			}
+			continue;
+		}
+
+		/* Every dayofweek of the month */
+		if (*flags == (F_DAYOFWEEK | F_MONTH | F_VARIABLE)) {
+			dow = first_dayofweek_of_month(year, imonth);
+			d = (idayofweek - dow + 8) % 7;
+			while (d <= mondays[imonth]) {
+				if (remember_ymd(year, imonth, d))
+					remember(index++, yearp, monthp, dayp,
+					    year, imonth, rd);
+				d += 7;
+			}
+			continue;
+
+		}
+
+		printf("Unprocessed:\n");
+		debug_determinestyle(2, date, *flags, month, imonth,
+		    dayofmonth, idayofmonth, dayofweek, idayofweek,
+		    modifieroffset, modifierindex, specialday);
 
-	if ((*flags & !F_VARIABLE) == (F_MONTH | F_DAYOFMONTH)) {
 	}
 
-	return (0);
+	return (index);
 
 #ifdef NOTDEF
 	if (!(v1 = getfield(date, &flags)))



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