1 /*
2 * schedule.c -- schedule manage
3 *
4 * Copyright (C) 1993,1997,1999,2003 by Yoshifumi Mori
5 *
6 * tab:4
7 */
8
9 #include "cdefs.h"
10 #include "extern.h"
11
12 #define SCHEDULE_FOLDTYPE_DEFAULT (MSG_FOLDTYPE_BASE + 1) /* type1 */
13 #define SCHEDULE_DEFAULT_RANGE 4 /* notify max 4 days */
14
15 char *schedule_filetbl[MAXSCHEDULEFILE];
16
17 #ifndef INCLUDE_CALENDAR
18 char *schedule_sortorder;
19 int schedule_sort = SORT_UP_ORDER;
20 int schedule_foldtype = SCHEDULE_FOLDTYPE_DEFAULT;
21 int schedule_limit = SCHEDULE_DEFAULT_RANGE;
22
23 static int schedule_sortflag;
24 static int schedule_sortorder_tbl[MAXSORTITEM]; /* ����_����_���� */
25 static int schedule_listup_flag;
26 static const int mesg_start_tbl[4][2] = { /* �ޤ��֤��Կ� */
27 { 13, 13 }, /* type0 1st:13, 2nd:13 */
28 { 14, 12 }, /* type1 1st:14, 2nd:12 */
29 { 14, 14 }, /* type2 1st:14, 2nd:14 */
30 { 16, 14 } /* type3 1st:16, 2nd:14 */
31 };
32 static int sc_range;
33 #else /* INCLUDE_CALENDAR */
34 char schedule_daytbl[MAXMONTH_SCHEDULE][MAXDAY_SCHEDULE];
35 #endif /* INCLUDE_CALENDAR */
36
37 #ifndef INCLUDE_CALENDAR
38 static int schedule_search(int index, const char *infile);
39 static int schedule_make_msg(int month, int day, int diffday, const char *comment, const char *msg);
40 static void schedule_listup(int diffday, int tm);
41 static void schedule_listadd(int sortorder_no, int diffday, int tm);
42 static void schedule_output(const char *msg, ...);
43 static int schedule_range(void);
44 #endif /* !INCLUDE_CALENDAR */
45
46 #ifndef INCLUDE_CALENDAR
47 /*
48 * �������塼���ɽ������
49 */
schedule(void)50 void schedule(void)
51 {
52 int i;
53 int j;
54 void (*output_func)(const char *msg, ...);
55
56 schedule_sortflag = TRUE;
57 schedule_sortorder_tbl[0] = 0;
58 schedule_sortorder_tbl[1] = 1;
59 schedule_sortorder_tbl[2] = 2;
60 schedule_listup_flag = FALSE;
61
62 if (schedule_foldtype < MSG_FOLDTYPE_BASE + 0 ||
63 schedule_foldtype > MSG_FOLDTYPE_BASE + 3) {
64 schedule_foldtype = SCHEDULE_FOLDTYPE_DEFAULT;
65 errprint("schedule", ERR_WARN, "schedule_foldtype error, default %d set", schedule_foldtype);
66 }
67 if (schedule_limit < -MAX_DAYOFMONTH || schedule_limit > MAX_DAYOFMONTH) {
68 schedule_limit = SCHEDULE_DEFAULT_RANGE;
69 errprint("schedule", ERR_WARN, "schedule_limit error, default %d set", schedule_limit);
70 }
71
72 schedule_sortflag = analysis_sortorder("schedule", schedule_sortorder, schedule_sortorder_tbl, schedule_sortflag);
73
74 sc_range = schedule_range();
75
76 list_init();
77
78 for (i = 0; i < MAXSCHEDULEFILE; i++) {
79 if (schedule_filetbl[i] != NULL) {
80 for (j = CENTER_MONTH; j < MAX_MONTH_TBL; j++) {
81 if (schedule_search(j, schedule_filetbl[i]) == FALSE &&
82 (mkfile_status & (SET_MKF_CC | SET_MKF_YY | SET_MKF_MM)) == 0) {
83 break;
84 }
85 }
86 }
87 }
88
89 if (schedule_foldtype == 0) {
90 output_func = pager_output;
91 } else {
92 output_func = schedule_output;
93 }
94 if (schedule_sortflag == FALSE) {
95 list_output(0, output_func);
96 } else {
97 for (i = 0; i < MAXSORTITEM; i++) {
98 if (schedule_sortorder_tbl[i] >= 0) {
99 list_output(schedule_sortorder_tbl[i], output_func);
100 }
101 }
102 }
103
104 list_free();
105 }
106
107 /*
108 * �ե����뤫�饹�����塼�����Ф�ɽ������
109 *
110 * return value:
111 * TRUE ���ェλ
112 * FALSE ���顼ȯ��(�ե����륪���ץ��)
113 *
114 * file format:
115 * year/month/day [*comment] message
116 */
117 static
schedule_search(int index,const char * infile)118 int schedule_search(int index, const char *infile)
119 {
120 char *bp;
121 char *lasts;
122 char *comment, *msg;
123 struct DATE_T date;
124 int pyear, pmonth, pmaxday;
125 div_t c;
126 int hitday;
127 int mindif;
128 int diffday;
129 int tm;
130
131 pyear = monthtbl[index].year;
132 pmonth = monthtbl[index].month;
133 pmaxday = monthtbl[index].dayofmonth;
134
135 if (openfile(make_filename2(infile, pyear, pmonth, 0))) {
136 return (FALSE);
137 }
138
139 while ((bp = getfile()) != NULL) {
140 lasts = NULL;
141 bp = strtok_r(bp, fmt_sep3, &lasts);
142 if (bp == NULL ||
143 read_date(0x0177, bp, &date, NULL) == DATE_NG) {
144 continue;
145 }
146
147 bp = strtok_r(NULL, fmt_sep4, &lasts);
148 if (bp == NULL) { /* ���դ����ιԤ�̵�� */
149 continue;
150 }
151
152 if (date.year == 0) {
153 date.year = pyear;
154 } else if (pyear != date.year) {
155 continue;
156 }
157 if (date.month == 0) {
158 date.month = pmonth;
159 } else if (pmonth != date.month) {
160 continue;
161 }
162
163 if (date.day == 0) {
164 if (index == CENTER_MONTH) {
165 date.day = calendar.day;
166 } else {
167 date.day = 1;
168 }
169 } else {
170 if (date.day < 0) { /* ��������,�������� */
171 date.day = -date.day;
172 if (date.day < 100) {
173 date.day = pmaxday - (date.day - 1);
174 } else {
175 c = div(date.day - 100, 10);
176 date.day = ((c.rem - 1) - monthtbl[index].first_dayofweek) + 1;
177 if (date.day < 1) {
178 date.day += 7;
179 }
180 if (c.quot > 5) { /* ��-n���� */
181 date.day = (c.rem - 1) - monthtbl[index].last_dayofweek;
182 if (date.day > 0) {
183 date.day -= 7;
184 }
185 date.day += pmaxday - (c.quot - 6) * 7;
186 } else if (c.quot > 0) { /* ��n���� */
187 date.day += (c.quot - 1) * 7;
188 } else {
189 hitday = -1;
190 mindif = 999;
191 /* ���ֶᤤ������1��õ�� */
192 while (date.day <= pmaxday) {
193 diffday = (int)(Julian(date.year, date.month, date.day) - calendar.julian_day);
194 if (diffday >= 0 && diffday < mindif) {
195 mindif = diffday;
196 hitday = date.day;
197 }
198 date.day += 7;
199 }
200 date.day = hitday;
201 }
202 }
203 }
204 if (date.day < 1 || date.day > pmaxday) {
205 continue;
206 }
207 }
208
209 diffday = (int)(Julian(date.year, date.month, date.day) - calendar.julian_day);
210 if (diffday < 0 || diffday > sc_range) {
211 continue;
212 }
213
214 if (*bp == '*') {
215 comment = xstrescape(undertospace(strtok_r(bp, fmt_sep3, &lasts) + 1));
216 bp = strtok_r(NULL, fmt_sep4, &lasts);
217 if (bp == NULL) { /* �����Ȥ����ιԤ�̵�� */
218 continue;
219 }
220 } else {
221 comment = " --:-- ";
222 }
223 msg = xstrescape(strip(bp));
224 tm = schedule_make_msg(date.month, date.day, diffday, comment, msg);
225 schedule_listup(diffday, tm);
226 }
227
228 closefile();
229
230 return (TRUE);
231 }
232
233 /*
234 * �������塼���å���������
235 *
236 * �������塼���������
237 */
238 static
schedule_make_msg(int month,int day,int diffday,const char * comment,const char * msg)239 int schedule_make_msg(int month, int day, int diffday, const char *comment, const char *msg)
240 {
241 int tm;
242 int h, m;
243
244 tm = 9999;
245 if (sscanf(comment, "%d:%d", &h, &m) == 2) {
246 if ((h >= 0 && h <= 23) && (m >= 0 && m <= 59)) {
247 tm = h * 100 + m;
248 }
249 }
250 if (diffday == 0) {
251 sprintf(msgbuf, "%-12.12s ", comment);
252 } else {
253 if (month == 0) {
254 strcpy(msgbuf, " --");
255 } else {
256 sprintf(msgbuf, " %02d", month);
257 }
258 if (day == 0) {
259 strcpy(&msgbuf[3], "/--");
260 } else {
261 sprintf(&msgbuf[3], "/%02d", day);
262 }
263 if (tm == 9999) {
264 strcpy(&msgbuf[6], " --:-- ");
265 } else {
266 sprintf(&msgbuf[6], " %02d:%02d ", h, m);
267 }
268 }
269 strcpy(&msgbuf[mesg_start_tbl[schedule_foldtype][0]], msg);
270 return (tm);
271 }
272
273 /*
274 * �������塼���ɽ������
275 */
276 static
schedule_listup(int diffday,int tm)277 void schedule_listup(int diffday, int tm)
278 {
279 int sortorder_no;
280 int i;
281
282 sortorder_no = 0; /* ���� */
283 if (diffday < 0) {
284 sortorder_no = 1; /* ���� */
285 } else if (diffday > 0) {
286 sortorder_no = 2; /* ���� */
287 }
288 for (i = 0; i < MAXSORTITEM; i++) {
289 if (schedule_sortorder_tbl[i] == sortorder_no) {
290 break;
291 }
292 }
293 if (i >= MAXSORTITEM) {
294 return ;
295 }
296
297 if (schedule_listup_flag == FALSE) {
298 schedule_listup_flag = TRUE;
299 pager_output_skip();
300 #ifdef MSG_STYLE
301 pager_output("#### ���礦�Υ������塼�� ####");
302 #else
303 pager_output("���� ���礦�Υ������塼�� ����");
304 #endif
305 }
306
307 schedule_listadd(sortorder_no, diffday, tm);
308 }
309
310 /*
311 * �������塼����Ȥ��뤿�ᡢ�ꥹ�ȹ�¤�˳�Ǽ����
312 *
313 * �ꥹ�ȹ�¤��Ǽ��ˡ(�����Ȥ��ʤ��Ȥ������� No.0)
314 * No.0: ����
315 * No.1: ����
316 * No.2: ����
317 */
318 static
schedule_listadd(int sortorder_no,int diffday,int tm)319 void schedule_listadd(int sortorder_no, int diffday, int tm)
320 {
321 if (schedule_sortflag == FALSE) {
322 list_add(0, 0, 0, 0, msgbuf);
323 } else {
324 switch (schedule_sort) {
325 case SORT_UP_ORDER:
326 list_insert(sortorder_no, diffday, tm, 0, msgbuf);
327 break;
328 case SORT_DOWN_ORDER:
329 list_insert(sortorder_no, diffday, -tm, 0, msgbuf);
330 break;
331 case SORT_NO_ORDER:
332 list_add(sortorder_no, diffday, tm, 0, msgbuf);
333 break;
334 }
335 }
336 }
337
338 /*
339 * �������塼���ɽ������(pager �˽��Ϥ���)
340 *
341 * 1�Ԥ˼��ޤ�ʤ��Ȥ��ϡ�ʣ���Ԥ�ʬ�䤷��ɽ��
342 * �ޤ���ʸ�Ϥζ�§������Ԥ�
343 */
344 static
schedule_output(const char * msg,...)345 void schedule_output(const char *msg, ...)
346 {
347 int second_start;
348
349 second_start = mesg_start_tbl[schedule_foldtype][1];
350 message_fold((const unsigned char *)msg, screen_max_columns - 3, 0, second_start);
351 }
352
353 /*
354 * �������塼���ɽ��������֤����
355 */
356 static
schedule_range(void)357 int schedule_range(void)
358 {
359 int base_day;
360 int limit_day;
361 int n;
362
363 base_day = calendar.day + monthtbl[CENTER_MONTH].offset_day - 1;
364 limit_day = base_day;
365 n = schedule_limit;
366
367 if (n < 0) {
368 return (-n);
369 }
370
371 while (--n >= 0) {
372 limit_day++;
373 if ((holiday_tbl[limit_day] & (SET_SUNID | SET_SATID | SET_HOLID | SET_OVRID)) == 0) {
374 break; /* ʿ�� */
375 }
376 }
377
378 return (limit_day - base_day);
379 }
380
381 #else /* INCLUDE_CALENDAR */
382
383 /*
384 * calendar.c, calfw.c �� �������塼��롼����
385 */
386
387 /*
388 * �ե����뤫�饹�����塼���/��Ф���schedule_daytbl �����ꤹ��
389 *
390 * return value:
391 * TRUE ���ェλ
392 * FALSE ���顼ȯ��(�ե����륪���ץ��)
393 *
394 * file format:
395 * year/month/day [*comment] message
396 */
397 static
schedule_find_sub(int index,const char * infile)398 int schedule_find_sub(int index, const char *infile)
399 {
400 char *bp;
401 char *lasts;
402 struct DATE_T date;
403 int pyear, pmonth, pmaxday;
404 int last_dayofweek;
405 int i;
406 div_t c;
407
408 pyear = caltbl[index].year;
409 pmonth = caltbl[index].month;
410 pmaxday = caltbl[index].dayofmonth;
411 last_dayofweek = GetDayofWeek(pyear, pmonth, pmaxday);
412
413 if (openfile(make_filename2(infile, pyear, pmonth, 0))) {
414 return (FALSE);
415 }
416
417 while ((bp = getfile()) != NULL) {
418 lasts = NULL;
419 bp = strtok_r(bp, fmt_sep3, &lasts);
420 if (bp == NULL ||
421 read_date(0x0177, bp, &date, NULL) == DATE_NG) {
422 continue;
423 }
424
425 bp = strtok_r(NULL, fmt_sep4, &lasts);
426 if (bp == NULL) { /* ���դ����ιԤ�̵�� */
427 continue;
428 }
429
430 if (date.year != 0 && pyear != date.year) {
431 continue;
432 }
433 if (date.month != 0 && pmonth != date.month) {
434 continue;
435 }
436
437 if (date.day == 0) {
438 for (i = 0; i < pmaxday; i++) {
439 schedule_daytbl[index][i] = SCHEDULE_EXIST;
440 }
441 } else {
442 if (date.day < 0) { /* ��������,�������� */
443 date.day = -date.day;
444 if (date.day < 100) {
445 date.day = pmaxday - (date.day - 1);
446 } else {
447 c = div(date.day - 100, 10);
448 date.day = ((c.rem - 1) - caltbl[index].first_dayofweek) + 1;
449 if (date.day < 1) {
450 date.day += 7;
451 }
452 if (c.quot > 5) { /* ��-n���� */
453 date.day = (c.rem - 1) - last_dayofweek;
454 if (date.day > 0) {
455 date.day -= 7;
456 }
457 date.day += pmaxday - (c.quot - 6) * 7;
458 } else if (c.quot > 0) { /* ��n���� */
459 date.day += (c.quot - 1) * 7;
460 } else {
461 while (date.day <= pmaxday) {
462 schedule_daytbl[index][date.day - 1] = SCHEDULE_EXIST;
463 date.day += 7;
464 }
465 continue;
466 }
467 }
468 }
469 if (date.day > 0 && date.day <= pmaxday) {
470 schedule_daytbl[index][date.day - 1] = SCHEDULE_EXIST;
471 }
472 }
473 }
474
475 closefile();
476
477 return (TRUE);
478 }
479
480 /*
481 * �������塼���/��Ф���schedule_daytbl �����ꤹ��
482 */
schedule_find(void)483 void schedule_find(void)
484 {
485 int i, j;
486
487 memset(schedule_daytbl, (char)SCHEDULE_NONE, sizeof(schedule_daytbl));
488
489 for (i = 0; i < MAXSCHEDULEFILE; i++) {
490 if (schedule_filetbl[i] != NULL) {
491 for (j = 0; j < MAXMONTH_SCHEDULE; j++) {
492 if (schedule_find_sub(j, schedule_filetbl[i]) == FALSE &&
493 (mkfile_status & (SET_MKF_CC | SET_MKF_YY | SET_MKF_MM)) == 0) {
494 break;
495 }
496 }
497 }
498 }
499 }
500
501 #if defined(_T_WINDOWS)
502 /*
503 * used calfw.c
504 *
505 * �ե����뤫�饹�����塼�����Ф���å������ơ��֥����
506 */
507 static
schedule_loadmsg_sub(const char * infile,int year,int month,int day,int * msgcount,char ** msgtbl)508 char **schedule_loadmsg_sub(const char *infile, int year, int month, int day, int *msgcount, char **msgtbl)
509 {
510 char *bp;
511 char *lasts;
512 char *comment, *msg;
513 struct DATE_T sdate;
514 int pmaxday;
515 int first_dayofweek;
516 int last_dayofweek;
517 div_t c;
518 char *msgbuf;
519
520 if (openfile(make_filename2(infile, year, month, 0))) {
521 return (msgtbl);
522 }
523
524 pmaxday = GetDayofMonth(year, month);
525 first_dayofweek = GetDayofWeek(year, month, 1);
526 last_dayofweek = GetDayofWeek(year, month, pmaxday);
527
528 while ((bp = getfile()) != NULL) {
529 lasts = NULL;
530 bp = strtok_r(bp, fmt_sep3, &lasts);
531 if (bp == NULL ||
532 read_date(0x0177, bp, &sdate, NULL) == DATE_NG) {
533 continue;
534 }
535
536 bp = strtok_r(NULL, fmt_sep4, &lasts);
537 if (bp == NULL) { /* ���դ����ιԤ�̵�� */
538 continue;
539 }
540
541 if (sdate.year != 0 && sdate.year != year) {
542 continue;
543 }
544 if (sdate.month != 0 && sdate.month != month) {
545 continue;
546 }
547 if (sdate.day < 0) { /* �������� */
548 sdate.day = -sdate.day;
549 if (sdate.day < 100) {
550 sdate.day = pmaxday - (sdate.day - 1);
551 } else {
552 c = div(sdate.day - 100, 10);
553 sdate.day = ((c.rem - 1) - first_dayofweek) + 1;
554 if (sdate.day < 1) {
555 sdate.day += 7;
556 }
557 if (c.quot > 5) { /* ��-n���� */
558 sdate.day = (c.rem - 1) - last_dayofweek;
559 if (sdate.day > 0) {
560 sdate.day -= 7;
561 }
562 sdate.day += pmaxday - (c.quot - 6) * 7;
563 } else if (c.quot > 0) { /* ��n���� */
564 sdate.day += (c.quot - 1) * 7;
565 } else {
566 while (sdate.day <= MAX_DAYOFMONTH) {
567 if (sdate.day == day) {
568 break;
569 }
570 sdate.day += 7;
571 }
572 }
573 }
574 }
575 if (sdate.day != 0 && sdate.day != day) {
576 continue;
577 }
578
579 if (*bp == '*') {
580 comment = xstrescape(undertospace(strtok_r(bp, fmt_sep3, &lasts) + 1));
581 bp = strtok_r(NULL, fmt_sep4, &lasts);
582 if (bp == NULL) { /* �����Ȥ����ιԤ�̵�� */
583 continue;
584 }
585 } else {
586 comment = " --:-- ";
587 }
588 msg = xstrescape(strip(bp));
589
590 msgbuf = XMALLOC(12 + 1 + strlen(msg) + 1);
591 sprintf(msgbuf, "%-12.12s %s", comment, msg);
592
593 msgtbl = realloc(msgtbl, sizeof(char *) * (*msgcount + 1));
594 if (msgtbl == NULL) {
595 memerr("schedule_loadmsg_sub");
596 }
597 msgtbl[*msgcount] = msgbuf;
598 (*msgcount)++;
599 }
600
601 closefile();
602
603 return (msgtbl);
604 }
605
606 /*
607 * �������դΥ������塼����ɼ�ꡢ��å������ơ��֥�(msgtbl)���������
608 *
609 * return value:
610 * NULL �������塼��ʤ�
611 */
schedule_loadmsg(int year,int month,int day,int * count)612 char **schedule_loadmsg(int year, int month, int day, int *count)
613 {
614 int i;
615 int msgcount;
616 char **msgtbl;
617
618 msgcount = 0;
619 msgtbl = NULL;
620
621 for (i = 0; i < MAXSCHEDULEFILE; i++) {
622 if (schedule_filetbl[i] != NULL) {
623 msgtbl = schedule_loadmsg_sub(schedule_filetbl[i], year, month, day, &msgcount, msgtbl);
624 }
625 }
626
627 *count = msgcount;
628 return (msgtbl);
629 }
630 #endif /* _T_WINDOWS */
631 #endif /* INCLUDE_CALENDAR */
632