1 /*
2 * birthday.c -- birthday manage
3 *
4 * Copyright (C) 1989,1997,1999,2000,2003 by Yoshifumi Mori
5 *
6 * tab:4
7 */
8
9 #include "cdefs.h"
10 #include "extern.h"
11
12 /* #define ROUGH_PERIOD_YEAR */
13 /* #define BIRTHDAY_ENDMSG_CUT */
14
15 #define LIST_DEATHDAY_BASE 3 /* 0,1,2 ����������3,4,5 ��̿���ǻ��� */
16
17 struct BDATA {
18 char *name; /* ̾�� */
19 struct DATE_T birth; /* ������ */
20 struct DATE_T death; /* ̿�� */
21 int flags; /* �ե饰 */
22 int age; /* ǯ��/��ǯ */
23 int ayear; /* ��ǯ */
24 int sex; /* ���̡�̤������ */
25 };
26 #define FLAG_BD_BIRTH 001 /* ������ͭ�� */
27 #define FLAG_BD_DEATH 002 /* ̿��ͭ�� */
28 #define FLAG_BD_BIRTH_W 004 /* ���������� */
29 #define FLAG_BD_DEATH_W 010 /* ̿������ */
30
31 #define MASK_SEX 01 /* ���� mask */
32 #define MASK_MARRIED 02 /* �뺧 mask */
33 #define MASK_UNKNOWN 04 /* �������� mask */
34 #define SET_MALE 00 /* ���� */
35 #define SET_FEMALE 01 /* ���� */
36 #define SET_UNMARRIED 00 /* ̤�� */
37 #define SET_MARRIED 02 /* ���� */
38 #define SET_UNKNOWN 04 /* �������� */
39
40 /* birthday_addinfo */
41 #define FLAG_AI_BIRTH 01 /* ���������ɲþ���ɽ�� */
42 #define FLAG_AI_DEATH 02 /* ̿�����ɲþ���ɽ�� */
43 #define FLAG_AI_MASK (FLAG_AI_BIRTH|FLAG_AI_DEATH)
44
45 /* birthday_agelevel */
46 #define FLAG_B_MASK 03
47
48 /* deathday_agelevel */
49 #define FLAG_D_AYEAR 01 /* ��ǯɽ�� */
50 #define FLAG_D_AGE 02 /* ǯ��ɽ�� */
51 #define FLAG_D_MASK (FLAG_D_AYEAR|FLAG_D_AGE)
52
53 enum AGE_DISPMODE {
54 INVISIBLE, /* ǯ����ɽ�� */
55 VISIBLE, /* ǯ��ɽ�� */
56 AGECHECK, /* ǯ���ǧ */
57 };
58
59 enum {
60 DATE_ADDDT_BIRTH, /* ���������ɲþ�������� */
61 DATE_ADDDT_DEATH, /* ̿�����ɲþ�������� */
62 };
63
64 char *birthday_filetbl[MAXBIRTHFILE];
65 char *birthday_sortorder;
66 int birthday_agesort = SORT_DOWN_ORDER;
67 int birthday_addinfo = 0;
68
69 int birthday_agelevel = BIRTHDAY_AGE_NO;
70 int birthday_notice_range = NOTICE_DEFAULT_RANGE;
71 int birthday_notice_flag = NOTICE_ALL;
72 int birthday_flower = FALSE;
73
74 int deathday_flag = TRUE; /* TRUE: ̿����ɽ�� */
75 int deathday_agelevel = 0;
76 int deathday_notice_range = NOTICE_DEFAULT_RANGE;
77 int deathday_notice_flag = NOTICE_NO;
78
79 static int birthday_sortflag;
80 static int birthday_sortorder_tbl[MAXSORTITEM];
81 static int birthday_effect_addinfo;
82
83 static int birthday_title_flag;
84 static int birthday_listup_flag;
85 static int birthday_todayhit_flag;
86 static int birthday_effect_agelevel;
87
88 static int deathday_listup_flag;
89 static int deathday_effect_agelevel;
90
91 static void birthday_main(void);
92 static void birthday_filemain(const char *infile);
93 static int birthday_check_sex(const char *sex, int *flag_sex);
94 static int birthday_check_noticerange(struct DATE_T date, int notice_range, int *diffday, int *age);
95 static int period_year(struct DATE_T start, struct DATE_T end);
96
97 static void birthday_display(int diffday, struct BDATA bdata);
98 static void birthday_listadd(int sortorder_no, int diffday, int age);
99 static void birthday_title(void);
100 static void birthday_listup(void);
101 static void birthday_message(void);
102
103 static void deathday_display(int diffday, struct BDATA bdata);
104 static void deathday_listadd(int sortorder_no, int diffday, int ayear, int age);
105 static void deathday_listup(void);
106
107 static void add_dateinfo(int type, struct DATE_T date, int wflag);
108
109 static void ctrl_msg_proc(char *bp);
110
111 /*
112 * ��������ɽ��
113 *
114 * �ƥե�������˽�������
115 */
birthday(void)116 void birthday(void)
117 {
118 birthday_sortflag = TRUE;
119 birthday_sortorder_tbl[0] = 0;
120 birthday_sortorder_tbl[1] = 1;
121 birthday_sortorder_tbl[2] = 2;
122 birthday_sortflag = analysis_sortorder("birthday", birthday_sortorder, birthday_sortorder_tbl, birthday_sortflag);
123
124 birthday_title_flag = FALSE;
125 birthday_listup_flag = FALSE;
126 birthday_todayhit_flag = FALSE;
127 if (birthday_notice_range < 0 || birthday_notice_range > MAX_DAYOFMONTH) {
128 birthday_notice_range = NOTICE_DEFAULT_RANGE;
129 errprint("birthday", ERR_WARN, "birthday_notice_range error, default %d set", birthday_notice_range);
130 }
131
132 deathday_listup_flag = FALSE;
133 if (deathday_notice_range < 0 || deathday_notice_range > MAX_DAYOFMONTH) {
134 deathday_notice_range = NOTICE_DEFAULT_RANGE;
135 errprint("birthday", ERR_WARN, "deathday_notice_range error, default %d set", deathday_notice_range);
136 }
137
138 list_init();
139
140 birthday_main();
141 birthday_listup();
142 birthday_message();
143
144 deathday_listup();
145
146 list_free();
147 }
148
149 /*
150 * �������ե�������������
151 */
152 static
birthday_main(void)153 void birthday_main(void)
154 {
155 int i;
156 int offs;
157 int mm;
158
159 for (i = 0; i < MAXBIRTHFILE; i++) {
160 if (birthday_filetbl[i] != NULL) {
161 for (offs = -1; offs <= 1; offs++) {
162 mm = calendar.month + offs;
163 if (mm < 1) {
164 mm = 12;
165 } else if (mm > 12) {
166 mm = 1;
167 }
168 birthday_filemain(make_filename2(birthday_filetbl[i], 0, mm, 0));
169 if ((mkfile_status & SET_MKF_MM) == 0) {
170 break;
171 }
172 }
173 }
174 }
175 }
176
177 /*
178 * �ե�����������������������
179 *
180 * file format:
181 * [+n] year/month/day sm name1 name2
182 */
183 static
birthday_filemain(const char * infile)184 void birthday_filemain(const char *infile)
185 {
186 char *bp;
187 char *lasts;
188 char *name[2];
189 char *sex;
190 struct BDATA bdata;
191 int wflag;
192 int notice_range;
193 int notice_force_range;
194 int d_notice_range;
195 int diffday;
196 char *sp;
197
198 if (openfile(infile)) {
199 return ;
200 }
201
202 birthday_effect_addinfo = birthday_addinfo;
203 birthday_effect_agelevel = birthday_agelevel;
204 deathday_effect_agelevel = deathday_agelevel;
205
206 while ((bp = getfile()) != NULL) {
207 if (*bp == '$') {
208 ctrl_msg_proc(bp);
209 continue;
210 }
211
212 lasts = NULL;
213 bp = strtok_r(bp, fmt_sep3, &lasts);
214 if (bp == NULL) {
215 continue;
216 }
217
218 memset(&bdata, 0, sizeof(bdata));
219
220 notice_range = 0; /* notice off */
221 notice_force_range = FALSE;
222 if (*bp == '+') {
223 bp++; /* skip '+' */
224 notice_range = birthday_notice_range;
225 if (isdigit((unsigned char)*bp) != 0) {
226 notice_range = (int)strtol(bp, &bp, 10);
227 notice_force_range = TRUE;
228 }
229 bp = strtok_r(NULL, fmt_sep3, &lasts);
230 }
231
232 if (birthday_notice_flag == NOTICE_NO) {
233 notice_range = 0; /* notice off */
234 } else if (birthday_notice_flag == NOTICE_ALL) {
235 if (notice_range == 0 && notice_force_range == FALSE) {
236 notice_range = birthday_notice_range;
237 }
238 }
239
240 if (bp == NULL ||
241 read_date(0x99, bp, &bdata.birth, &wflag) == DATE_NG) {
242 continue;
243 }
244 if (bdata.birth.month != 0 && bdata.birth.day != 0) {
245 /* 0000/00/00, yyyy/00/00 �λ�����������̵���Τޤ� */
246 bdata.flags |= FLAG_BD_BIRTH;
247 }
248 if (wflag != FALSE) {
249 bdata.flags |= FLAG_BD_BIRTH_W;
250 }
251
252 sex = strtok_r(NULL, fmt_sep3, &lasts);
253 if (sex == NULL) {
254 continue;
255 }
256
257 bp = strtok_r(NULL, fmt_sep3, &lasts);
258 if (bp == NULL) {
259 continue;
260 }
261
262 d_notice_range = 0; /* notice off */
263 notice_force_range = FALSE;
264 if (*bp == '+') {
265 bp++; /* skip '+' */
266 d_notice_range = deathday_notice_range;
267 if (isdigit((unsigned char)*bp) != 0) {
268 d_notice_range = (int)strtol(bp, &bp, 10);
269 notice_force_range = TRUE;
270 }
271 bp = strtok_r(NULL, fmt_sep3, &lasts);
272 }
273 if (deathday_notice_flag == NOTICE_NO) {
274 d_notice_range = 0; /* notice off */
275 } else if (deathday_notice_flag == NOTICE_ALL) {
276 if (d_notice_range == 0 && notice_force_range == FALSE) {
277 d_notice_range = deathday_notice_range;
278 }
279 }
280
281 if (bp == NULL) {
282 continue;
283 }
284
285 sp = xstrdup(bp);
286 if (read_date(0x99, sp, &bdata.death, &wflag) == DATE_OK) {
287 bdata.flags |= FLAG_BD_DEATH;
288 if (wflag != FALSE) {
289 bdata.flags |= FLAG_BD_DEATH_W;
290 }
291 bp = strtok_r(NULL, fmt_sep3, &lasts);
292 }
293 free(sp);
294
295 name[0] = bp;
296 if (name[0] == NULL) {
297 continue;
298 }
299 name[1] = strtok_r(NULL, fmt_sep3, &lasts);
300 if (name[1] == NULL) {
301 name[1] = name[0];
302 }
303
304 if (birthday_check_sex(sex, &bdata.sex) == FALSE) {
305 errprint("birthday", ERR_WARN, "%s: %d: sex type %s for %s", infile, lines, sex, name[0]);
306 }
307
308 bdata.name = undertospace(name[0]);
309
310 if ((bdata.flags & FLAG_BD_BIRTH) != 0 &&
311 birthday_check_noticerange(bdata.birth, notice_range, &diffday, &bdata.age) == TRUE) {
312 birthday_display(diffday, bdata);
313 }
314
315 if ((bdata.flags & FLAG_BD_DEATH) != 0 &&
316 deathday_flag == TRUE &&
317 birthday_check_noticerange(bdata.death, d_notice_range, &diffday, &bdata.ayear) == TRUE) {
318 bdata.age = period_year(bdata.birth, bdata.death);
319 deathday_display(diffday, bdata);
320 }
321 }
322
323 closefile();
324 }
325
326 /*
327 * ���̡�̤��/�������̤���
328 *
329 * return value:
330 * TRUE : ��������
331 * FALSE : ���顼ȯ��
332 */
333 static
birthday_check_sex(const char * sex,int * flag_sex)334 int birthday_check_sex(const char *sex, int *flag_sex)
335 {
336 static const struct SEX_T {
337 const char *string;
338 const int type;
339 } sextbl[] = {
340 { "ms", SET_MALE | SET_UNMARRIED },
341 { "mu", SET_MALE | SET_UNMARRIED },
342 { "mm", SET_MALE | SET_MARRIED },
343 { "fs", SET_FEMALE | SET_UNMARRIED },
344 { "fu", SET_FEMALE | SET_UNMARRIED },
345 { "fm", SET_FEMALE | SET_MARRIED },
346 { "m?", SET_MALE | SET_UNMARRIED },
347 { "f?", SET_FEMALE | SET_UNMARRIED },
348 { "?s", SET_MALE | SET_UNMARRIED | SET_UNKNOWN },
349 { "?u", SET_MALE | SET_UNMARRIED | SET_UNKNOWN },
350 { "?m", SET_MALE | SET_MARRIED | SET_UNKNOWN },
351 { "??", SET_MALE | SET_UNMARRIED | SET_UNKNOWN },
352 };
353 int i;
354
355 *flag_sex = SET_MALE | SET_UNMARRIED | SET_UNKNOWN;
356
357 for (i = 0; i < (sizeof(sextbl) / sizeof(struct SEX_T)); i++) {
358 if (stricmp(sex, sextbl[i].string) == 0) {
359 *flag_sex = sextbl[i].type;
360 return (TRUE);
361 }
362 }
363
364 return (FALSE);
365 }
366
367 /*
368 * ��������̿���ޤǤδ��֤��ᡢͽ������⤫Ĵ�٤�
369 * ǯ��/��ǯ�����
370 *
371 * return value:
372 * TRUE ͽ�������
373 * FALSE ͽ���ϰϳ�
374 */
375 static
birthday_check_noticerange(struct DATE_T date,int notice_range,int * diffday,int * age)376 int birthday_check_noticerange(struct DATE_T date, int notice_range, int *diffday, int *age)
377 {
378 int cmpyear;
379 int diffmonth;
380 int diffdays;
381 struct DATE_T nowdate;
382
383 if (date.month == 0 && date.day == 0) {
384 return (FALSE);
385 }
386
387 if (date.month == 2 && date.day == 29 && isleap(calendar.year) == 0) {
388 /* 2/29 -> 3/1 translation */
389 date.month = 3;
390 date.day = 1;
391 }
392
393 cmpyear = calendar.year;
394 diffmonth = calendar.month - date.month;
395 if (diffmonth >= 6) {
396 cmpyear++;
397 } else if (diffmonth <= -6) {
398 cmpyear--;
399 }
400 diffdays = (int)(Julian(cmpyear, date.month, date.day) - calendar.julian_day);
401 if (diffdays != 0) {
402 if (notice_range == 0 || diffdays > notice_range || diffdays < -1) {
403 return (FALSE);
404 }
405 if (diffdays >= 28) {
406 if (diffdays > monthtbl[CENTER_MONTH].dayofmonth) {
407 return (FALSE);
408 }
409 if (date.day == calendar.day) {
410 diffdays = NOTICE_MONTH(1);
411 }
412 }
413 }
414
415 *diffday = diffdays;
416
417 /* ǯ��/��ǯ�� */
418 nowdate = date;
419 nowdate.year = cmpyear;
420 *age = period_year(date, nowdate);
421 if (date.year != 0 && *age < 0) {
422 return (FALSE); /* �ޤ����ޤ�Ƥ��ʤ�/˴���ʤäƤ��ʤ� */
423 }
424
425 return (TRUE);
426 }
427
428 /*
429 * ����(ǯ)�����
430 *
431 * �Ϥ�����դ�꽪�������դ�ɬ���礭������
432 * #ifdef ROUGH_PERIOD_YEAR
433 * �ɤ��餫�����դ� 00/00 �ξ���ñ��� end.year - start.year ���֤�
434 * #endif
435 *
436 * ǯ��˴����ǯ��˴���Ƥ���δ���(ǯ)
437 */
438 static
period_year(struct DATE_T start,struct DATE_T end)439 int period_year(struct DATE_T start, struct DATE_T end)
440 {
441 int period;
442
443 if (start.year == 0 || end.year == 0 || start.year > end.year) {
444 return (-1); /* �Ϥᡢ������ǯ�β������� 0 �ξ��Ϸ����ʤ� */
445 }
446
447 #ifndef ROUGH_PERIOD_YEAR
448 if (start.month == 0 || start.day == 0 ||
449 end.month == 0 || end.day == 0) {
450 return (-1); /* ����(����)�������ξ��ϴ���(ǯ)����ʤ� */
451 }
452 #endif
453
454 if (start.month == 2 && start.day == 29 && isleap(start.year) == 0) {
455 /* 2/29 -> 3/1 translation */
456 start.month = 3;
457 start.day = 1;
458 }
459
460 if (end.month == 2 && end.day == 29 && isleap(end.year) == 0) {
461 /* 2/29 -> 3/1 translation */
462 end.month = 3;
463 end.day = 1;
464 }
465
466 period = end.year - start.year;
467 if (start.year < 0 && end.year > 0) { /* �������������ޤ��� */
468 period--;
469 }
470 if (start.month != 0 && end.month != 0 &&
471 (end.month < start.month ||
472 (end.month == start.month && end.day < start.day))) {
473 period--;
474 }
475
476 return (period);
477 }
478
479 /*
480 * ����������Ϥ���(ͽ��)
481 */
482 static
birthday_display(int diffday,struct BDATA bdata)483 void birthday_display(int diffday, struct BDATA bdata)
484 {
485 static const char tbl_show_age[2][4] = {
486 { VISIBLE, VISIBLE, AGECHECK, INVISIBLE }, /* male */
487 { VISIBLE, INVISIBLE, INVISIBLE, INVISIBLE }, /* female */
488 };
489 #ifdef BIRTHDAY_ENDMSG_CUT
490 char *ep;
491 #endif
492 char *end_msg;
493 int sortorder_no;
494 int show_age;
495 int period = FALSE;
496 int i;
497
498 sortorder_no = 0; /* ���� */
499 if (diffday < 0) {
500 sortorder_no = 1; /* ���� */
501 } else if (diffday > 0) {
502 sortorder_no = 2; /* ���� */
503 } else {
504 birthday_todayhit_flag = TRUE;
505 }
506 for (i = 0; i < MAXSORTITEM; i++) {
507 if (birthday_sortorder_tbl[i] == sortorder_no) {
508 break;
509 }
510 }
511 if (i >= MAXSORTITEM) {
512 return ;
513 }
514
515 if (bdata.birth.year == 0) {
516 show_age = INVISIBLE;
517 } else {
518 show_age = (int)tbl_show_age[bdata.sex & MASK_SEX][birthday_effect_agelevel];
519 if (show_age == AGECHECK) {
520 if (bdata.age < 25) { /* 25��̤����ǯ��ɽ�� */
521 show_age = VISIBLE;
522 } else {
523 show_age = INVISIBLE;
524 }
525 }
526 }
527
528 #ifdef BIRTHDAY_ENDMSG_CUT
529 ep = strlastp(bdata.name);
530 if (ep[-1] == '.') {
531 ep[-1] = '\0';
532 period = TRUE;
533 }
534 #endif
535
536 sprintf(msgbuf, "%s %s �����", Notice_Message(bdata.name, diffday, &end_msg), bdata.name);
537 if (show_age == VISIBLE) {
538 sprintf(strlastp(msgbuf), "%d���ܤ�", bdata.age);
539 }
540 strcat(msgbuf, "������");
541 if (period == FALSE) {
542 strcat(msgbuf, end_msg);
543 }
544 strcat(msgbuf, MSG_PERIOD);
545
546 /* ���������ɲþ��� */
547 if ((birthday_effect_addinfo & FLAG_AI_BIRTH) != 0 &&
548 (bdata.flags & FLAG_BD_DEATH) != 0) {
549 add_dateinfo(DATE_ADDDT_BIRTH, bdata.death, bdata.flags & FLAG_BD_DEATH_W);
550 }
551
552 birthday_listadd(sortorder_no, diffday, bdata.age);
553 }
554
555 /*
556 * ���������Ȥ��뤿�ᡢ�ꥹ�ȹ�¤�˳�Ǽ����
557 *
558 * �ꥹ�ȹ�¤��Ǽ��ˡ(�����Ȥ��ʤ��Ȥ������� No.0)
559 * No.0: ����
560 * No.1: ����
561 * No.2: ����
562 */
563 static
birthday_listadd(int sortorder_no,int diffday,int age)564 void birthday_listadd(int sortorder_no, int diffday, int age)
565 {
566 (void)xstrescape(msgbuf);
567
568 if (birthday_sortflag == FALSE) {
569 list_add(0, 0, 0, 0, msgbuf);
570 } else {
571 switch (birthday_agesort) {
572 case SORT_NO_ORDER:
573 list_add(sortorder_no, diffday, age, 0, msgbuf);
574 break;
575 case SORT_UP_ORDER:
576 list_insert(sortorder_no, diffday, age, 0, msgbuf);
577 break;
578 case SORT_DOWN_ORDER:
579 list_insert(sortorder_no, diffday, -age, 0, msgbuf);
580 break;
581 }
582 }
583
584 birthday_listup_flag = TRUE;
585 }
586
587 /*
588 * �������Υ����ȥ�ɽ��
589 */
590 static
birthday_title(void)591 void birthday_title(void)
592 {
593 if (birthday_title_flag == FALSE) {
594 birthday_title_flag = TRUE;
595
596 pager_output_skip();
597 #ifdef MSG_STYLE
598 pager_output("----------- ������ -----------");
599 #else
600 pager_output("�ݡݡݡݡݡ����������ݡݡݡݡ�");
601 #endif
602 }
603 }
604
605 /*
606 * ��������ꥹ�ȥ��å�
607 */
608 static
birthday_listup(void)609 void birthday_listup(void)
610 {
611 int i;
612
613 if (birthday_listup_flag == FALSE) {
614 return ;
615 }
616
617 birthday_title();
618
619 if (birthday_sortflag == FALSE) {
620 list_output(0, pager_output);
621 } else {
622 for (i = 0; i < MAXSORTITEM; i++) {
623 if (birthday_sortorder_tbl[i] >= 0) {
624 list_output(birthday_sortorder_tbl[i], pager_output);
625 }
626 }
627 }
628 }
629
630 /*
631 * ���¡������С�������β֡��������β֡��ָ��դ�ɽ��
632 */
633 static
birthday_message(void)634 void birthday_message(void)
635 {
636 const char *defSuffix;
637 const struct FLOWER_T *flower;
638
639 if (birthday_flower == TRUE || birthday_todayhit_flag == TRUE) {
640 birthday_title();
641
642 defSuffix = GetDefaultSuffix(0);
643 flower = GetLanguageofFlower(calendar.month, calendar.day);
644
645 if (birthday_todayhit_flag == TRUE) {
646 pager_output("���¤� %s %s" MSG_PERIOD, GetNameofConstellation(calendar.month, calendar.day), defSuffix);
647 pager_output("������ %s %s" MSG_PERIOD, GetNameofBirthstone(calendar.month), defSuffix);
648 }
649 pager_output("%s��β֤� %s %s" MSG_PERIOD, (birthday_todayhit_flag != FALSE) ? "����" : "��", GetNameofBirthflowers(calendar.month), defSuffix);
650 pager_output("%s�֤� %s���֤��ȤФϡ�%s��%s" MSG_PERIOD, (birthday_todayhit_flag != FALSE) ? "��������" : "����������", flower->name, flower->language, defSuffix);
651 }
652 }
653
654 /*
655 * ̿������Ϥ���(ͽ��)
656 */
657 static
deathday_display(int diffday,struct BDATA bdata)658 void deathday_display(int diffday, struct BDATA bdata)
659 {
660 #ifdef BIRTHDAY_ENDMSG_CUT
661 char *ep;
662 #endif
663 char *end_msg;
664 int sortorder_no;
665 int period = FALSE;
666 int i;
667
668 sortorder_no = 0; /* ���� */
669 if (diffday < 0) {
670 sortorder_no = 1; /* ���� */
671 } else if (diffday > 0) {
672 sortorder_no = 2; /* ���� */
673 }
674 for (i = 0; i < MAXSORTITEM; i++) {
675 if (birthday_sortorder_tbl[i] == sortorder_no) {
676 break;
677 }
678 }
679 if (i >= MAXSORTITEM) {
680 return ;
681 }
682
683 #ifdef BIRTHDAY_ENDMSG_CUT
684 ep = strlastp(bdata.name);
685 if (ep[-1] == '.') {
686 ep[-1] = '\0';
687 period = TRUE;
688 }
689 #endif
690
691 sprintf(msgbuf, "%s %s �����", Notice_Message(bdata.name, diffday, &end_msg), bdata.name);
692 if ((deathday_effect_agelevel & FLAG_D_AYEAR) != 0 && bdata.ayear > 0) {
693 sprintf(strlastp(msgbuf), "%d���ܤ�", bdata.ayear);
694 }
695 strcat(msgbuf, "̿��");
696 if (period == FALSE) {
697 strcat(msgbuf, end_msg);
698 }
699 strcat(msgbuf, MSG_PERIOD);
700
701 if ((deathday_effect_agelevel & FLAG_D_AGE) != 0 && bdata.age >= 0) {
702 sprintf(strlastp(msgbuf), "��ǯ%d��" MSG_PERIOD, bdata.age);
703 }
704
705 /* ̿�����ɲþ��� */
706 if ((birthday_effect_addinfo & FLAG_AI_DEATH) != 0) {
707 add_dateinfo(DATE_ADDDT_DEATH, bdata.birth, bdata.flags & FLAG_BD_BIRTH_W);
708 }
709
710 deathday_listadd(sortorder_no, diffday, bdata.ayear, bdata.age);
711 }
712
713 /*
714 * ̿�����Ȥ��뤿�ᡢ�ꥹ�ȹ�¤�˳�Ǽ����
715 *
716 * �ꥹ�ȹ�¤��Ǽ��ˡ(�����Ȥ��ʤ��Ȥ������� No.0)
717 * No.0: ����
718 * No.1: ����
719 * No.2: ����
720 */
721 static
deathday_listadd(int sortorder_no,int diffday,int ayear,int age)722 void deathday_listadd(int sortorder_no, int diffday, int ayear, int age)
723 {
724 (void)xstrescape(msgbuf);
725
726 if (birthday_sortflag == FALSE) {
727 list_add(LIST_DEATHDAY_BASE, 0, 0, 0, msgbuf);
728 } else {
729 switch (birthday_agesort) {
730 case SORT_NO_ORDER:
731 list_add(sortorder_no + LIST_DEATHDAY_BASE, diffday, ayear, age, msgbuf);
732 break;
733 case SORT_UP_ORDER:
734 list_insert(sortorder_no + LIST_DEATHDAY_BASE, diffday, ayear, age, msgbuf);
735 break;
736 case SORT_DOWN_ORDER:
737 list_insert(sortorder_no + LIST_DEATHDAY_BASE, diffday, -ayear, -age, msgbuf);
738 break;
739 }
740 }
741
742 deathday_listup_flag = TRUE;
743 }
744
745 /*
746 * ̿����ꥹ�ȥ��å�
747 */
deathday_listup(void)748 void deathday_listup(void)
749 {
750 int i;
751
752 if (deathday_listup_flag == FALSE) {
753 return ;
754 }
755
756 pager_output_skip();
757 #ifdef MSG_STYLE
758 pager_output("----------- ̿�� -----------");
759 #else
760 pager_output("�ݡݡݡݡݡ�̿�����ݡݡݡݡ�");
761 #endif
762
763 if (birthday_sortflag == FALSE) {
764 list_output(LIST_DEATHDAY_BASE, pager_output);
765 } else {
766 for (i = 0; i < MAXSORTITEM; i++) {
767 if (birthday_sortorder_tbl[i] >= 0) {
768 list_output(birthday_sortorder_tbl[i] + LIST_DEATHDAY_BASE, pager_output);
769 }
770 }
771 }
772 }
773
774 /*
775 * �ɲþ�����ɲä���
776 */
777 static
add_dateinfo(int type,struct DATE_T date,int wflag)778 void add_dateinfo(int type, struct DATE_T date, int wflag)
779 {
780 const char *msg1;
781 const char *msg2;
782 const char *msgfmt;
783 const char *nameofera;
784 const char *temp_name;
785 char *msg_w;
786 int date_flag = 0;
787 int disp_year;
788 int temp_year;
789 #define FLAG_DISP_YY 01
790 #define FLAG_DISP_MMDD 02
791 #define FLAG_DISP_YYMMDD (FLAG_DISP_YY|FLAG_DISP_MMDD)
792
793 switch (type) {
794 case DATE_ADDDT_BIRTH:
795 msg1 = "��";
796 msg2 = "̿������";
797 break;
798 case DATE_ADDDT_DEATH:
799 msg1 = "���ޤ�";
800 msg2 = "����������";
801 break;
802 }
803
804 if (date.year != 0) {
805 date_flag |= FLAG_DISP_YY;
806 nameofera = (date.year < 0) ? "BC" : "";
807 disp_year = abs(date.year);
808 }
809 if (date.month != 0 && date.day != 0) {
810 date_flag |= FLAG_DISP_MMDD;
811 }
812
813 msg_w = strlastp(msgbuf);
814
815 switch (date_flag) {
816 case 0:
817 sprintf(msg_w, "(%s)", msg2);
818 break;
819 case FLAG_DISP_YY:
820 sprintf(msg_w, "(%s%04d%s)", nameofera, disp_year, msg1);
821 break;
822 case FLAG_DISP_MMDD:
823 sprintf(msg_w, "(%02d/%02d%s)", date.month, date.day, msg1);
824 break;
825 case FLAG_DISP_YY | FLAG_DISP_MMDD:
826 if (wflag != 0 &&
827 (temp_name = GetNameofEra(LANG_E, date.year, date.month, date.day, &temp_year)) != NULL) {
828 msgfmt = "(%s%02d/%02d/%02d%s)";
829 nameofera = temp_name;
830 disp_year = temp_year;
831 } else {
832 msgfmt = "(%s%04d/%02d/%02d%s)";
833 }
834 sprintf(msg_w, msgfmt, nameofera, disp_year, date.month, date.day, msg1);
835 break;
836 }
837 }
838
839 /*
840 * ��å���������ȥ������
841 *
842 * ${ctrl}
843 *
844 * ctrl: An ǯ��ɽ����٥� 0-3
845 * Dn ��ǯ����ǯɽ����٥� 0-3
846 * In ��������̿�����ɲþ���ɽ����٥� 0-3
847 */
848 static
ctrl_msg_proc(char * bp)849 void ctrl_msg_proc(char *bp)
850 {
851 int n;
852
853 bp++;
854 while (*bp != '\0') {
855 switch (*bp) {
856 case 'A':
857 bp++;
858 if (isdigit(*bp) != 0) {
859 n = *bp - '0';
860 if (0 <= n && n <= FLAG_B_MASK) {
861 birthday_effect_agelevel = n;
862 }
863 bp++;
864 } else {
865 /* RESET */
866 birthday_effect_agelevel = birthday_agelevel;
867 }
868 break;
869 case 'D':
870 bp++;
871 if (isdigit(*bp) != 0) {
872 n = *bp - '0';
873 if (0 <= n && n <= FLAG_D_MASK) {
874 deathday_effect_agelevel = n;
875 }
876 bp++;
877 } else {
878 /* RESET */
879 deathday_effect_agelevel = deathday_agelevel;
880 }
881 break;
882 case 'I':
883 bp++;
884 if (isdigit(*bp) != 0) {
885 n = *bp - '0';
886 if (0 <= n && n <= FLAG_AI_MASK) {
887 birthday_effect_addinfo = n;
888 }
889 bp++;
890 } else {
891 /* RESET */
892 birthday_effect_addinfo = birthday_addinfo;
893 }
894 break;
895 default:
896 bp++;
897 break;
898 }
899 }
900 }
901