summaryrefslogtreecommitdiffstats
path: root/mbbsd/calendar.c
diff options
context:
space:
mode:
authorin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
committerin2 <in2@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2002-03-07 23:13:44 +0800
commitae31e19f92e717919ac8e3db9039eb38d2b89aae (patch)
treec70164d6a1852344f44b04a653ae2815043512af /mbbsd/calendar.c
downloadpttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.gz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.bz2
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.lz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.xz
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.tar.zst
pttbbs-ae31e19f92e717919ac8e3db9039eb38d2b89aae.zip
Initial revision
git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/calendar.c')
-rw-r--r--mbbsd/calendar.c284
1 files changed, 284 insertions, 0 deletions
diff --git a/mbbsd/calendar.c b/mbbsd/calendar.c
new file mode 100644
index 00000000..78ca46cf
--- /dev/null
+++ b/mbbsd/calendar.c
@@ -0,0 +1,284 @@
+/* $Id: calendar.c,v 1.1 2002/03/07 15:13:48 in2 Exp $ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include "config.h"
+#include "pttstruct.h"
+#include "proto.h"
+#include "modes.h"
+
+typedef struct event_t {
+ int year, month, day, days;
+ int color;
+ char *content;
+ struct event_t *next;
+} event_t;
+
+static int MonthDay(int m, int leap) {
+ static int day[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
+
+ return leap && m == 2 ? 29 : day[m - 1];
+}
+
+static int IsLeap(int y) {
+ if(y % 400 == 0 || (y % 4 == 0 && y % 100 != 0))
+ return 1;
+ else
+ return 0;
+}
+
+static int Days(int y, int m, int d) {
+ int i, w;
+
+ w = 1 + 365 * (y - 1)
+ + ((y - 1) / 4) - ((y - 1) / 100) + ((y - 1) / 400)
+ + d - 1;
+ for(i = 1; i < m; i++)
+ w += MonthDay(i, IsLeap(y));
+ return w;
+}
+
+static int ParseDate(char *date, event_t *t) {
+ char *y, *m, *d;
+
+ y = strtok(date, "/");
+ m = strtok(NULL, "/");
+ d = strtok(NULL, "");
+ if(!y || !m || !d)
+ return 1;
+
+ t->year = atoi(y);
+ t->month = atoi(m);
+ t->day = atoi(d);
+ if(t->year < 1 || t->month < 1 || t->month > 12 ||
+ t->day < 1 || t->day > 31)
+ return 1;
+ t->days = Days(t->year, t->month, t->day);
+ return 0;
+}
+
+static int ParseColor(char *color) {
+ struct {
+ char *str;
+ int val;
+ } c[] = {
+ {"black", 0},
+ {"red", 1},
+ {"green", 2},
+ {"yellow", 3},
+ {"blue", 4},
+ {"magenta", 5},
+ {"cyan", 6},
+ {"white", 7}
+ };
+ int i;
+
+ for(i = 0; i < sizeof(c) / sizeof(c[0]); i++)
+ if(strcasecmp(color, c[i].str) == 0)
+ return c[i].val;
+ return 7;
+}
+
+static void InsertEvent(event_t *head, event_t *t) {
+ event_t *p;
+
+ for(p = head; p->next && p->next->days < t->days; p = p->next);
+ t->next = p->next;
+ p->next = t;
+}
+
+static void FreeEvent(event_t *e) {
+ event_t *n;
+
+ while(e) {
+ n = e->next;
+ free(e);
+ e = n;
+ }
+}
+
+extern userec_t cuser;
+
+static event_t *ReadEvent(int today) {
+ FILE *fp;
+ char buf[256];
+ static event_t head;
+
+ head.next = NULL;
+ setcalfile(buf, cuser.userid);
+ fp = fopen(buf, "r");
+ if(fp) {
+ while(fgets(buf, sizeof(buf), fp)) {
+ char *date, *color, *content;
+ event_t *t;
+
+ if(buf[0] == '#')
+ continue;
+
+ date = strtok(buf, " \t\n");
+ color = strtok(NULL, " \t\n");
+ content = strtok(NULL, "\n");
+ if(!date || !color || !content)
+ continue;
+
+ t = malloc(sizeof(event_t));
+ if(ParseDate(date, t) || t->days < today) {
+ free(t);
+ continue;
+ }
+ t->color = ParseColor(color) + 30;
+ for(; *content == ' ' || *content == '\t'; content++);
+ t->content = strdup(content);
+ InsertEvent(&head, t);
+ }
+ fclose(fp);
+ }
+ return head.next;
+}
+
+static char **AllocCalBuffer(int line, int len) {
+ int i;
+ char **p;
+
+ p = malloc(sizeof(char *) * line);
+ p[0] = malloc(sizeof(char) * line * len);
+ for(i = 1; i < line; i++)
+ p[i] = p[i - 1] + len;
+ return p;
+}
+
+static void FreeCalBuffer(char **buf) {
+ free(buf[0]);
+ free(buf);
+}
+
+#define CALENDAR_COLOR "\33[0;30;47m"
+#define HEADER_COLOR "\33[1;44m"
+#define HEADER_SUNDAY_COLOR "\33[31m"
+#define HEADER_DAY_COLOR "\33[33m"
+
+static int GenerateCalendar(char **buf, int y, int m, int today, event_t *e) {
+ static char *week_str[7] = {"日", "一", "二", "三", "四", "五", "六"};
+ static char *month_color[12] = {
+ "\33[1;32m", "\33[1;33m", "\33[1;35m", "\33[1;36m",
+ "\33[1;32m", "\33[1;33m", "\33[1;35m", "\33[1;36m",
+ "\33[1;32m", "\33[1;33m", "\33[1;35m", "\33[1;36m"
+ };
+ static char *month_str[12] = {
+ "一月 ", "二月 ", "三月 ", "四月 ", "五月 ", "六月 ",
+ "七月 ", "八月 ", "九月 ", "十月 ", "十一月", "十二月"
+ };
+
+ char *p, attr1[16], *attr2;
+ int i, d, w, line = 0, first_day = Days(y, m, 1);
+
+
+ /* week day banner */
+ p = buf[line];
+ p += sprintf(p, " %s%s%s%s", HEADER_COLOR, HEADER_SUNDAY_COLOR,
+ week_str[0], HEADER_DAY_COLOR);
+ for(i = 1; i < 7; i++)
+ p += sprintf(p, " %s", week_str[i]);
+ p += sprintf(p, "\33[m");
+
+ /* indent for first line */
+ p = buf[++line];
+ p += sprintf(p, " %s", CALENDAR_COLOR);
+ for(i = 0, w = first_day % 7; i < w; i++)
+ p += sprintf(p, " ");
+
+ /* initial event */
+ for(; e && e->days < first_day; e = e->next);
+
+ d = MonthDay(m, IsLeap(y));
+ for(i = 1; i <= d; i++, w = (w + 1) % 7) {
+ attr1[0] = 0;
+ attr2 = "";
+ while(e && e->days == first_day + i - 1) {
+ sprintf(attr1, "\33[1;%dm", e->color);
+ attr2 = CALENDAR_COLOR;
+ e = e->next;
+ }
+ if(today == first_day + i - 1) {
+ strcpy(attr1, "\33[1;37;42m");
+ attr2 = CALENDAR_COLOR;
+ }
+ p += sprintf(p, "%s%2d%s", attr1, i, attr2);
+
+ if(w == 6) {
+ p += sprintf(p, "\33[m");
+ p = buf[++line];
+ /* show month */
+ if(line >= 2 && line <= 4)
+ p += sprintf(p, "%s%2.2s\33[m %s", month_color[m - 1],
+ month_str[m - 1] + (line - 2) * 2,
+ CALENDAR_COLOR);
+ else if(i < d)
+ p += sprintf(p, " %s", CALENDAR_COLOR);
+ } else
+ *p++ = ' ';
+ }
+
+ /* fill up the last line */
+ if(w) {
+ for(w = 7 - w; w; w--)
+ p += sprintf(p, w == 1 ? " " : " ");
+ p += sprintf(p, "\33[m");
+ }
+ return line + 1;
+}
+
+int calendar() {
+ char **buf;
+ time_t t;
+ struct tm now;
+ int i, y, m, today, lines = 0;
+ event_t *head = NULL, *e = NULL;
+
+ /* initialize date */
+ time(&t);
+ memcpy(&now, localtime(&t), sizeof(struct tm));
+ today = Days(now.tm_year + 1900, now.tm_mon + 1, now.tm_mday);
+ y = now.tm_year + 1900, m = now.tm_mon + 1;
+
+ /* read event */
+ head = e = ReadEvent(today);
+
+ /* generate calendar */
+ buf = AllocCalBuffer(22, 256);
+ for(i = 0; i < 22; i++)
+ sprintf(buf[i], "%24s", "");
+ for(i = 0; i < 3; i++) {
+ lines += GenerateCalendar(buf + lines, y, m, today, e) + 1;
+ if(m == 12)
+ y++, m = 1;
+ else
+ m++;
+ }
+
+ /* output */
+ clear();
+ outc('\n');
+ for(i = 0; i < 22; i++) {
+ outs(buf[i]);
+ if(i == 0) {
+ prints("\t\33[1;37m現在是 %d.%02d.%02d %2d:%02d:%02d%cm\33[m",
+ now.tm_year + 1900, now.tm_mon + 1, now.tm_mday,
+ (now.tm_hour == 0 || now.tm_hour == 12) ?
+ 12 : now.tm_hour % 12, now.tm_min, now.tm_sec,
+ now.tm_hour >= 12 ? 'p' : 'a');
+ } else if(i >= 2 && e) {
+ prints("\t\33[1;37m(\33[%dm%3d\33[37m)\33[m %02d/%02d %s",
+ e->color, e->days - today,
+ e->month, e->day, e->content);
+ e = e->next;
+ }
+ outc('\n');
+ }
+ FreeEvent(head);
+ FreeCalBuffer(buf);
+ pressanykey();
+ return 0;
+}