1 /*
2  * event.c -- event manage
3  *
4  * Copyright (C) 1989,1997,1999,2001,2003 by Yoshifumi Mori
5  *
6  * tab:4
7  */
8 
9 #include "cdefs.h"
10 #include "extern.h"
11 
12 #define total_weekofyear	53		/* ǯ��53�� */
13 #define PARAM_COUNT			32		/* �ȡ��������ʬ��� */
14 #define SET_DAY				'\xFF'
15 #define CLEAR_DAY			'\0'
16 #define MAXHIT				8
17 #define MAXFLAG				64
18 
19 #define WEEK(x)	(((x) - 1) / 7 + 1)
20 #define LVAR(x)	event_level_var[(x)-'a']
21 
22 #define EV_YEAR_ERR			0
23 #define EV_YEAR_YEAR		1
24 #define EV_YEAR_DATE		2
25 
26 struct DATE_MD {
27 	int	month;
28 	int	day;
29 };
30 
31 char	*event_filetbl[MAXEVENTFILE];
32 char	*week_filetbl[MAXWEEKFILE];
33 char	*event_sortorder;
34 int		event_notice_range = NOTICE_DEFAULT_RANGE;
35 int		event_notice_flag = NOTICE_MARK_ONLY;
36 int		event_range_flag = TRUE;
37 char	*event_level_str;
38 
39 static char	pbuff[PARAM_COUNT * 8];
40 static char	*param[PARAM_COUNT];
41 static struct SRANGE_T	rangetbl[PARAM_COUNT];
42 
43 static int	event_sortflag;
44 static int	event_sortorder_tbl[MAXSORTITEM];	/* ����_����_���� */
45 static int	message_counter;
46 static int	event_msg_level_default;
47 static int	event_msg_level;
48 static char	event_level_var[MAXLVAR];
49 
50 static int	endofmonth;
51 static int	endofyear;
52 static int	start_dayofyear, end_dayofyear;
53 static int	start_weekofyear, end_weekofyear;
54 static int	start_dayofweek, end_dayofweek;
55 static long	start_julian, end_julian;
56 
57 static int	current_year;
58 static int	current_month;
59 static int	current_day;
60 static int	current_leap;
61 static int	current_offsetday;
62 static int	current_mode;
63 static int	current_weekcount;
64 
65 static int	focus_flag;
66 
67 enum {
68 	EVENT_MODE,
69 	LC_EVENT_MODE,
70 };
71 
72 static int	dayshift_direction;
73 static int	dayshift_skip_saturday;
74 
75 static char	pinpoint_daytbl[MAX_DAYOFMONTH], pinpoint_masktbl[MAX_DAYOFMONTH];
76 static int	pinpoint_hittbl[MAXHIT];
77 
78 static unsigned char	evflag[(MAXFLAG + 7) / 8];
79 
80 static void setup_event_level(void);
81 static void event_out(const char *msg, ...);
82 static void event_main(void);
83 static void setup_eventmode(int index);
84 static void setup_lc_eventmode(int index);
85 static void call_eventsearch(void);
86 static int eventSearch(const char *filename);
87 static void ctrl_msg_proc(char *bp);
88 static int analysis_ev_day(char *bp);
89 static int analysis_ev_whatday(char *bp);
90 static int analysis_ev_week(char *bp);
91 static int analysis_ev_month(char *bp);
92 static int analysis_ev_year(char *bp);
93 static int analysis_year_date(const char *p, int *year, long *jul);
94 static int pickup_event(int notice_range);
95 static int pickup_lc_event(int notice_range);
96 static void pinpoint_dayclear(void);
97 static void pinpoint_maskclear(void);
98 static int pinpoint_day(void);
99 
100 static void event_week(void);
101 static int weekSearch(const char *filename);
102 static int check_week(struct DATE_MD *begin, struct DATE_MD *end);
103 
104 static void output_eventlist(int type, char *msg, int diffday, int rangeflag);
105 
106 static int skipHoliday(int day);
107 static void makerange(char *msg);
108 
109 /*
110  * ���٥�Ȥ�ɽ��
111  *
112  * �ƥե�������˽�������
113  */
event(void)114 void event(void)
115 {
116 	unsigned int	hol_attr;
117 	char	*hol_name;
118 
119 	event_sortflag = TRUE;
120 	event_sortorder_tbl[0] = 0;
121 	event_sortorder_tbl[1] = 1;
122 	event_sortorder_tbl[2] = 2;
123 	message_counter = 0;
124 
125 	if (event_notice_range < 0 || event_notice_range > MAX_DAYOFMONTH) {
126 		event_notice_range = NOTICE_DEFAULT_RANGE;
127 		errprint("event", ERR_WARN, "event_notice_range error, default %d set", event_notice_range);
128 	}
129 
130 	event_sortflag = analysis_sortorder("event", event_sortorder, event_sortorder_tbl, event_sortflag);
131 
132 	setup_event_level();
133 
134 	list_init();
135 
136 	hol_attr = holiday_tbl[calendar.day + monthtbl[CENTER_MONTH].offset_day - 1];
137 	if ((hol_attr & SET_HOLID) == SET_HOLID) {
138 		hol_name = GetHolidayName(GET_HOLNAMEI(hol_attr));
139 		if (hol_name != NULL) {
140 			event_msg_level = LVAR('a');
141 			event_out(hol_name);
142 			free(hol_name);
143 		}
144 	}
145 
146 	event_msg_level = LVAR('b');
147 	memset(evflag, '\0', sizeof(evflag));
148 	rekichu(evflag, event_out);
149 
150 	event_main();
151 	event_week();
152 
153 	output_eventlist(0, NULL, 0, FALSE);
154 	list_free();
155 }
156 
157 /*
158  * ��٥��ѿ�������
159  */
160 static
setup_event_level(void)161 void setup_event_level(void)
162 {
163 	char	*p;
164 	int		i, n;
165 
166 	memset(event_level_var, 99, sizeof(event_level_var));
167 	if (event_level_str != NULL) {
168 		p = event_level_str;
169 		i = 0;
170 		while (*p != '\0' && i < MAXLVAR) {
171 			if (sscanf(p, "%02d", &n) != 1) {
172 				break;
173 			}
174 			event_level_var[i++] = (char)n;
175 			p += 2;
176 		}
177 	}
178 }
179 
180 /*
181  * ���٥�ȥ�å�����ɽ�������θƤӽФ�
182  */
183 static
event_out(const char * msg,...)184 void event_out(const char *msg, ...)
185 {
186 	char	msgtmp[64];
187 	va_list	ap;
188 
189 	va_start(ap, msg);
190 	vsprintf(msgtmp, msg, ap);
191 	va_end(ap);
192 	output_eventlist(1, msgtmp, 0, FALSE);
193 }
194 
195 /*
196  * ����3����ʬ�Υ��٥�Ƚ�����ư(�ᥤ��)
197  */
198 static
event_main(void)199 void event_main(void)
200 {
201 	int	i;
202 
203 	for (i = 0; i < MAX_MONTH_TBL; i++) {
204 		focus_flag = (i == CENTER_MONTH) ? TRUE : FALSE;
205 
206 		setup_eventmode(i);
207 		call_eventsearch();
208 		if (calendar.lc_valid == TRUE && calendar.lc_tbl == TRUE) {
209 			setup_lc_eventmode(i);
210 			call_eventsearch();
211 		}
212 	}
213 }
214 
215 /*
216  * ���٥�ȸ���/����ѥǡ����ν����
217  */
218 static
setup_eventmode(int index)219 void setup_eventmode(int index)
220 {
221 	endofyear = GetDayofYear(calendar.year, 12, 31);
222 	endofmonth = monthtbl[index].dayofmonth;
223 
224 	start_dayofyear = GetDayofYear(monthtbl[index].year, monthtbl[index].month, 1);
225 	end_dayofyear = GetDayofYear(monthtbl[index].year, monthtbl[index].month, monthtbl[index].dayofmonth);
226 
227 	start_weekofyear = WEEK(start_dayofyear);
228 	end_weekofyear = WEEK(end_dayofyear);
229 
230 	start_dayofweek = monthtbl[index].first_dayofweek;
231 	end_dayofweek = monthtbl[index].last_dayofweek;
232 
233 	start_julian = Julian(monthtbl[index].year, monthtbl[index].month, 1);
234 	end_julian = Julian(monthtbl[index].year, monthtbl[index].month, monthtbl[index].dayofmonth);
235 
236 	current_year = monthtbl[index].year;
237 	current_month = monthtbl[index].month;
238 	current_day = calendar.day;
239 	current_leap = monthtbl[index].leap;
240 	current_offsetday = monthtbl[index].offset_day;
241 	current_mode = EVENT_MODE;
242 	current_weekcount = 7;
243 }
244 
245 /*
246  * �����٥�ȸ���/����ѥǡ����ν����
247  */
248 static
setup_lc_eventmode(int index)249 void setup_lc_eventmode(int index)
250 {
251 	endofyear = 0;
252 	endofmonth = monthtbl[index].lc.dayofmonth;
253 
254 	start_dayofyear = 0;
255 	end_dayofyear = 0;
256 
257 	start_weekofyear = 0;
258 	end_weekofyear = 0;
259 
260 	start_dayofweek = monthtbl[index].lc.first_dayofweek;
261 	end_dayofweek = monthtbl[index].lc.last_dayofweek;
262 
263 	start_julian = 0L;
264 	end_julian = 0L;
265 
266 	current_year = monthtbl[index].lc.year;
267 	current_month = monthtbl[index].lc.month;
268 	current_day = calendar.lc_day;
269 	current_leap = monthtbl[index].lc.leap;
270 	current_offsetday = monthtbl[index].lc.offset_day;
271 	current_mode = LC_EVENT_MODE;
272 	current_weekcount = 6;
273 }
274 
275 /*
276  * �ƥ��٥����Ͽ�ե�������������
277  */
278 static
call_eventsearch(void)279 void call_eventsearch(void)
280 {
281 	int	i;
282 	const char	*filename;
283 
284 	event_msg_level_default = LVAR('i');
285 	for (i = 0; i < MAXEVENTFILE; i++) {
286 		if (event_filetbl[i] != NULL) {
287 			filename = make_filename2(event_filetbl[i], current_year, current_month, current_day);
288 			eventSearch(filename);
289 		}
290 	}
291 }
292 
293 /*
294  * �ե����뤫�饤�٥�Ȥ���/��Ф���
295  *
296  * return value:
297  *   TRUE  ���ェλ
298  *   FALSE ���顼ȯ��(�ե����륪���ץ��)
299  *
300  * file format:
301  *   [+n] [<>|&]day whatday week month [year] message
302  */
303 static
eventSearch(const char * infile)304 int eventSearch(const char *infile)
305 {
306 	char	*bp;
307 	char	*lasts;
308 
309 	if (openfile(infile)) {
310 		return (FALSE);
311 	}
312 
313 	event_msg_level = event_msg_level_default;
314 
315 	while ((bp = getfile()) != NULL) {
316 		char	*eventmessage;
317 		int		flag_day, flag_whatday, flag_week;
318 		int		notice_range;
319 		int		notice_force_range;
320 		int		rangeflag;
321 		int		hitcnt;
322 		int		i;
323 		int		diffday;
324 
325 		if (*bp == '$') {
326 			ctrl_msg_proc(bp);
327 			continue;
328 		}
329 
330 		notice_range = 0;	/* notice off */
331 		notice_force_range = FALSE;
332 		if (*bp == '+') {
333 			lasts = NULL;
334 			bp = strtok_r(bp, fmt_sep3, &lasts);
335 			if (bp == NULL) {
336 				continue;
337 			}
338 			bp++;	/* skip '+' */
339 			notice_range = event_notice_range;
340 			if (isdigit((unsigned char)*bp) != 0) {
341 				notice_range = (int)strtol(bp, &bp, 10);
342 				notice_force_range = TRUE;
343 			}
344 			bp = NULL;
345 		}
346 
347 		if (event_notice_flag == NOTICE_NO) {
348 			notice_range = 0;	/* notice off */
349 		} else if (event_notice_flag == NOTICE_ALL) {
350 			if (notice_range == 0 && notice_force_range == FALSE) {
351 				notice_range = event_notice_range;
352 			}
353 		}
354 
355 		bp = strtok_r(bp, fmt_sep3, &lasts);
356 		if (bp == NULL) {
357 			continue;
358 		}
359 
360 		dayshift_direction = 0;
361 		dayshift_skip_saturday = FALSE;
362 		switch (*bp) {
363 		case '&':	/* ������� */
364 			if (current_mode == EVENT_MODE) {
365 				continue;
366 			}
367 			if (notice_range == 0 && focus_flag == FALSE) {
368 				continue;
369 			}
370 			bp++;
371 			break;
372 		case '<':
373 			dayshift_direction = -1;
374 			goto dayshift_check;
375 		case '>':
376 			dayshift_direction = 1;
377 dayshift_check:
378 			if (current_mode == LC_EVENT_MODE) {
379 				continue;
380 			}
381 			bp++;
382 			if (bp[0] == bp[-1]) {
383 				dayshift_skip_saturday = TRUE;
384 				bp++;
385 			}
386 			break;
387 		default:
388 			if (current_mode == LC_EVENT_MODE) {
389 				continue;
390 			}
391 			if (notice_range == 0 && focus_flag == FALSE) {
392 				continue;
393 			}
394 			break;
395 		}
396 
397 		pinpoint_dayclear();
398 
399 		flag_day = analysis_ev_day(bp);
400 
401 		bp = strtok_r(NULL, fmt_sep3, &lasts);
402 		if (bp == NULL) {
403 			continue;
404 		}
405 		flag_whatday = analysis_ev_whatday(bp);
406 
407 		bp = strtok_r(NULL, fmt_sep3, &lasts);
408 		if (bp == NULL) {
409 			continue;
410 		}
411 		flag_week = analysis_ev_week(bp);
412 
413 		if (flag_day == FALSE && flag_whatday == FALSE && flag_week == FALSE) {
414 			continue;
415 		}
416 
417 		bp = strtok_r(NULL, fmt_sep3, &lasts);
418 		if (bp == NULL) {
419 			continue;
420 		}
421 		if (analysis_ev_month(bp) == FALSE) {
422 			continue;
423 		}
424 
425 		bp = strtok_r(NULL, fmt_sep3, &lasts);
426 		if (bp == NULL) {
427 			continue;
428 		}
429 		if (analysis_ev_year(bp) == FALSE) {
430 			continue;
431 		}
432 
433 		bp = strtok_r(NULL, fmt_sep4, &lasts);
434 		if (bp == NULL) {
435 			continue;
436 		}
437 		eventmessage = strip(bp);
438 
439 		rangeflag = FALSE;
440 		if (flag_day == TRUE && flag_whatday == FALSE && flag_week == FALSE &&
441 		    rangetbl[0].start != 0) {
442 			rangeflag = TRUE;
443 		}
444 
445 		if (current_mode == EVENT_MODE) {
446 			hitcnt = pickup_event(notice_range);
447 		} else {
448 			hitcnt = pickup_lc_event(notice_range);
449 		}
450 		for (i = 0; i < hitcnt; i++) {
451 			diffday = pinpoint_hittbl[i];
452 			if (diffday == 0) {
453 				output_eventlist(1, eventmessage, 0, rangeflag);
454 			} else {
455 				output_eventlist(3, eventmessage, diffday, rangeflag);
456 			}
457 		}
458 	}
459 
460 	closefile();
461 
462 	return (TRUE);
463 }
464 
465 /*
466  * ��å���������ȥ������
467  *
468  * ${ctrl}
469  *
470  * ctrl: Lnn   ��å�������٥� 0-99
471  *       Lx    ��å�������٥��ѿ� a-z, A-Z
472  *       L@,L  ��å�������٥�ꥻ�å�
473  */
474 static
ctrl_msg_proc(char * bp)475 void ctrl_msg_proc(char *bp)
476 {
477 	char	*ep;
478 
479 	bp++;
480 	while (*bp != '\0') {
481 		switch (*bp) {
482 		case 'L':
483 			bp++;
484 			if (isdigit(*bp) != 0) {
485 				event_msg_level = strtol(bp, &ep, 10);
486 				bp = ep;
487 			} else if (isalpha(*bp) != 0) {
488 				event_msg_level = LVAR(tolower(*bp));
489 				bp++;
490 			} else if (*bp == '@' || *bp == '\0') {
491 				event_msg_level = event_msg_level_default;
492 			}
493 			break;
494 		default:
495 			bp++;
496 			break;
497 		}
498 	}
499 }
500 
501 /*
502  * ���դβ���(�����б�)
503  *
504  * ������� !nn �ϻ��ѤǤ��ʤ�
505  * %n ��ͽ��������ˤ���ư���Ǥ��ʤ�
506  *
507  * return value:
508  *   TRUE  pinpoint_daytbl[] ����
509  *   FALSE ̤���� '0' �����ꤵ�줿���ᡢ����̵��
510  */
511 static
analysis_ev_day(char * bp)512 int analysis_ev_day(char *bp)
513 {
514 	int	change_masktbl = FALSE;
515 	int	pcnt;
516 	int	pc;
517 
518 	pcnt = separate_param(bp, pbuff, param, PARAM_COUNT, rangetbl);
519 	pinpoint_maskclear();
520 
521 	for (pc = 0; pc < pcnt; pc++) {
522 		const char	*pp;
523 		int	pday;
524 		int	pf;
525 
526 		pp = param[pc];
527 		if (*pp == '%') {	/* �ü����� */
528 			pf = atoi(pp + 1);
529 			if (pf < 1 || pf > MAXFLAG) {
530 				continue;
531 			}
532 			pf--;
533 			if (focus_flag == TRUE && CHKBIT(pf, evflag) != 0) {
534 				pday = calendar.day;
535 			} else {
536 				continue;
537 			}
538 		} else if (*pp == '!') {	/* ǯƬ������̻��� */
539 			pday = atoi(pp + 1);
540 			if (pday < 0) {
541 				pday += endofyear + 1;
542 			}
543 			if (pday < start_dayofyear || pday > end_dayofyear) {
544 				continue;
545 			}
546 			pday -= start_dayofyear - 1;
547 		} else {	/* ���̤��� */
548 			pday = atoi(pp);
549 			if (pday < 0) {
550 				pday += endofmonth + 1;
551 			}
552 		}
553 		if (pday > 0 && pday <= endofmonth) {
554 			pinpoint_masktbl[pday - 1] = SET_DAY;
555 			change_masktbl = TRUE;
556 		}
557 	}
558 
559 	if (change_masktbl == FALSE) {
560 		return (FALSE);
561 	}
562 	return (pinpoint_day());
563 }
564 
565 /*
566  * �����β���(�����б�)
567  *
568  * return value:
569  *   TRUE  pinpoint_daytbl[] ����
570  *   FALSE ̤���� '0' �����ꤵ�줿���ᡢ������̵��
571  */
572 static
analysis_ev_whatday(char * bp)573 int analysis_ev_whatday(char *bp)
574 {
575 	int	change_masktbl = FALSE;
576 	int	pcnt;
577 	int	pc;
578 
579 	pcnt = separate_param(bp, pbuff, param, PARAM_COUNT, NULL);
580 	pinpoint_maskclear();
581 
582 	for (pc = 0; pc < pcnt; pc++) {
583 		const char	*pp;
584 		int			pwhatday;
585 
586 		pp = param[pc];
587 		pwhatday = atoi(pp);
588 		if (pwhatday != 0) {
589 			int	i;
590 
591 			i = pwhatday - (start_dayofweek + 1) + 1;
592 			if (i < 1) {
593 				i += current_weekcount;
594 			}
595 			while (i > 0 && i <= endofmonth) {
596 				pinpoint_masktbl[i - 1] = SET_DAY;
597 				i += current_weekcount;
598 				change_masktbl = TRUE;
599 			}
600 		}
601 	}
602 
603 	if (change_masktbl == FALSE) {
604 		return (FALSE);
605 	}
606 	return (pinpoint_day());
607 }
608 
609 /*
610  * ���β���(�����б�)
611  *
612  * ������ϡ� !nn, %nn, .nn �ϻ��ѤǤ��ʤ�
613  *
614  * return value:
615  *   TRUE  pinpoint_daytbl[] ����
616  *   FALSE ̤���� '0' �����ꤵ�줿���ᡢ����̵��
617  */
618 static
analysis_ev_week(char * bp)619 int analysis_ev_week(char *bp)
620 {
621 	int	change_masktbl = FALSE;
622 	int	pcnt;
623 	int	pc;
624 
625 	pcnt = separate_param(bp, pbuff, param, PARAM_COUNT, NULL);
626 	pinpoint_maskclear();
627 
628 	for (pc = 0; pc < pcnt; pc++) {
629 		const char	*pp;
630 		int			pweek;
631 		int			previously_change_masktbl = FALSE;
632 		int			start_day_range = 0;
633 
634 		pp = param[pc];
635 		if (*pp == '!') {	/* ǯƬ������̻��� */
636 			pweek = atoi(pp + 1);
637 			if (pweek < 0) {
638 				pweek += total_weekofyear + 1;
639 			}
640 			if (pweek < start_weekofyear || pweek > end_weekofyear) {
641 				continue;
642 			}
643 			start_day_range = (pweek - 1) * current_weekcount + 1 - start_dayofyear + 1;
644 		} else if (*pp == '%') {	/* �ֽ� */
645 			pweek = atoi(pp + 1);
646 			if (pweek != 0) {
647 				int	i;
648 				int	mod_week;
649 
650 				mod_week = pweek % 2;
651 				previously_change_masktbl = TRUE;
652 				for (i = 0; i < MAX_DAYOFMONTH; i++) {
653 					pweek = (start_dayofyear + i - 1) / current_weekcount + 1;
654 					if ((pweek % 2) == mod_week) {
655 						pinpoint_masktbl[i] = SET_DAY;
656 						change_masktbl = TRUE;
657 					}
658 				}
659 			}
660 		} else if (*pp == '.') {	/* ���������β��ν� */
661 			pweek = atoi(pp + 1);
662 			if (pweek == 0) {
663 				;
664 			} else if (pweek < 0) {
665 				start_day_range = endofmonth - end_dayofweek + (pweek - 1) * current_weekcount;
666 			} else {
667 				start_day_range = 1 - start_dayofweek + (pweek - 1) * current_weekcount;
668 			}
669 		} else {	/* ���̤ν� */
670 			pweek = atoi(pp);
671 			if (pweek == 0) {
672 				;
673 			} else if (pweek < 0) {
674 				start_day_range = endofmonth + pweek * current_weekcount + 1;
675 			} else {
676 				start_day_range = 1 + (pweek - 1) * current_weekcount;
677 			}
678 		}
679 
680 		if (pweek != 0 && previously_change_masktbl == FALSE) {
681 			int	i;
682 			int	end_day_range;
683 
684 			end_day_range = start_day_range + current_weekcount;
685 			for (i = start_day_range; i < end_day_range; i++) {
686 				if (i > 0 && i <= endofmonth) {
687 					pinpoint_masktbl[i - 1] = SET_DAY;
688 					change_masktbl = TRUE;
689 				}
690 			}
691 		}
692 	}
693 
694 	if (change_masktbl == FALSE) {
695 		return (FALSE);
696 	}
697 	return (pinpoint_day());
698 }
699 
700 /*
701  * used analysis_ev_month(), analysis_ev_year()
702  */
703 #define MASKBIT(x)	(1 << (x))
704 
705 /*
706  * ��β���(�����б�)
707  *
708  * %1,%2 �� ��,%4,%5 ��Ʊ���˻��ꤷ������ AND �����Ȥʤ�
709  * %1,%2 ��Ʊ���˻��ꤹ��� %0 �������Ȥʤ�
710  * 0,1,2,5 �Ȼ��ꤹ��� 0 ��̵�뤹��
711  *
712  * return value:
713  *   TRUE  �оݷ�
714  *   FALSE ̤�о�
715  */
716 static
analysis_ev_month(char * bp)717 int analysis_ev_month(char *bp)
718 {
719 	int	pcnt;
720 	int	pc;
721 	int	monthmap = 0;	/* ��ͭ���ӥåȥޥå� bit0:1 - bit11:12 */
722 	int	leaptype = 0;	/* bit0:��ǯ/��Ǥʤ�, bit1:��ǯ/�� */
723 
724 	pcnt = separate_param(bp, pbuff, param, PARAM_COUNT, NULL);
725 	for (pc = 0; pc < pcnt; pc++) {
726 		const char	*p;
727 		int			pmon;
728 
729 		p = param[pc];
730 		if (*p == '%') {
731 			pmon = atoi(p + 1);
732 			switch (pmon) {
733 			case 1:	/* %1 ��ǯ/��Ǥʤ� */
734 				leaptype |= 1;
735 				break;
736 			case 2:	/* %2 ��ǯ/�� */
737 				leaptype |= 2;
738 				break;
739 			case 4:	/* %4 ������ */
740 				monthmap |= 0x0AAA;
741 				break;
742 			case 5:	/* %5 ����� */
743 				monthmap |= 0x0555;
744 				break;
745 			}
746 		} else {
747 			pmon = atoi(p);
748 			if (pmon >= 1 && pmon <= 12) {
749 				monthmap |= MASKBIT(pmon - 1);
750 			}
751 		}
752 	}
753 
754 	if (monthmap == 0 || (monthmap & MASKBIT(current_month - 1)) != 0) {
755 		if (leaptype == 0 || leaptype == 3 || (leaptype == (current_leap + 1))) {
756 			return (TRUE);
757 		}
758 	}
759 	return (FALSE);
760 }
761 
762 /*
763  * ǯ(����)�β���(�����б�)
764  *
765  * ���դ���ꤷ�ƴ��֤����Ǥ���
766  * ����������դϻ��ѤǤ��ʤ�
767  *
768  * %1,%2 �� ǯ,%4,%5 ��Ʊ���˻��ꤷ������ AND �����Ȥʤ�
769  * %1,%2 ��Ʊ���˻��ꤹ��ȱ�ǯɾ���Ϥ��ʤ�
770  * %4,%5 ��Ʊ���˻��ꤹ��ȴ����ɾ���Ϥ��ʤ�
771  * 0,1995,1997 �Ȼ��ꤹ��� 0 ��̵�뤹��
772  *
773  * return value:
774  *   TRUE  �о�ǯ(����)
775  *   FALSE ̤�о�
776  */
777 static
analysis_ev_year(char * bp)778 int analysis_ev_year(char *bp)
779 {
780 	int	change_masktbl = FALSE;
781 	int	pcnt;
782 	int	pc;
783 	int	leaptype = 0;	/* bit0:��ǯ�Ǥʤ�, bit1:��ǯ */
784 	int	monthtype = 0;	/* bit0:����ǯ, bit1:���ǯ */
785 
786 	pcnt = separate_param2(bp, param, PARAM_COUNT);
787 	pinpoint_maskclear();
788 
789 	for (pc = 0; pc < pcnt; pc++) {
790 		const char	*p;
791 		const char	*q;
792 		int	pyear;
793 		int	pyear2;
794 		long	pjul;
795 		long	pjul2;
796 
797 		p = param[pc];
798 		if (*p == '%') {
799 			pyear = atoi(p + 1);
800 			switch (pyear) {
801 			case 1:	/* %1 ��ǯ�Ǥʤ� */
802 				leaptype |= 1;
803 				break;
804 			case 2:	/* %2 ��ǯ */
805 				leaptype |= 2;
806 				break;
807 			case 4:	/* %4 ����ǯ */
808 				monthtype |= 1;
809 				break;
810 			case 5:	/* %5 ���ǯ */
811 				monthtype |= 2;
812 				break;
813 			}
814 		} else if (*p == '-') {
815 			switch (analysis_year_date(p + 1, &pyear, &pjul)) {
816 			case EV_YEAR_ERR:
817 			default:
818 				continue;
819 			case EV_YEAR_YEAR:	/* -n ����ǯ���� */
820 				pyear2 = pyear;
821 				pyear = INT_MIN;
822 				goto year_check;
823 			case EV_YEAR_DATE:	/* -yy/mm/dd �������հ��� */
824 				pjul2 = pjul;
825 				pjul = LONG_MIN;
826 				goto date_check;
827 			}
828 		} else {
829 			switch (analysis_year_date(p, &pyear, &pjul)) {
830 			case EV_YEAR_ERR:
831 			default:
832 				continue;
833 			case EV_YEAR_YEAR:
834 				q = strchr(p, '-');
835 				if (q == NULL) {	/* n ����ǯ�Τ� */
836 					pyear2 = pyear;
837 				} else if (q[1] == '\0') {	/* n- ����ǯ�ʹ� */
838 					pyear2 = INT_MAX;
839 				} else {	/* n-m �ϰϻ��� */
840 					if (analysis_year(q + 1, &pyear2, NULL) == YEAR_NG) {
841 						continue;
842 					}
843 				}
844 year_check:
845 				if (pyear == 0) {
846 					continue;
847 				}
848 				if (pyear == INT_MIN) {
849 					pjul = LONG_MIN;
850 				} else {
851 					pjul = Julian(pyear, 1, 1);
852 				}
853 				if (pyear2 == INT_MAX) {
854 					pjul2 = LONG_MAX;
855 				} else {
856 					pjul2 = Julian(pyear2, 12, 31);
857 				}
858 				goto date_check;
859 			case EV_YEAR_DATE:
860 				q = strchr(p, '-');
861 				if (q == NULL) {	/* yy/mm/dd �������դΤ� */
862 					pjul2 = pjul;
863 				} else if (q[1] == '\0') {	/* yy/mm/dd- �������հʹ� */
864 					pjul2 = LONG_MAX;
865 				} else {	/* yy/mm/dd-yy/mm/dd �ϰϻ��� */
866 					switch (analysis_year_date(q + 1, &pyear2, &pjul2)) {
867 					case EV_YEAR_ERR:
868 					case EV_YEAR_YEAR:
869 					default:
870 						continue;
871 					case EV_YEAR_DATE:
872 						break;
873 					}
874 				}
875 date_check:
876 				change_masktbl = TRUE;
877 				if (start_julian <= pjul2 && pjul <= end_julian) {
878 					int	js;
879 					int	je;
880 
881 					if (pjul <= start_julian) {
882 						js = 0;
883 					} else {
884 						js = (int)(pjul - start_julian);
885 					}
886 
887 					if (pjul2 > end_julian) {
888 						je = endofmonth - 1;
889 					} else {
890 						je = (int)(pjul2 - start_julian);
891 					}
892 
893 					while (js <= je) {
894 						pinpoint_masktbl[js++] = SET_DAY;
895 					}
896 				}
897 				break;
898 			}
899 		}
900 	}
901 
902 	/* change_masktbl == FALSE ���� 0 �����ꤵ��Ƥ��� */
903 	if (change_masktbl == FALSE || pinpoint_day() != FALSE) {
904 		if (monthtype == 0 || monthtype == 3 ||
905 		    ((monthtype - 1) == (current_year & 1))) {
906 			if (leaptype == 0 || leaptype == 3 ||
907 			    (leaptype == (current_leap + 1))) {
908 				return (TRUE);
909 			}
910 		}
911 	}
912 	return (FALSE);
913 }
914 
915 /*
916  * ǯ(����)�����(����̤�б�)
917  *
918  * return value:
919  *   EV_YEAR_ERR  ��ʸ���顼
920  *   EV_YEAR_YEAR ǯ�Τ߻���
921  *   EV_YEAR_DATE ���ջ���
922  */
923 static
analysis_year_date(const char * p,int * year,long * jul)924 int analysis_year_date(const char *p, int *year, long *jul)
925 {
926 	char	*q;
927 	int	yy;
928 	int	mm;
929 	int	dd;
930 
931 	if (analysis_year(p, &yy, NULL) == YEAR_NG) {
932 		return (EV_YEAR_ERR);
933 	}
934 
935 	/* AD, BC, �����ά���楹���å� */
936 	while (isalpha(*p) != 0) {
937 		p++;
938 	}
939 	/* ����(ǯ)�����å� */
940 	while (isdigit(*p) != 0) {
941 		p++;
942 	}
943 
944 	*year = yy;
945 	if (*p != '/') {
946 		return (EV_YEAR_YEAR);
947 	}
948 
949 	mm = (int)strtol(p + 1, &q, 10);
950 	if (*q != '/') {
951 		return (EV_YEAR_ERR);
952 	}
953 	dd = (int)strtol(q + 1, &q, 10);
954 #if 0
955 	if (current_mode == LC_EVENT_MODE) {
956 		int	leap = 0;
957 		const struct DATE_T	*nowcal;
958 
959 		if (*q == '.') {
960 			leap = 1;
961 		}
962 		nowcal = LunarToNowCalendar(yy, mm, dd, leap);
963 		yy = nowcal->year;
964 		mm = nowcal->month;
965 		dd = nowcal->day;
966 	}
967 #endif
968 	*jul = Julian(yy, mm, dd);
969 
970 	return (EV_YEAR_DATE);
971 }
972 
973 /*
974  * ���٥�Ȥ��о�����õ���Ф�
975  *
976  * return value:
977  *   �оݿ�
978  *
979  * pinpoint_hittbl[n] = diffday - ���٥�ȤޤǤδ���(����1�����)
980  */
981 static
pickup_event(int notice_range)982 int pickup_event(int notice_range)
983 {
984 	int	cday;
985 	int	hitcnt;
986 	int	i;
987 
988 	cday = calendar.day + monthtbl[CENTER_MONTH].offset_day;
989 	hitcnt = 0;
990 
991 	for (i = 0; i < endofmonth; i++) {
992 		int	cmpday;
993 		int	diffdays;
994 
995 		if (pinpoint_daytbl[i] == CLEAR_DAY) {
996 			continue;
997 		}
998 		cmpday = i + current_offsetday + 1;
999 		if (dayshift_direction != 0) {
1000 			cmpday = skipHoliday(cmpday);
1001 		}
1002 		diffdays = cmpday - cday;
1003 		if (diffdays == 0 || (notice_range != 0 && diffdays >= -1 && diffdays <= notice_range)) {
1004 			if (diffdays >= 28) {
1005 				if (diffdays > monthtbl[CENTER_MONTH].dayofmonth) {
1006 					continue;
1007 				}
1008 				if (cmpday == calendar.day) {
1009 					diffdays = NOTICE_MONTH(1);
1010 				}
1011 			}
1012 			pinpoint_hittbl[hitcnt++] = diffdays;
1013 			if (hitcnt >= MAXHIT) {
1014 				break;
1015 			}
1016 		}
1017 	}
1018 
1019 	return (hitcnt);
1020 }
1021 
1022 /*
1023  * ���٥�Ȥ��о�����õ���Ф�(������)
1024  *
1025  * return value:
1026  *   �оݿ�
1027  *
1028  * pinpoint_hittbl[n] = diffday - ���٥�ȤޤǤδ���(����1�����)
1029  */
1030 static
pickup_lc_event(int notice_range)1031 int pickup_lc_event(int notice_range)
1032 {
1033 	int	cday;
1034 	int	hitcnt;
1035 	int	i;
1036 
1037 	cday = calendar.lc_day + monthtbl[CENTER_MONTH].lc.offset_day;
1038 	hitcnt = 0;
1039 
1040 	for (i = 0; i < endofmonth; i++) {
1041 		int	cmpday;
1042 		int	diffdays;
1043 
1044 		if (pinpoint_daytbl[i] == CLEAR_DAY) {
1045 			continue;
1046 		}
1047 		cmpday = i + current_offsetday + 1;
1048 		diffdays = cmpday - cday;
1049 		if (diffdays == 0 || (notice_range != 0 && diffdays >= -1 && diffdays <= notice_range)) {
1050 			if (diffdays >= 28) {	/* ������ɤ������� */
1051 				const struct DATE_T	*date;
1052 				int	cmpyear, cmpmonth, cmpleap;
1053 
1054 				if (diffdays > monthtbl[CENTER_MONTH].dayofmonth) {
1055 					continue;
1056 				}
1057 				cmpday -= monthtbl[CENTER_MONTH].lc.offset_day;
1058 				cmpyear = calendar.lc_year;
1059 				cmpmonth = calendar.lc_month;
1060 				cmpleap = calendar.lc_leap;
1061 				if (cmpday < 1) {
1062 					cmpyear = monthtbl[CENTER_MONTH - 1].lc.year;
1063 					cmpmonth = monthtbl[CENTER_MONTH - 1].lc.month;
1064 					cmpday += monthtbl[CENTER_MONTH - 1].lc.dayofmonth;
1065 					cmpleap = monthtbl[CENTER_MONTH - 1].lc.leap;
1066 				} else if (cmpday > monthtbl[CENTER_MONTH].lc.dayofmonth) {
1067 					cmpyear = monthtbl[CENTER_MONTH + 1].lc.year;
1068 					cmpmonth = monthtbl[CENTER_MONTH + 1].lc.month;
1069 					cmpday -= monthtbl[CENTER_MONTH].lc.dayofmonth;
1070 					cmpleap = monthtbl[CENTER_MONTH + 1].lc.leap;
1071 				}
1072 				date = LunarToNowCalendar(cmpyear, cmpmonth, cmpday, cmpleap);
1073 				if (date == NULL) {
1074 					continue;
1075 				}
1076 				if (date->day == calendar.day) {
1077 					diffdays = NOTICE_MONTH(1);
1078 				}
1079 			}
1080 			pinpoint_hittbl[hitcnt++] = diffdays;
1081 			if (hitcnt >= MAXHIT) {
1082 				break;
1083 			}
1084 		}
1085 	}
1086 
1087 	return (hitcnt);
1088 }
1089 
1090 /*
1091  * ���٥���о��������٤Υơ��֥����������
1092  */
1093 static
pinpoint_dayclear(void)1094 void pinpoint_dayclear(void)
1095 {
1096 	memset(pinpoint_daytbl, SET_DAY, sizeof(pinpoint_daytbl));
1097 }
1098 
1099 /*
1100  * ���٥���о�����ʤ���ि��Υޥ����ơ��֥����������
1101  */
1102 static
pinpoint_maskclear(void)1103 void pinpoint_maskclear(void)
1104 {
1105 	memset(pinpoint_masktbl, CLEAR_DAY, sizeof(pinpoint_masktbl));
1106 }
1107 
1108 /*
1109  * ���٥���о�����ʤ���� (and)
1110  *
1111  * return:
1112  *   FALSE: �оݥ��٥��̵��
1113  *   TRUE : �оݥ��٥�Ȥ���
1114  */
1115 static
pinpoint_day(void)1116 int pinpoint_day(void)
1117 {
1118 	int	i;
1119 	int	flag = 0;
1120 
1121 	for (i = 0; i < MAX_DAYOFMONTH; i++) {
1122 		pinpoint_daytbl[i] &= pinpoint_masktbl[i];
1123 		flag |= pinpoint_daytbl[i];
1124 	}
1125 
1126 	return ((flag == 0) ? FALSE : TRUE);
1127 }
1128 
1129 /*
1130  * ���־���ν���
1131  *
1132  * �ƽ�����Ͽ�ե���������
1133  */
1134 static
event_week(void)1135 void event_week(void)
1136 {
1137 	int	i;
1138 	const char	*filename;
1139 
1140 	event_msg_level_default = LVAR('r');
1141 	for (i = 0; i < MAXWEEKFILE; i++) {
1142 		if (week_filetbl[i] != NULL) {
1143 			filename = make_filename(week_filetbl[i]);
1144 			weekSearch(filename);
1145 		}
1146 	}
1147 }
1148 /*
1149  * �ե����뤫�齵�־������/��Ф���
1150  *
1151  * return value:
1152  *   FALSE ���顼ȯ��(�ե����륪���ץ��)
1153  *   TRUE  ���ェλ
1154  *
1155  * file format:
1156  *   month/day month/day message
1157  */
1158 static
weekSearch(const char * infile)1159 int weekSearch(const char *infile)
1160 {
1161 	char	*bp;
1162 	char	*lasts;
1163 	char	*weekmessage;
1164 	struct DATE_MD	begin, end;
1165 
1166 	if (openfile(infile)) {
1167 		return (FALSE);
1168 	}
1169 
1170 	current_mode = EVENT_MODE;	/* makerange */
1171 	event_msg_level = event_msg_level_default;
1172 
1173 	while ((bp = getfile()) != NULL) {
1174 		if (*bp == '$') {
1175 			ctrl_msg_proc(bp);
1176 			continue;
1177 		}
1178 
1179 		lasts = NULL;
1180 		bp = strtok_r(bp, fmt_sep1, &lasts);
1181 		if (bp == NULL) {
1182 			continue;
1183 		}
1184 		begin.month = atoi(bp);
1185 
1186 		bp = strtok_r(NULL, fmt_sep3, &lasts);
1187 		if (bp == NULL) {
1188 			continue;
1189 		}
1190 		begin.day = atoi(bp);
1191 
1192 		bp = strtok_r(NULL, fmt_sep1, &lasts);
1193 		if (bp == NULL) {
1194 			continue;
1195 		}
1196 		end.month = atoi(bp);
1197 
1198 		bp = strtok_r(NULL, fmt_sep3, &lasts);
1199 		if (bp == NULL) {
1200 			continue;
1201 		}
1202 		end.day = atoi(bp);
1203 
1204 		if (begin.month == 0 || begin.day == 0 || end.month == 0 || end.day == 0) {
1205 			continue;
1206 		}
1207 
1208 		weekmessage = strtok_r(NULL, fmt_sep4, &lasts);
1209 		if (weekmessage == NULL) {
1210 			continue;
1211 		}
1212 
1213 		if (check_week(&begin, &end) == FALSE) {
1214 			continue;
1215 		}
1216 
1217 		rangetbl[0].bmonth = begin.month;
1218 		rangetbl[0].start = begin.day;
1219 		rangetbl[0].emonth = end.month;
1220 		rangetbl[0].end = end.day;
1221 		rangetbl[1].bmonth = rangetbl[1].emonth = 0;
1222 		rangetbl[1].start = rangetbl[1].end = 0;
1223 		output_eventlist(2, strip(weekmessage), 0, TRUE);
1224 	}
1225 
1226 	closefile();
1227 
1228 	return (TRUE);
1229 }
1230 
1231 /*
1232  * ���־��������⤫��ǧ����
1233  *
1234  * return value:
1235  *   TRUE  ������
1236  *   FALSE ���ֳ�
1237  */
1238 static
check_week(struct DATE_MD * begin,struct DATE_MD * end)1239 int check_week(struct DATE_MD *begin, struct DATE_MD *end)
1240 {
1241 	long	jd1, jd2;
1242 
1243 	jd1 = Julian(calendar.year, begin->month, begin->day);
1244 	jd2 = Julian(calendar.year, end->month, end->day);
1245 
1246 	if (jd1 > jd2) {
1247 		if (jd1 <= calendar.julian_day) {
1248 			jd2 = Julian(calendar.year + 1, end->month, end->day);
1249 		} else if (jd2 >= calendar.julian_day) {
1250 			jd1 = Julian(calendar.year - 1, begin->month, begin->day);
1251 		}
1252 	}
1253 
1254 	if (jd1 <= calendar.julian_day && calendar.julian_day <= jd2) {
1255 		return (TRUE);
1256 	}
1257 	return (FALSE);
1258 }
1259 
1260 /*
1261  * ���٥�ȥ�å�������ꥹ�ȹ�¤�˳�Ǽ����
1262  * �ꥹ�ȹ�¤�����å�������ڡ����㡼�˽��Ϥ���
1263  *
1264  * type:
1265  *   0: ��å�������ڡ����㡼�˽��Ϥ���
1266  *   1: ���٥�ȥ�å�������ꥹ�ȹ�¤�˳�Ǽ����
1267  *   2: ���־����å�������ꥹ�ȹ�¤�˳�Ǽ����
1268  *   3: ͽ���å�������ꥹ�ȹ�¤�˳�Ǽ����
1269  *
1270  * �ꥹ�ȹ�¤��Ǽ��ˡ(�����Ȥ��ʤ��Ȥ������� No.0)
1271  *   No.0: ����
1272  *   No.1: ����
1273  *   No.2: ����
1274  */
1275 static
output_eventlist(int type,char * msg,int diffday,int rangeflag)1276 void output_eventlist(int type, char *msg, int diffday, int rangeflag)
1277 {
1278 	static const char	*title_message[2] = {
1279 #ifdef MSG_STYLE
1280 		"****** ���礦�ϲ���������? ******",
1281 		"****** ���礦�ϲ������Ǥ⤢��ޤ��� ******"
1282 #else
1283 		"������ ���礦�ϲ��������ʡ� ������",
1284 		"������ ���礦�ϲ������Ǥ⤢��ޤ���. ������"
1285 #endif
1286 	};
1287 	const char	*notice_msg;
1288 	char		*end_msg;
1289 	char		*ep;
1290 	int			sortorder_no;
1291 	int			period = FALSE;
1292 	int			i;
1293 
1294 	switch (type) {
1295 	case 0:	/* messages flush */
1296 		if (event_sortflag == FALSE) {
1297 			list_output(0, pager_output);
1298 		} else {
1299 			for (i = 0; i < MAXSORTITEM; i++) {
1300 				if (event_sortorder_tbl[i] >= 0) {
1301 					list_output(event_sortorder_tbl[i], pager_output);
1302 				}
1303 			}
1304 		}
1305 		if (message_counter > 0) {
1306 #ifdef MSG_STYLE
1307 			pager_output("--- %d�� ---", message_counter);
1308 #else
1309 			pager_output("--- %2d�� ---", message_counter);
1310 #endif
1311 		} else {
1312 			pager_output_skip();
1313 			pager_output("%s", title_message[1]);
1314 		}
1315 		break;
1316 	case 1:	/* event */
1317 	case 2:	/* week */
1318 	case 3:	/* event notice */
1319 		sortorder_no = 0;		/* ���� */
1320 		if (diffday < 0) {
1321 			sortorder_no = 1;	/* ���� */
1322 		} else if (diffday > 0) {
1323 			sortorder_no = 2;	/* ���� */
1324 		}
1325 		for (i = 0; i < MAXSORTITEM; i++) {
1326 			if (event_sortorder_tbl[i] == sortorder_no) {
1327 				break;
1328 			}
1329 		}
1330 		if (i >= MAXSORTITEM) {
1331 			return ;
1332 		}
1333 
1334 		if (message_counter == 0) {
1335 			pager_output_skip();
1336 			pager_output("%s", title_message[0]);
1337 		}
1338 		message_counter++;
1339 		for (; *msg == ' ' || *msg == '\t'; msg++)
1340 			;
1341 		ep = strlastp(msg);
1342 		if (ep[-1] == '.') {
1343 			ep[-1] = '\0';
1344 			period = TRUE;
1345 		}
1346 		(void)xstrescape(msg);
1347 		notice_msg = Notice_Message(msg, diffday, &end_msg);
1348 		if (type != 3) {
1349 			strcpy(msgbuf, msg);
1350 		} else {
1351 			strcpy(msgbuf, notice_msg);
1352 			strcat(msgbuf, msg);
1353 		}
1354 		if (rangeflag == TRUE) {
1355 			makerange(msgbuf);
1356 		}
1357 		if (period == FALSE) {
1358 			strcat(msgbuf, end_msg);
1359 		}
1360 		strcat(msgbuf, MSG_PERIOD);
1361 		if (event_sortflag == FALSE) {
1362 			list_add(0, 0, 0, event_msg_level, msgbuf);
1363 		} else {
1364 			list_insert(sortorder_no, diffday, 0, event_msg_level, msgbuf);
1365 		}
1366 		break;
1367 	}
1368 }
1369 
1370 /*
1371  * ���դΰ�ư
1372  *
1373  * ���դ����ˡ������ξ�硢��������ˤ��餹
1374  * ����ˤ�äƤϡ����������оݤˤ���
1375  *
1376  * ���餹����: dayshift_direction     < 0: ��  > 0: ��
1377  * �������о�: dayshift_skip_saturday == TRUE
1378  *
1379  * return value:
1380  *   ��ư�������(holiday_tbl �ΰ��� + 1)
1381  *   �ơ��֥뤫���줿��� 0 ���֤�
1382  */
1383 static
skipHoliday(int day)1384 int skipHoliday(int day)
1385 {
1386 	day--;	/* day:1-31 �� holiday_tbl ���ϰ� 0-30 ���Ѵ� */
1387 
1388 	while (day >= 0 && day < (MAX_DAYOFMONTH * MAX_MONTH_TBL)) {
1389 		if (holiday_tbl[day] == 0 ||
1390 		    ((holiday_tbl[day] & SET_SATID) != 0 &&
1391 		     (holiday_tbl[day] & SET_HOLID) == 0 && dayshift_skip_saturday == FALSE)) {
1392 			return (day + 1);
1393 		}
1394 		day += dayshift_direction;
1395 	}
1396 
1397 	return (0);
1398 }
1399 
1400 /*
1401  * ���٥�ȴ��֤��դ���
1402  *
1403  * rangetbl[] ����Ѥ��� msgbuff �κǸ�� (mm/dd��mm/dd) ���դ���
1404  * msgbuff �Υ����С��Ϲ�θ���Ƥ��ʤ��Τǡ���ʬ���礭������
1405  */
1406 static
makerange(char * msgbuff)1407 void makerange(char *msgbuff)
1408 {
1409 	char	*lastp;
1410 	int		modify_flag = FALSE;
1411 	int		i;
1412 
1413 	if (event_range_flag == FALSE) {
1414 		return ;
1415 	}
1416 
1417 	lastp = strlastp(msgbuff);
1418 	lastp[0] = '(';
1419 	lastp[1] = '\0';
1420 	if (current_mode == LC_EVENT_MODE) {
1421 		strcat(lastp, "����:");
1422 	}
1423 
1424 	for (i = 0; i < PARAM_COUNT; i++) {
1425 		int	bmonth, emonth;
1426 
1427 		if (rangetbl[i].start == 0) {
1428 			break;
1429 		}
1430 		bmonth = rangetbl[i].bmonth;
1431 		if (bmonth == 0) {
1432 			bmonth = current_month;
1433 		}
1434 		emonth = rangetbl[i].emonth;
1435 		if (emonth == 0) {
1436 			emonth = current_month;
1437 		}
1438 		if (rangetbl[i].start < 0) {
1439 			rangetbl[i].start = endofmonth + rangetbl[i].start + 1;
1440 		}
1441 		if (rangetbl[i].end < 0) {
1442 			rangetbl[i].end = endofmonth + rangetbl[i].end + 1;
1443 		}
1444 
1445 		sprintf(strlastp(msgbuff), "%d/%d��%d/%d,", bmonth, rangetbl[i].start, emonth, rangetbl[i].end);
1446 		modify_flag = TRUE;
1447 	}
1448 
1449 	if (modify_flag == TRUE) {
1450 		lastp = strlastp(msgbuff);
1451 		lastp[-1] = ')';
1452 	} else {
1453 		*lastp = '\0';
1454 	}
1455 }
1456