1 /*
2 * calendar.c -- calendar display program
3 *
4 * Copyright (C) 1988,1999,2003 by Yoshifumi Mori
5 *
6 * 2003/06/14 SAT - UNIX defpathbuf[] �ɲ�
7 * 2003/04/08 TUE ver.2.5B - �ֹ�̱�ε�����ư����
8 * 1999/01/19 TUE ver.2.5A - holiday.tbl load proc move to misc.c
9 * 1997/05/25 SUN ver.2.5 - holiday.tbl format change
10 * 1993/08/19 THU ver.2.4A - human68k ESC output sequence change
11 * 1993/07/08 THU ver.2.4
12 * 1993/06/29 TUE - holiday.tbl 10��ʬ ���º��
13 * 1993/06/27 SUN - -& -> -r, schedule display support.
14 * 1993/06/20 SUN ver.2.3 - -@, -& option support.
15 * 1993/05/09 SUN ver.2.2 - minor change
16 * 1992/05/13 WED ver.2.1 - minor change
17 * 1992/04/23 THU ver.2.0 - kyureki, color config.
18 * 1991/03/03 SUN ver.1.7 - 3 month display support.
19 * 1990/04/07 SAT ver.1.6a
20 * 1990/03/31 SAT ver.1.6
21 * 1990/03/11 SUN ver.1.5a
22 * 1989/09/24 SUN ver.1.5
23 * 1989/09/12 TUE ver.1.4a
24 * 1989/09/11 MON ver.1.4 - X68000 version.
25 * 1989/06/05 MON ver.1.3a - help option add.
26 * 1989/06/01 THU ver.1.3 - ANSI escape sequence.
27 * 1989/04/11 TUE ver.1.2
28 * 1989/03/22 WED ver.1.1
29 * 1988/12/19 MON ver.1.0
30 *
31 * tab:4
32 */
33
34 #include "cdefs.h"
35 #include "extern.h"
36
37 #define MAXATTRBUF 24 /* ���������ץ�������Ÿ���Хåե� */
38 #define MAXLINEBUF 512 /* 1��Ÿ���Хåե��� */
39 #define MAXLINE 6
40 #define MAXWEEK 7
41 #define MAXMONTH 3
42 #define CENTER_MONTH (MAXMONTH / 2)
43 #define MAXWEEKTBL (MAXLINE * MAXWEEK)
44 #define MAXMONTHNAME 9
45 #define MAXROKUYOU 6
46
47 enum WEEK {
48 SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY,
49 };
50
51 static const char Copyright[] = "Copyright (C) 1988,1999,2003 by Yoshifumi Mori";
52 static const char version[] = "calendar " __DATE__ " version 2.5B";
53
54 const char *fmt_sep1 = "/\t ";
55 const char *fmt_sep2 = ",\t ";
56 const char *fmt_sep3 = "\t ";
57 const char *fmt_sep4 = "";
58
59 const char *todaycnf_file = "today.cnf";
60
61 static char cmdpathbuf[_T_MAXPATHNAME];
62 #if defined(_T_UNIX)
63 static char defpathbuf[_T_MAXPATHBUF];
64 #endif
65 static char linebuffer[MAXLINEBUF];
66 static int daytbl[MAXMONTH][MAXWEEKTBL];
67 static int attrtbl[MAXMONTH][MAXWEEKTBL];
68 static int weekcolor[MAXWEEK];
69 static int cal3_flag = FALSE;
70 static int kyureki_flag = FALSE;
71 static int kyureki_valid_flag = TRUE;
72 static int schedule_flag = TRUE;
73
74 static struct CALENDAR nowdate;
75
76 struct CALTBL caltbl[MAXMONTH];
77
78 #define CTBL_COLORMASK 0x0F /* ���顼�ޥ��� */
79 #define CTBL_REVERSE 16 /* ��С���(ȿžʸ��) */
80 #define CTBL_BLINK 17 /* �֥��(����ʸ��) */
81 #define CTBL_HIGHLIGHT 18 /* �ϥ��饤��(��Ĵʸ��) */
82 #define CTBL_MAX 19 /* ���顼�����ɥơ��֥�� */
83
84 /* ���顼���������ץ������� �ֹ�ơ��֥� */
85 static int color[CTBL_MAX] = {
86 30, /* �� */
87 34, /* �� */
88 31, /* �� */
89 35, /* �� */
90 32, /* �� */
91 36, /* �忧 */
92 33, /* �� */
93 37, /* �� */
94 0, 0, 0, 0, 0, 0, 0, 0, /* ͽ���ΰ� */
95 7, /* ��С���(ȿžʸ��) */
96 5, /* �֥��(����ʸ��) */
97 1, /* �ϥ��饤��(��Ĵʸ��) */
98 };
99
100 #define COL_NONE -1
101 #define COL_WEEKDAY 0 /* ʿ�� */
102 #define COL_SUNDAY 1 /* ���� */
103 #define COL_SATDAY 2 /* ���� */
104 #define COL_HOLIDAY 3 /* ����/���� */
105 #define COL_ROKUYOU 4 /* ϻ�� */
106 #define COL_SCHEDULE 10 /* �������塼�뤢�� */
107 #define COL_TODAY 20 /* ���� */
108 #define COL_HEADER 40 /* �إå��� */
109 #define COL_MAX 41 /* ���顼�ơ��֥�� */
110
111 #define ATTR_REVERSE 0x10 /* ��С���(ȿžʸ��) */
112 #define ATTR_BLINK 0x20 /* �֥��(����ʸ��) */
113 #define ATTR_HIGHLIGHT 0x40 /* �ϥ��饤��(��Ĵʸ��) */
114
115 /* �������� �ƹ��ܥ��顼�ơ��֥� */
116 static int calcolor[COL_MAX] = {
117 0x07, 0x02, 0x05, 0x02, 0x04, 0x05, 0x03, 0x01, 0x02, 0x07, /* 0~9 */
118 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 10~19 */
119 0x67, 0x62, 0x65, 0x62, 0x64, 0x65, 0x63, 0x61, 0x62, 0x67, /* 20~29 */
120 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 30~39 */
121 0x07,
122 };
123 /* calcolor[n]
124 * 0 : ʿ�� ��
125 * 1 : ���� ��
126 * 2 : ���� �忧
127 * 3 : ����/���� ��
128 * 4 : �辡 ��
129 * 5 : ͧ�� �忧
130 * 6 : ���� ��
131 * 7 : ʩ�� ��
132 * 8 : ��� ��
133 * 9 : �ָ� ��
134 * 10 : �������塼�뤢�� ����
135 * 11~29 : ͽ���ΰ�
136 * 20~30 : ʿ�����ָ� �����ξ�� �ƿ�+�֥��+�ϥ��饤��
137 * 31~39 : ͽ���ΰ�
138 * 40 : �إå��� ��
139 */
140
141 #define COLMAP_COLMASK(x) ((x) & 0x00FF)
142 #define COLMAP_NEWLINE 0x0100
143 #define COLMAP_TODAY 0x0200
144 #define COLMAP_ROKUYOU 0x0400
145 #define COLMAP_HEADER 0x0800
146 #define COLMAP_ATTRMASK(x) ((x) & (COLMAP_NEWLINE | COLMAP_TODAY | \
147 COLMAP_ROKUYOU | COLMAP_HEADER))
148
149 enum {
150 COLMAP_FIRST, /* ���� */
151 COLMAP_SECOND, /* ���� */
152 COLMAP_ROKUYOU1, /* ϻ�� ��6�� */
153 COLMAP_ROKUYOU2, /* ϻ�� ��3�� */
154 };
155
156 static struct COLOR_MAP {
157 const char *name;
158 const int attr;
159 } colormap_tbl[] = {
160 { "�إå���", COL_HEADER | COLMAP_HEADER | COLMAP_NEWLINE },
161 { "ʿ��", COL_WEEKDAY | COLMAP_TODAY },
162 { "����", COL_SUNDAY | COLMAP_TODAY },
163 { "����", COL_SATDAY | COLMAP_TODAY },
164 { "����", COL_HOLIDAY | COLMAP_TODAY },
165 { "�������塼��", COL_SCHEDULE | COLMAP_TODAY | COLMAP_NEWLINE },
166 { "�辡", (COL_ROKUYOU + 0) | COLMAP_TODAY | COLMAP_ROKUYOU },
167 { "ͧ��", (COL_ROKUYOU + 1) | COLMAP_TODAY | COLMAP_ROKUYOU },
168 { "����", (COL_ROKUYOU + 2) | COLMAP_TODAY | COLMAP_ROKUYOU },
169 { "ʩ��", (COL_ROKUYOU + 3) | COLMAP_TODAY | COLMAP_ROKUYOU },
170 { "���", (COL_ROKUYOU + 4) | COLMAP_TODAY | COLMAP_ROKUYOU },
171 { "�ָ�", (COL_ROKUYOU + 5) | COLMAP_TODAY | COLMAP_ROKUYOU | COLMAP_NEWLINE },
172 { NULL, 0 }
173 };
174
175 static const struct OPERAND_TABLE op_mode[] = {
176 { "yes", TRUE },
177 { "no", FALSE },
178 { NULL, 0 },
179 };
180
181 /* ����ե����졼����� �ѥ��� */
182 static struct CONFIG_VARIABLE_TABLE conf_tbl[] = {
183 { "calcolor", VAR_DIMINT, { (void *)COL_MAX }, { calcolor } },
184 { "color", VAR_DIMINT, { (void *)CTBL_MAX }, { color } },
185 { "kyureki", VAR_OP, { op_mode }, { &kyureki_flag } },
186 { "replace_pathenv", VAR_OP, { op_mode }, { &replace_pathenv } },
187 { "schedule", VAR_OP, { op_mode }, { &schedule_flag } },
188 { "schedule_file", VAR_DIMSTR, { (void *)MAXSCHEDULEFILE }, { schedule_filetbl } },
189 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_WIN32CONSOLE)
190 { "table_path", VAR_STR, { NULL }, { &search_path } },
191 #else /* _T_UNIX */
192 { "table_path", VAR_PATH, { NULL }, { &search_path } },
193 #endif
194 { "three_months", VAR_OP, { op_mode }, { &cal3_flag } },
195 { NULL, VAR_NONE, { NULL }, { NULL } },
196 };
197
198 static const char *readblock[] = { "calendar", "common", NULL };
199
200 static void calendar(int year, int month);
201 static void setup_weekcolor(void);
202 static void schedule_setup(int monindex);
203 static void kyureki_setup(int monindex);
204 static void output_header(void);
205 static void output_calendar(void);
206 static void add_spaces(int spcnt, int *attr);
207 static void output_footer(void);
208 static void output_colormap(void);
209 static void output_colorsample(int type);
210 static void holidayset(int monindex);
211 static const char *MakeAttr(int attr);
212 static void clear_buffer(void);
213 static void add_buffer(const char *fmt, ...);
214 static void flush_buffer(void);
215
main(int argc,char ** argv)216 int main(int argc, char **argv)
217 {
218 int c_rtc;
219 int year, month;
220 int errflag;
221 int verflag;
222 int testflag;
223 int c;
224
225 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_WIN32CONSOLE)
226 {
227 char *p;
228
229 strncpy(cmdpathbuf, argv[0], sizeof(cmdpathbuf) - 1);
230 p = strrchr(cmdpathbuf, _T_FS_CHR);
231 if (p == NULL) {
232 p = strrchr(cmdpathbuf, '/');
233 if (p == NULL) {
234 p = strrchr(cmdpathbuf, ':');
235 }
236 }
237 if (p != NULL) {
238 p[1] = '\0';
239 search_cmdpath = cmdpathbuf;
240 }
241 }
242 #else /* _T_UNIX */
243 if (readlink(_T_PROCSELFEXE_PATH, cmdpathbuf, sizeof(cmdpathbuf) - 1) > 0 &&
244 cmdpathbuf[0] == '/') {
245 char *p;
246
247 p = strrchr(cmdpathbuf, '/');
248 if (p != NULL) {
249 p[1] = '\0';
250 }
251 search_cmdpath = cmdpathbuf;
252 }
253
254 (void)setlocale(LC_ALL, "");
255 strncpy(defpathbuf, _T_SEARCH_DEFPATHS, sizeof(defpathbuf) - 1);
256 search_defpath = defpathbuf;
257 #endif
258
259 search_envname = "TODAYTBL";
260 replace_pathenv = TRUE;
261
262 c_rtc = config(todaycnf_file, &conf_tbl[0], &readblock[0]);
263
264 #if defined(_T_UNIX)
265 /*
266 * unix �Ǥ� _T_SEARCH_DEFPATH �� today.cnf ���ɤ�� HOME ��
267 * today.cnf ���ɤ߹���
268 *
269 * table_path �� & �� HOME �ˤ��� today.cnf �� table_path �����ꤷ�Ƥ�
270 * ��� & ����ʬ������Υѥ����֤�������
271 *
272 * �� table_path = &:/home/mori/tbl
273 */
274 if (c_rtc == 0 && search_hitphase == 1) { /* _T_SEARCH_DEFPATH ��ȯ���Ǥ��� */
275 search_errignore = TRUE;
276 search_gophase = 6; /* _T_HOMEENV ��Ĵ�٤� */
277 (void)config(todaycnf_file, &conf_tbl[0], &readblock[0]);
278 search_gophase = 0;
279 search_errignore = FALSE;
280 }
281 #endif /* _T_UNIX */
282
283 rdcalendar(&nowdate);
284 year = nowdate.year;
285 month = nowdate.month;
286
287 errflag = FALSE;
288 verflag = FALSE;
289 testflag = FALSE;
290
291 while ((c = getopt(argc, argv, "13@::Kkr::Sstv?")) != EOF) {
292 switch (c) {
293 case '1':
294 cal3_flag = FALSE;
295 break;
296 case '3':
297 cal3_flag = TRUE;
298 break;
299 case 'k':
300 kyureki_flag = TRUE;
301 break;
302 case 'K':
303 kyureki_flag = FALSE;
304 break;
305 case 's':
306 schedule_flag = TRUE;
307 break;
308 case 'S':
309 schedule_flag = FALSE;
310 break;
311 case 'v':
312 verflag = TRUE;
313 break;
314 case 't':
315 testflag = TRUE;
316 break;
317 case 'r': /* ���Ū���ѿ������� */
318 if (optarg != NULL) {
319 config_oneline("cmdline", &conf_tbl[0], optarg);
320 }
321 break;
322 case '@': /* ���Ū�� TODAY.CNF ���ɤ߹��� */
323 config(optarg, &conf_tbl[0], &readblock[0]);
324 break;
325 case '?':
326 default:
327 errflag = TRUE;
328 break;
329 }
330 }
331
332 argc -= optind;
333 argv += optind;
334
335 switch (argc) {
336 case 0: /* no option */
337 break;
338 case 2: /* month & year option */
339 year = atoi(argv[1]);
340 case 1: /* month option */
341 month = atoi(argv[0]);
342 break;
343 default:
344 errflag = TRUE;
345 }
346
347 if (verflag == TRUE) {
348 puts(Copyright);
349 puts(version);
350 }
351 if (testflag == TRUE) {
352 output_colormap();
353 return (0);
354 }
355 if (errflag == TRUE) {
356 fprintf(stderr, "usage: calendar [options] [month [year]]\n"
357 "options:"
358 " -1|-3\tɽ���������\t\t-1��1��ʬ\n"
359 "\t -k|-K\tϻ�ˤ�ɽ������\t\t-k��ɽ��\n"
360 "\t -s|-S\t�������塼���ɽ������\t-s��ɽ��\n"
361 "\t -t\t�����������ɽ��\n"
362 "\t -v\t�С������ɽ��\n\n"
363 "\t -@file\t���Ū��%s(file)���ɤ߹���\n"
364 "\t -rvarname=value ���Ū���ѿ����ѹ�\n", todaycnf_file);
365 exit(3);
366 }
367
368 calendar(year, month);
369
370 return (0);
371 }
372
373 /*
374 * ��������ɽ���ᥤ��
375 */
376 static
calendar(int year,int month)377 void calendar(int year, int month)
378 {
379 int i;
380
381 if (year < 1 || year > 9999) {
382 errprint(NULL, ERR_ERROR, "invalid year %d\n", year);
383 exit(5);
384 }
385 if (month < 1 || month > 12) {
386 errprint(NULL, ERR_ERROR, "invalid month %d\n", month);
387 exit(5);
388 }
389
390 if (Loading_GengoTbl() != LOAD_OK) {
391 errprint(NULL, ERR_ERROR, "ǯ���Ѵ��ϤǤ��ޤ���");
392 }
393 if (Loading_HolidayTbl() != LOAD_OK) {
394 errprint(NULL, ERR_ERROR, "������������ɽ���Ǥ��ޤ���");
395 }
396
397 for (i = 0; i < MAXMONTH; i++) {
398 int nyear;
399 int nmonth;
400 int nday;
401
402 nyear = year;
403 nmonth = month + (i - CENTER_MONTH);
404 if (nmonth < 1) {
405 nyear--;
406 nmonth += 12;
407 }
408 if (nmonth > 12) {
409 nyear++;
410 nmonth -= 12;
411 }
412
413 nday = GetDayofMonth(nyear, nmonth);
414 caltbl[i].year = nyear;
415 caltbl[i].month = nmonth;
416 caltbl[i].dayofmonth = nday;
417 caltbl[i].first_dayofweek = GetDayofWeek(nyear, nmonth, 1);
418 caltbl[i].last_dayofweek = GetDayofWeek(nyear, nmonth, nday);
419 caltbl[i].monthname = GetNameofMonth(1, nmonth);
420 }
421
422 setup_weekcolor();
423 /*
424 * ����λ��ϰ츫��̵�̤˸����뤬
425 * �����顼������Ǥ��ʤ����ˡ����̤�����
426 */
427 for (i = 0; i < MAXMONTH; i++) {
428 int weekindex;
429
430 for (weekindex = 0; weekindex < MAXWEEKTBL; weekindex++) {
431 daytbl[i][weekindex] = 0;
432 attrtbl[i][weekindex] = weekcolor[weekindex % MAXWEEK];
433 }
434 }
435
436 if (schedule_flag == TRUE) {
437 schedule_find();
438 }
439
440 for (i = 0; i < MAXMONTH; i++) {
441 int weekindex;
442 int day;
443
444 weekindex = caltbl[i].first_dayofweek;
445
446 for (day = 1; day <= caltbl[i].dayofmonth; day++, weekindex++) {
447 daytbl[i][weekindex] = day;
448 }
449
450 if (kyureki_flag == FALSE) {
451 holidayset(i);
452 schedule_setup(i);
453 } else {
454 kyureki_setup(i);
455 #if 0
456 schedule_setup(i);
457 #endif
458 }
459
460 /* today mark */
461 if (caltbl[i].year == nowdate.year &&
462 caltbl[i].month == nowdate.month) {
463 weekindex = caltbl[i].first_dayofweek + nowdate.day - 1;
464 attrtbl[i][weekindex] += COL_TODAY;
465 }
466 }
467
468 output_header();
469 output_calendar();
470 output_footer();
471 }
472
473 /*
474 * ���ˤο������ꤹ��
475 */
476 static
setup_weekcolor(void)477 void setup_weekcolor(void)
478 {
479 int i;
480
481 for (i = 0; i < MAXWEEK; i++) {
482 weekcolor[i] = COL_WEEKDAY;
483 }
484 weekcolor[SUNDAY] = COL_SUNDAY;
485 weekcolor[SATURDAY] = COL_SATDAY;
486 }
487
488 /*
489 * �������塼������ꤹ��
490 */
491 static
schedule_setup(int monindex)492 void schedule_setup(int monindex)
493 {
494 int i;
495 int day;
496
497 if (schedule_flag == FALSE) {
498 return ;
499 }
500
501 for (i = 0; i < MAXWEEKTBL; i++) {
502 day = daytbl[monindex][i];
503 if (day > 0 && schedule_daytbl[monindex][day - 1] == SCHEDULE_EXIST) {
504 attrtbl[monindex][i] = COL_SCHEDULE;
505 }
506 }
507 }
508
509 /*
510 * ϻ��(����)�����ꤹ��
511 */
512 static
kyureki_setup(int monindex)513 void kyureki_setup(int monindex)
514 {
515 int year, month, day;
516 int i;
517
518 if (kyureki_valid_flag == FALSE) {
519 return ;
520 }
521
522 year = caltbl[monindex].year;
523 month = caltbl[monindex].month;
524
525 for (i = 0; i < MAXWEEKTBL; i++) {
526 day = daytbl[monindex][i];
527 if (day > 0) {
528 const struct LUNAR_CALENDAR *lc;
529
530 lc = GetLunarCalendar(year, month, day);
531 if (lc == NULL) {
532 errprint(NULL, ERR_ERROR, "�������뤳�Ȥ��Ǥ��ޤ���");
533 kyureki_valid_flag = FALSE;
534 return ;
535 }
536
537 attrtbl[monindex][i] = lc->dayofweek + COL_ROKUYOU;
538 }
539 }
540 }
541
542 /*
543 * �إå�������Ϥ���
544 */
545 static
output_header(void)546 void output_header(void)
547 {
548 const char *spbuf, *spbuf2;
549 int loop_limit;
550 int i;
551
552 clear_buffer();
553 add_buffer(MakeAttr(COL_HEADER));
554
555 spbuf = " "; /* 9 */
556 spbuf2 = " "; /* 5 */
557 loop_limit = 1;
558 if (cal3_flag == TRUE) {
559 spbuf = " "; /* 6 */
560 spbuf2 = " "; /* 2 */
561 loop_limit = MAXMONTH;
562 }
563
564 for (i = 0; i < MAXMONTH; i++) {
565 const char *nammonth;
566 char nambuf[MAXMONTHNAME + 1];
567 int spcnt;
568
569 if (cal3_flag == FALSE && i != CENTER_MONTH) {
570 continue;
571 }
572
573 nammonth = caltbl[i].monthname;
574 spcnt = (MAXMONTHNAME - strlen(nammonth)) / 2;
575 memset(nambuf, '\0', sizeof(nambuf));
576 memset(nambuf, ' ', spcnt);
577 strcat(nambuf, nammonth);
578
579 add_buffer("%s%-9s%s%4d", spbuf, nambuf, spbuf2, caltbl[i].year);
580
581 /* next month space */
582 if (cal3_flag == TRUE && i < (MAXMONTH - 1)) {
583 add_buffer(" ");
584 }
585 }
586 add_buffer(MakeAttr(COL_NONE));
587 flush_buffer();
588
589 add_buffer(MakeAttr(COL_HEADER));
590 for (i = 0; i < loop_limit; i++) {
591 if (cal3_flag == TRUE) {
592 add_buffer("SunMonTueWedThuFriSat");
593 /* next month space */
594 if (i < (loop_limit - 1)) {
595 add_buffer(" ");
596 }
597 } else {
598 add_buffer("Sun Mon Tue Wed Thu Fri Sat");
599 }
600 }
601 add_buffer(MakeAttr(COL_NONE));
602 flush_buffer();
603 }
604
605 /*
606 * �����������Τ���Ϥ���
607 */
608 static
output_calendar(void)609 void output_calendar(void)
610 {
611 int attr;
612 int linecount;
613
614 clear_buffer();
615 attr = COL_NONE;
616 add_buffer(MakeAttr(attr));
617
618 for (linecount = 0; linecount < MAXLINE; linecount++) {
619 int i;
620
621 for (i = 0; i < MAXMONTH; i++) {
622 int weekindex;
623 int weekcount;
624
625 if (cal3_flag == FALSE && i != CENTER_MONTH) {
626 continue;
627 }
628
629 weekindex = linecount * MAXWEEK;
630 for (weekcount = 0; weekcount < MAXWEEK; weekcount++) {
631 if (daytbl[i][weekindex] != 0) {
632 add_spaces(1, &attr);
633 if (attr != attrtbl[i][weekindex]) {
634 attr = attrtbl[i][weekindex];
635 add_buffer(MakeAttr(attr));
636 }
637 add_buffer("%2d", daytbl[i][weekindex]);
638 } else {
639 add_spaces(3, &attr);
640 }
641 if (cal3_flag == FALSE) {
642 add_spaces(1, &attr);
643 }
644 weekindex++;
645 }
646
647 /* next month space */
648 if (cal3_flag == TRUE && i < (MAXMONTH - 1)) {
649 add_spaces(2, &attr);
650 }
651 }
652 if (attr != COL_NONE) {
653 attr = COL_NONE;
654 add_buffer(MakeAttr(attr));
655 }
656 flush_buffer();
657 }
658 }
659
660 /*
661 * ���ϥХåե��˥��ڡ������ɲä���
662 */
663 static
add_spaces(int spcnt,int * attr)664 void add_spaces(int spcnt, int *attr)
665 {
666 if (*attr != COL_NONE) {
667 *attr = COL_NONE;
668 add_buffer(MakeAttr(*attr));
669 }
670 while (spcnt-- > 0) {
671 add_buffer(" ");
672 }
673 }
674
675 /*
676 * �եå�������Ϥ���
677 */
678 static
output_footer(void)679 void output_footer(void)
680 {
681 if (kyureki_flag == FALSE || kyureki_valid_flag == FALSE) {
682 return ;
683 }
684
685 if (cal3_flag == FALSE) {
686 output_colorsample(COLMAP_ROKUYOU2);
687 } else {
688 output_colorsample(COLMAP_ROKUYOU1);
689 }
690 }
691
692 /*
693 * ���������γƿ���������֤�ɽ������
694 */
695 static
output_colormap(void)696 void output_colormap(void)
697 {
698 clear_buffer();
699 add_buffer("%s�������� �ƿ��������", MakeAttr(COL_NONE));
700 flush_buffer();
701
702 output_colorsample(COLMAP_FIRST);
703
704 add_buffer("%s������", MakeAttr(COL_NONE));
705 flush_buffer();
706
707 output_colorsample(COLMAP_SECOND);
708 }
709
710 /*
711 * �ƹ��ܤο������ɽ������
712 */
713 static
output_colorsample(int type)714 void output_colorsample(int type)
715 {
716 int i = 0;
717 struct COLOR_MAP *cmp;
718
719 clear_buffer();
720
721 for (cmp = colormap_tbl; cmp->name != NULL; cmp++) {
722 int attr = COLMAP_ATTRMASK(cmp->attr);
723 int dspflag = FALSE;
724 int base_no = 0;
725 int namcolor = COL_NONE;
726
727 switch (type) {
728 case COLMAP_FIRST:
729 dspflag = TRUE;
730 break;
731 case COLMAP_SECOND:
732 if (attr & COLMAP_TODAY) {
733 dspflag = TRUE;
734 base_no = COL_TODAY;
735 }
736 break;
737 case COLMAP_ROKUYOU1:
738 case COLMAP_ROKUYOU2:
739 if (attr & COLMAP_ROKUYOU) {
740 dspflag = TRUE;
741 namcolor = COL_HEADER;
742 if (type == COLMAP_ROKUYOU2) {
743 i++;
744 }
745 }
746 break;
747 }
748
749 if (dspflag == TRUE) {
750 add_buffer("%s��", MakeAttr(COLMAP_COLMASK(cmp->attr) + base_no));
751 add_buffer("%s..%s", MakeAttr(namcolor), cmp->name);
752
753 if (namcolor == COL_HEADER) {
754 add_buffer(MakeAttr(COL_NONE));
755 }
756
757 if (attr & COLMAP_NEWLINE || i == 3) {
758 flush_buffer();
759 } else {
760 add_buffer(" ");
761 }
762 }
763 }
764
765 flush_buffer();
766 }
767
768 /*
769 * ���������������������ꤹ��(���ص�����Ԥ�)
770 */
771 static
holidayset(int monindex)772 void holidayset(int monindex)
773 {
774 int *tbl;
775 int i;
776 int day;
777 int week;
778
779 tbl = GetHolidayTbl(caltbl[monindex].year, caltbl[monindex].month);
780 if (tbl != NULL) {
781 for (i = 0; i < MAX_DAYOFMONTH; i++) {
782 if (tbl[i] != 0) {
783 day = i + 1;
784 week = caltbl[monindex].first_dayofweek + day - 1;
785 if ((week % MAXWEEK) == SUNDAY &&
786 checkTransferHoliday(caltbl[monindex].year, caltbl[monindex].month, day) == TRUE) {
787 day++;
788 week++; /* ���ص��� */
789 }
790 if (day <= caltbl[monindex].dayofmonth) {
791 attrtbl[monindex][week] = COL_HOLIDAY;
792 } else if ((monindex + 1) < MAXMONTH) {
793 attrtbl[monindex + 1][week % MAXWEEK] = COL_HOLIDAY;
794 }
795 }
796 /* �ֹ�̱�ε�����Ŭ�����б� */
797 if (i >= 2 &&
798 tbl[i - 2] != 0 &&
799 tbl[i - 1] == 0 &&
800 tbl[i + 0] != 0 &&
801 checkNationalHoliday(caltbl[monindex].year, caltbl[monindex].month, i) == TRUE) {
802 week = caltbl[monindex].first_dayofweek + i - 1;
803 if ((week % MAXWEEK) != SUNDAY) {
804 attrtbl[monindex][week] = COL_HOLIDAY;
805 }
806 }
807 }
808 free(tbl);
809 }
810 }
811
812 /*
813 * ���������ץ�������ʸ�������
814 */
815 static
MakeAttr(int attr)816 const char *MakeAttr(int attr)
817 {
818 static char attrbuf[MAXATTRBUF];
819 int colno;
820
821 colno = calcolor[attr];
822
823 strcpy(attrbuf, "\033[");
824 if (attr == COL_NONE) {
825 strcat(attrbuf, "0m");
826 return (attrbuf);
827 }
828 #if defined(_T_HUMAN68K)
829 sprintf(strlastp(attrbuf), "%d", color[colno & CTBL_COLORMASK]);
830 if ((colno & ATTR_HIGHLIGHT) != 0 && color[CTBL_HIGHLIGHT] != 0) {
831 sprintf(strlastp(attrbuf), ";%d", color[CTBL_HIGHLIGHT]);
832 }
833 if ((colno & ATTR_BLINK) != 0 && color[CTBL_BLINK] != 0) {
834 sprintf(strlastp(attrbuf), ";%d", color[CTBL_BLINK]);
835 }
836 if ((colno & ATTR_REVERSE) != 0 && color[CTBL_REVERSE] != 0) {
837 sprintf(strlastp(attrbuf), ";%d", color[CTBL_REVERSE]);
838 }
839 strcat(attrbuf, "m");
840 #else /* _T_MSDOS || _T_UNIX || _T_WIN32CONSOLE */
841 if ((colno & ATTR_HIGHLIGHT) != 0 && color[CTBL_HIGHLIGHT] != 0) {
842 sprintf(strlastp(attrbuf), "%d;", color[CTBL_HIGHLIGHT]);
843 }
844 if ((colno & ATTR_BLINK) != 0 && color[CTBL_BLINK] != 0) {
845 sprintf(strlastp(attrbuf), "%d;", color[CTBL_BLINK]);
846 }
847 if ((colno & ATTR_REVERSE) != 0 && color[CTBL_REVERSE] != 0) {
848 sprintf(strlastp(attrbuf), "%d;", color[CTBL_REVERSE]);
849 }
850 sprintf(strlastp(attrbuf), "%dm", color[colno & CTBL_COLORMASK]);
851 #endif
852 return (attrbuf);
853 }
854
855 /*
856 * ���ꥨ�顼����
857 */
memerr(const char * func)858 void memerr(const char *func)
859 {
860 errprint(func, ERR_PANIC, "virtual memory exhausted, program stop.");
861 terminate_program(TERM_MEMERROR);
862 }
863
864 /*
865 * �¹���Υ��顼ɽ��
866 *
867 * func: �¹Դؿ�̾
868 * level: ���顼��٥� (information, warning, debug, error, panic)
869 * fmt: ���顼��å�����
870 */
errprint(const char * func,int level,const char * fmt,...)871 void errprint(const char *func, int level, const char *fmt, ...)
872 {
873 static const char *statname[] = {
874 "warning", "debug", "error", "panic",
875 };
876 va_list ap;
877
878 va_start(ap, fmt);
879
880 fprintf(stderr, "calendar: %s");
881 if (level != ERR_INFO) {
882 fprintf(stderr, "%s: ", statname[level - ERR_WARN]);
883 }
884 if (func != NULL) {
885 fprintf(stderr, "%s: ", func);
886 }
887 vfprintf(stderr, fmt, ap);
888 fprintf(stderr, "\n");
889
890 va_end(ap);
891 }
892
893 /*
894 * �����ѥХåե��ν����
895 */
896 static
clear_buffer(void)897 void clear_buffer(void)
898 {
899 memset(linebuffer, '\0', sizeof(linebuffer));
900 }
901
902 /*
903 * ���ϥХåե���ʸ����(fmt)���ɲä���
904 */
905 static
add_buffer(const char * fmt,...)906 void add_buffer(const char *fmt, ...)
907 {
908 char *lp;
909 va_list ap;
910
911 lp = strlastp(linebuffer);
912 va_start(ap, fmt);
913 vsprintf(lp, fmt, ap);
914 va_end(ap);
915 }
916
917 /*
918 * ���ϥХåե������Ƥ����(stdout)�˽��Ϥ���
919 */
920 static
flush_buffer(void)921 void flush_buffer(void)
922 {
923 if (linebuffer[0] == '\0') {
924 return ;
925 }
926
927 puts(linebuffer);
928 clear_buffer();
929 }
930
931 /*
932 * ���顼�ˤ��ץ�������ǽ���
933 */
terminate_program(int sig)934 void terminate_program(int sig)
935 {
936 switch (sig) {
937 case TERM_MEMERROR:
938 exit(1);
939 break;
940 }
941 exit(99);
942 }
943