From ae31e19f92e717919ac8e3db9039eb38d2b89aae Mon Sep 17 00:00:00 2001 From: in2 Date: Thu, 7 Mar 2002 15:13:44 +0000 Subject: Initial revision git-svn-id: http://opensvn.csie.org/pttbbs/pttbbs/trunk/pttbbs@1 63ad8ddf-47c3-0310-b6dd-a9e9d9715204 --- mbbsd/calendar.c | 284 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 mbbsd/calendar.c (limited to 'mbbsd/calendar.c') 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 +#include +#include +#include +#include +#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; +} -- cgit v1.2.3