1 /*
2  * misc.c -- miscellaneous
3  *
4  * Copyright (C) 1989,1999,2003 by Yoshifumi Mori
5  *
6  * tab:4
7  */
8 
9 #include "cdefs.h"
10 #include "extern.h"
11 
12 #ifndef INCLUDE_CALENDAR
13 #define MAXTBL_SUFFIX		64	/* ������ ��Ͽ�� */
14 #define DEFAULT_SUFFIXLEN	64	/* ������Хåե��ǥե���ȥ����� */
15 
16 #define SWAP(a,b)	{ int tmp_value; tmp_value = a; a = b; b = tmp_value; }
17 #endif /* !INCLUDE_CALENDAR */
18 
19 #define MAX_ERANAME			8	/* ����κ���ʸ����(������4ʸ���ޤ�) */
20 #define MAX_SPHOLIDAY		2	/* �ü������ */
21 
22 struct ERATBL {
23 	char				nameofera[((MAX_ERANAME + 2) + 1) & ~1];
24 									/* ����ϴ�����2ʸ�� */
25 	char				symbol[2];	/* ά���� */
26 	struct DATE_T		begin;
27 	struct DATE_T		end;
28 	struct ERATBL FAR	*next;
29 };
30 
31 struct HOLIDAYTBL {
32 	int				yy1;	/* ����ǯ */
33 	int				yy2;	/* ��λǯ */
34 	int				mm;		/* �� */
35 	int				dd;		/* �� */
36 	int				week;	/* ���� */
37 	const char FAR	*name;	/* ̾�� */
38 };
39 
40 static int	gengo_loading_flag = FALSE;
41 static struct ERATBL FAR	*gengo_first_tbl = NULL;
42 
43 const char	*gengo_file = "gengo.tbl";
44 const char	*holiday_file = "holiday.tbl";
45 
46 #ifndef INCLUDE_CALENDAR
47 const char	*flower_file = "flower.tbl";
48 
49 unsigned int	holiday_tbl[MAX_DAYOFMONTH * MAX_MONTH_TBL];
50 
51 char	*suffix_file;
52 static char FAR	*tbl_suffix[MAXTBL_SUFFIX][2];
53 static int	tbl_suffix_cnt = 0;
54 static char	*suffix_bufptr[2] = { NULL, NULL };
55 static int	suffix_buflen[2] = { 0, 0 };
56 static const char	*defSuffix[2] = { "�Ǥ�", "�Ǥ���" };
57 #endif /* !INCLUDE_CALENDAR */
58 
59 int	mkfile_status;
60 
61 static int	max_holiday;
62 static struct HOLIDAYTBL FAR	*holidayTbl = NULL;
63 static long	spHolspanJDTbl[MAX_SPHOLIDAY][2];
64 
65 /*
66  * ��ǯ��Ƚ��
67  *
68  * return value:
69  *   0 ʿǯ
70  *   1 ��ǯ
71  */
isleap(int year)72 int isleap(int year)
73 {
74 	return ((year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0));
75 }
76 
77 /*
78  * ���������
79  */
GetDayofWeek(int year,int month,int day)80 int GetDayofWeek(int year, int month, int day)
81 {
82 	if (month < 3) {
83 		year--;
84 		month += 12;
85 	}
86 	return ((year + year / 4 - year / 100 + year / 400 + (month * 13 + 8) / 5 + day) % 7);
87 }
88 
89 /*
90  * ������������
91  */
GetDayofMonth(int year,int month)92 int GetDayofMonth(int year, int month)
93 {
94 	static const char	days_per_month[12] = {
95 		31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
96 	};
97 	int	dayofmonth;
98 
99 	if (month < 1 || month > 12) {
100 		return (-1);
101 	}
102 
103 	dayofmonth = (int)days_per_month[month - 1];
104 	if (month == 2) {
105 		dayofmonth += isleap(year);
106 	}
107 	return (dayofmonth);
108 }
109 
110 #ifndef INCLUDE_CALENDAR
111 /*
112  * ǯƬ������̻��������
113  * 1��1���� 1
114  */
GetDayofYear(int year,int month,int day)115 int GetDayofYear(int year, int month, int day)
116 {
117 	static const short	daycount[12] = {
118 		0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
119 	};
120 	int	dayofyear;
121 
122 	if (month < 1 || month > 12) {
123 		return (-1);
124 	}
125 
126 	dayofyear = (int)daycount[month - 1] + day;
127 	if (month > 2) {
128 		dayofyear += isleap(year);
129 	}
130 
131 	return (dayofyear);
132 }
133 #endif /* !INCLUDE_CALENDAR */
134 
135 /*
136  * ��ꥦ�����������
137  */
Julian(int year,int month,int day)138 long Julian(int year, int month, int day)
139 {
140 #if 0
141 #define JULIAN	1720994
142 #define MONTH	30.6001
143 #define YEAR	365.25
144 
145 	int	yy, mm;
146 	int	tmp;
147 
148 	yy = year;
149 	mm = month;
150 	if (month < 3) {
151 		yy--;
152 		mm += 12;
153 	}
154 	if ((year < 1582) || (year == 1582 && month < 10) ||
155 	    ((year == 1582 && month == 10) && day <= 4)) {
156 		tmp = 0;	/* ��ꥦ���� */
157 	} else if ((year == 1582 && month == 10) && day < 15) {
158 		errprint("Julian", ERR_ERROR, "DATE %d/%02d/%02d: ����¸�ߤ��ޤ���", year, month, day);
159 		return (0L);	/* ���ܤ�1872ǯ�˲��� */
160 	} else {
161 		tmp = 2 - (yy / 100) + (yy / 100) / 4;	/* ���쥴�ꥪ�� */
162 	}
163 	return (JULIAN + (int)(MONTH * (mm + 1)) + (long)(YEAR * yy) + day + tmp);
164 #else
165 	/*
166 	 * �Խ�ŵ��
167 	 *  ALGORITHM 199
168 	 *  CONVERSIONS BETWEEN CALENDAR DATE AND JULIAN DAY NUMBER
169 	 *  Robert G. Tantzen
170 	 *  Air Force Missile Development Center, Holloman AFB, New Mex.
171 	 *
172 	 *  ��COLLECTED ALGORITHMS FROM ACM Volume I Algorithms 1-220��
173 	 *  Copyright (C) 1980, Association for Computing Machinery, Inc.
174 	 *  ISBN: 0-89791-017-6
175 	 *
176 	 *  �嵭���르�ꥺ��ΰ����μ������(1721119 -> 1721118)���ѹ���
177 	 */
178 	div_t	c;
179 	int		t;
180 
181 	month -= 3;
182 	if (month < 0) {
183 		month += 12;
184 		year--;
185 	}
186 	c = div(year, 100);
187 	t = (153 * month + 2) / 5 + day;
188 	return (((146097L * c.quot) >> 2L) + ((1461L * c.rem) >> 2L) + t + 1721118L);
189 #endif
190 }
191 
192 #ifndef INCLUDE_CALENDAR
193 /*
194  * ����(������)��2�Ĥ����դκ�(��ñ��;����)����� DATE2 - DATE1
195  */
GetDiffLCDate(int year2,int month2,int day2,int leap2,int year1,int month1,int day1,int leap1)196 int GetDiffLCDate(int year2, int month2, int day2, int leap2, int year1, int month1, int day1, int leap1)
197 {
198 	const struct DATE_T	*date;
199 	long	jd;
200 
201 	date = LunarToNowCalendar(year1, month1, day1, leap1);
202 	if (date == NULL) {
203 		goto err_return;
204 	}
205 	jd = Julian(date->year, date->month, date->day);
206 
207 	date = LunarToNowCalendar(year2, month2, day2, leap2);
208 	if (date == NULL) {
209 err_return:;
210 		errprint("GetDiffLCDate", ERR_ERROR, "���ݡ����ϰϥ����С��Ǥ�");
211 		return (0);
212 	}
213 
214 	return ((int)(Julian(date->year, date->month, date->day) - jd));
215 }
216 
217 /*
218  * ���դ����ʬ���ʤ��(�᤹)
219  */
date_inc(struct DATE_T * date,int offset)220 void date_inc(struct DATE_T *date, int offset)
221 {
222 	int	year, month, day;
223 	int	daycnt;
224 
225 	year = date->year;
226 	month = date->month;
227 	day = date->day + offset;
228 
229 	while (day > (daycnt = GetDayofMonth(year, month))) {
230 		day -= daycnt;
231 		if (++month > 12) {
232 			year++;
233 			month = 1;
234 		}
235 	}
236 	while (day < 1) {
237 		if (--month < 1) {
238 			year--;
239 			month = 12;
240 		}
241 		day += GetDayofMonth(year, month);
242 	}
243 
244 	date->year = year;
245 	date->month = month;
246 	date->day = day;
247 	date->dayofweek = GetDayofWeek(year, month, day);
248 }
249 #endif /* !INCLUDE_CALENDAR */
250 
251 /*
252  * ���դ��ɤ߼��
253  *
254  * fmt : ���եե����ޥåȻ���(bitmap)
255  *    00000001 - YY / MM / DD
256  *    00000010 - YY / MM / **
257  *    00000100 - YY / ** / DD
258  *    00001000 - YY / ** / **
259  *    00010000 - ** / MM / DD
260  *    00100000 - ** / MM / **
261  *    01000000 - ** / ** / DD
262  *    10000000 - ** / ** / **
263  *
264  *   100000000 - DD �����������ǽ (ex. Sun, 2Mon)
265  *
266  * return value:
267  *   DATE_OK ���ェλ
268  *   DATE_NG �ե����ޥåȤ��۾�
269  *
270  * wflag = TRUE �������(NULL�����ǽ)
271  */
read_date(int fmt,char * bp,struct DATE_T * date,int * wflag)272 int read_date(int fmt, char *bp, struct DATE_T *date, int *wflag)
273 {
274 	static const char	*montbl = "JanFebMarAprMayJunJulAugSepOctNovDec";
275 	static const char	*weektbl = "SunMonTueWedThuFriSat";
276 	char	*lasts = NULL;
277 	char	*pp;
278 	char	*q;
279 	int		i;
280 	int		bit;
281 
282 	pp = strtok_r(bp, "/", &lasts);
283 	if (pp == NULL) {
284 		return (DATE_NG);
285 	}
286 	if (analysis_year(pp, &(date->year), wflag) == YEAR_NG) {
287 		return (DATE_NG);
288 	}
289 	pp = strtok_r(NULL, "/", &lasts);
290 	if (pp == NULL) {
291 		return (DATE_NG);
292 	}
293 	if (*pp == '*') {
294 		date->month = 0;
295 	} else if (isdigit(*pp) != 0) {
296 		date->month = atoi(pp);
297 		if (date->month < 0 || date->month > 12) {
298 			return (DATE_NG);
299 		}
300 	} else {
301 		for (i = 0; i < 12; i++) {
302 			if (strnicmp(pp, &montbl[i * 3], 3) == 0) {
303 				date->month = i + 1;
304 				break;
305 			}
306 		}
307 		if (i >= 12) {
308 			return (DATE_NG);
309 		}
310 	}
311 	pp = strtok_r(NULL, "", &lasts);
312 	if (pp == NULL) {
313 		return (DATE_NG);
314 	}
315 	if (*pp == '*') {
316 		date->day = 0;
317 	} else {
318 		date->day = (int)strtol(pp, &q, 10);
319 		if (*q != '\0') {
320 			for (i = 0; i < 7; i++) {
321 				if (strnicmp(q, &weektbl[i * 3], 3) == 0) {
322 					if (date->day < 0) {
323 						date->day = -date->day + 5;
324 					}
325 					date->day = -((i + 1) + date->day * 10 + 100);
326 					break;
327 				}
328 			}
329 			if ((fmt & 0x0100) == 0 || i >= 7) {
330 				return (DATE_NG);
331 			}
332 		}
333 	}
334 
335 	bit = 0;
336 	if (date->year == 0) {
337 		bit |= 4;
338 	}
339 	if (date->month == 0) {
340 		bit |= 2;
341 	}
342 	if (date->day == 0) {
343 		bit |= 1;
344 	}
345 
346 	date->dayofweek = 0;
347 
348 	return ((fmt & (1 << bit)) ? DATE_OK : DATE_NG);
349 }
350 
351 /*
352  * ǯ����ǧ���ͤ�����
353  *
354  * return value:
355  *   YEAR_OK ǯ�椬����
356  *   YEAR_NG ǯ�椬�۾�
357  *
358  * wflag = TRUE �������(NULL�����ǽ)
359  */
analysis_year(const char * p,int * year,int * wflag)360 int analysis_year(const char *p, int *year, int *wflag)
361 {
362 	struct ERATBL FAR	*era_tbl;
363 	int	c1, c2;
364 
365 	if (wflag != NULL) {
366 		*wflag = FALSE;
367 	}
368 
369 	if (isdigit((unsigned char)*p) != 0 ||
370 	    (p[0] == '-' && isdigit((unsigned char)p[1]) != 0)) {
371 		*year = atoi(p);
372 		return (YEAR_OK);
373 	}
374 	/* B.C. ������              before Christ */
375 	/* A.D. ���ꥹ�ȵ�����,���� anno Domini */
376 	c1 = tolower(p[0]);
377 	c2 = tolower(p[1]);
378 	if ((c1 == 'b' && c2 == 'c') || (c1 == 'a' && c2 == 'd')) {
379 		int	bc_flag = FALSE;
380 		int	y;
381 
382 		if (c1 == 'b') {
383 			bc_flag = TRUE;
384 		}
385 		y = atoi(p + 2);
386 		if (bc_flag == TRUE) {
387 			y = -y;
388 		}
389 		*year = y;
390 		return (YEAR_OK);
391 	}
392 
393 	if (p[0] == '?' || p[0] == '*') {	/* ???? -> 0 */
394 		*year = 0;
395 		return (YEAR_OK);
396 	}
397 
398 	if (gengo_loading_flag == FALSE) {
399 		return (YEAR_NG);
400 	}
401 
402 	/* �����ά����ˤ���Ѵ� */
403 	era_tbl = gengo_first_tbl;
404 	while (era_tbl != NULL) {
405 		if (*p == era_tbl->symbol[0] || *p == era_tbl->symbol[1]) {
406 			*year = atoi(p + 1) + era_tbl->begin.year - 1;
407 			if (wflag != NULL) {
408 				*wflag = TRUE;
409 			}
410 			return (YEAR_OK);
411 		}
412 		era_tbl = era_tbl->next;
413 	}
414 
415 	return (YEAR_NG);
416 }
417 
418 #ifndef INCLUDE_CALENDAR
419 /*
420  * ��������ˡ����Ϥ��������ơ��֥�����ꤹ��
421  *
422  * return value:
423  *   TRUE  �����Ȥ���
424  *   FALSE �����Ȥ��ʤ�
425  */
analysis_sortorder(const char * type,const char * string,int * sortorder_tbl,int org_sortflag)426 int analysis_sortorder(const char *type, const char *string, int *sortorder_tbl, int org_sortflag)
427 {
428 	static const char	*statname[MAXSORTITEM] = {
429 		"����", "����", "����",
430 	};
431 	int		statflag[MAXSORTITEM];
432 	int		i;
433 	char	*sp;
434 	char	*lasts;
435 	const char	*ip;
436 	const char	*sep_str = "_ ,/-:";
437 
438 	if (string == NULL || *string == '\0') {
439 		return (org_sortflag);
440 	}
441 
442 	if (strcmp(string, "�ʤ�") == 0) {
443 		return (FALSE);
444 	}
445 
446 	for (i = 0; i < MAXSORTITEM; i++) {
447 		sortorder_tbl[i] = UNUSE;
448 		statflag[i] = UNUSE;
449 	}
450 	sp = xstrdup(string);
451 
452 	lasts = NULL;
453 	ip = strtok_r(sp, sep_str, &lasts);
454 	for (i = 0; ip != NULL && i < MAXSORTITEM; ) {
455 		int	j;
456 		int	hit_flag = FALSE;
457 
458 		for (j = 0; j < MAXSORTITEM; j++) {
459 			if (strcmp(ip, statname[j]) == 0) {
460 				hit_flag = TRUE;
461 				if (statflag[j] == UNUSE) {
462 					sortorder_tbl[i] = j;
463 					statflag[j] = i;
464 					i++;
465 					break;
466 				} else {
467 					errprint(type, ERR_ERROR, "%s_sort = %s, duplicate %s", type, string, ip);
468 				}
469 			}
470 		}
471 
472 		if (hit_flag == FALSE) {
473 			errprint(type, ERR_ERROR, "%s_sort = %s, unknown %s", type, string, ip);
474 		}
475 
476 		ip = strtok_r(NULL, sep_str, &lasts);
477 	}
478 
479 	free(sp);
480 	return (TRUE);
481 }
482 #endif /* !INCLUDE_CALENDAR */
483 
484 #if !defined(INCLUDE_CALENDAR) || (defined(INCLUDE_CALENDAR) && defined(_T_WINDOWS))
485 /*
486  * '_' �� ' ' ���Ѵ�����
487  */
undertospace(char * chrptr)488 char *undertospace(char *chrptr)
489 {
490 	unsigned char	*p;
491 
492 #if defined(_T_MSDOS)
493 #define _INT	unsigned short
494 #endif
495 #if defined(_T_HUMAN68K) || defined(_T_UNIX) || defined(_T_WIN32CONSOLE) || defined(_T_WINDOWS)
496 #define _INT	int
497 #endif
498 
499 	p = (unsigned char *)chrptr;
500 	while ((p = jstrchr(p, (_INT)'_')) != '\0') {
501 		*p = ' ';
502 	}
503 	return (chrptr);
504 }
505 #endif /* !INCLUDE_CALENAR || (INCLUDE_CALENDAR && _T_WINDOWS) */
506 
507 /*
508  * ʸ����κǸ�ޤǥ����åפ������ΰ��֤��֤�
509  */
strlastp(char * p)510 char *strlastp(char *p)
511 {
512 	while (*p != '\0') {
513 		p++;
514 	}
515 
516 	return (p);
517 }
518 
519 /*
520  * �����Ѵ��ơ��֥���ɤ߹���
521  *
522  * use file: gengo.tbl
523  *
524  * file format:
525  *   gengo year/month/day year/month/day sc
526  *
527  * return value:
528  *   LOAD_OK �ɤ߹�������
529  *   LOAD_NG ���顼ȯ��
530  */
Loading_GengoTbl(void)531 int Loading_GengoTbl(void)
532 {
533 	struct ERATBL FAR	*now_tbl;
534 	char	*bp;
535 	char	*lasts;
536 
537 	if (gengo_loading_flag == TRUE) {
538 		return (LOAD_OK);
539 	}
540 
541 	if (openfile(gengo_file)) {
542 		return (LOAD_NG);
543 	}
544 
545 	now_tbl = NULL;
546 	while ((bp = getfile()) != NULL) {
547 		struct DATE_T	rdate;
548 		struct ERATBL FAR	*p;
549 
550 		lasts = NULL;
551 		bp = strtok_r(bp, fmt_sep3, &lasts);
552 		if (bp == NULL) {
553 			continue;
554 		}
555 		p = (struct ERATBL FAR *)XMALLOC(sizeof(struct ERATBL));
556 		FMEMSET(p, '\0', sizeof(struct ERATBL));
557 #if 0	/* memset �ǥ��ꥢ���Ƥ��뤫���פ�ʤ� */
558 		p->next = NULL;
559 #endif
560 		FSTRNCPY(p->nameofera, (char FAR *)bp, MAX_ERANAME);
561 
562 		bp = strtok_r(NULL, fmt_sep3, &lasts);
563 		if (bp == NULL ||
564 		    read_date(0x01, bp, &rdate, NULL) == DATE_NG) {
565 free_mem:
566 			XFREE(p);
567 			continue;
568 		}
569 		rdate.dayofweek = 0;
570 		p->begin = rdate;
571 
572 		bp = strtok_r(NULL, fmt_sep3, &lasts);
573 		if (bp == NULL ||
574 		    read_date(0x81, bp, &rdate, NULL) == DATE_NG) {
575 			goto free_mem;
576 		}
577 		rdate.dayofweek = 0;
578 		p->end = rdate;
579 
580 		bp = strtok_r(NULL, fmt_sep3, &lasts);
581 		if (bp != NULL) {
582 			FSTRNCPY(p->symbol, (char FAR *)bp, 2);
583 		}
584 
585 		if (gengo_first_tbl == NULL) {
586 			gengo_first_tbl = p;
587 		} else {
588 			now_tbl->next = p;
589 		}
590 		now_tbl = p;
591 	}
592 
593 	closefile();
594 
595 	if (gengo_first_tbl == NULL) {
596 		return (LOAD_NG);
597 	}
598 	gengo_loading_flag = TRUE;
599 
600 	return (LOAD_OK);
601 }
602 
603 #ifndef INCLUDE_CALENDAR
604 /*
605  * ����̾�����ܸ�/�Ѹ���֤�
606  */
GetNameofWhatday(int languagetype,int dayofweek)607 const char *GetNameofWhatday(int languagetype, int dayofweek)
608 {
609 	static const char	*name_e_dayofweek[7] = {
610 		"Sunday",   "Monday", "Tuesday", "Wednesday",
611 		"Thursday", "Friday", "Saturday",
612 	};
613 	static const char	*name_j_dayofweek = "����п��ڶ���";
614 	static char	buf[8];
615 
616 	dayofweek %= 7;
617 
618 	if (languagetype == LANG_J) {
619 		memset(buf, '\0', sizeof(buf));
620 		strncpy(buf, &name_j_dayofweek[dayofweek * 2], 2);
621 		strcat(buf, "����");
622 		return (buf);
623 	}
624 
625 	return (name_e_dayofweek[dayofweek]);
626 }
627 
628 /*
629  * ����(����)�����
630  *
631  * languagetype = LANG_J:����̾, LANG_E:ά��(����ʸ��)
632  *
633  * ����ξ��ϸ���̾���֤�
634  * ���顼�ξ��� NULL ���֤�
635  * wareki �� 0 �˽���������Τ����
636  */
GetNameofEra(int languagetype,int year,int month,int day,int * wareki)637 const char *GetNameofEra(int languagetype, int year, int month, int day, int *wareki)
638 {
639 	static char	erabuf[((MAX_ERANAME + 2) + 1) & ~1];
640 	struct ERATBL FAR	*p;
641 
642 	*wareki = 0;
643 
644 	if (gengo_loading_flag == FALSE) {
645 		return (NULL);
646 	}
647 
648 	p = gengo_first_tbl;
649 	do {
650 		if (year > p->begin.year ||
651 		    (year == p->begin.year &&
652 		     (month > p->begin.month || (month == p->begin.month && day >= p->begin.day)))) {
653 			if (p->end.year == 0 || year < p->end.year ||
654 			    (year == p->end.year &&
655 			     (month < p->end.month || (month == p->end.month && day <= p->end.day)))) {
656 				*wareki = year - p->begin.year + 1;
657 				switch (languagetype) {
658 				case LANG_J:	/* ����̾ */
659 				default:
660 					FSTRNCPY((char FAR *)erabuf, p->nameofera, MAX_ERANAME);
661 					break;
662 				case LANG_E:	/* ά��(����ʸ��) */
663 					if (isalpha(p->symbol[0]) != 0) {
664 						erabuf[0] = toupper(p->symbol[0]);
665 					} else {
666 						erabuf[0] = '?';
667 					}
668 					erabuf[1] = '\0';
669 					break;
670 				}
671 				return (erabuf);
672 			}
673 		}
674 		p = p->next;
675 	} while (p != NULL);
676 
677 	return (NULL);
678 }
679 #endif /* !INCLUDE_CALENDAR */
680 
681 /*
682  * ���̾�������ܸ�/�Ѹ���֤�
683  */
GetNameofMonth(int languagetype,int month)684 const char *GetNameofMonth(int languagetype, int month)
685 {
686 	static const char	*monthname[2][12] = {
687 		{ "�ӷ�", "ǡ��",   "����", "����",
688 		  "����", "��̵��", "ʸ��", "�շ�",
689 		  "Ĺ��", "��̵��", "����", "����" },
690 		{ "January", "February", "March",
691 		  "April",   "May",      "June",
692 		  "July",    "August",   "September",
693 		  "October", "November", "December" }
694 	};
695 
696 	if (month < 1 || month > 12) {
697 		return (NULL);
698 	}
699 
700 	return (monthname[languagetype][month - 1]);
701 }
702 
703 #ifndef INCLUDE_CALENDAR
704 /*
705  * ������̾���֤�
706  */
GetNameofBirthstone(int month)707 const char *GetNameofBirthstone(int month)
708 {
709 	static const char	*stonetable[12] = {
710 		"��������",        "��徽",       "����,����",
711 		"���������",    "�������",   "����,��Ĺ��",
712 		"��ӡ�",          "�֤��ޤ�Τ�", "���ե�����",
713 		"���ѡ���,�ŵ���", "�ȥѡ���",     "�ȥ륳��,���륳��",
714 	};
715 
716 	if (month < 1 || month > 12) {
717 		return (NULL);
718 	}
719 
720 	return (stonetable[month - 1]);
721 }
722 
723 /*
724  * ������β֤�̾�����֤�
725  */
GetNameofBirthflowers(int month)726 const char *GetNameofBirthflowers(int month)
727 {
728 	static const char	*flowerstable[12] = {
729 		"�����͡������,���Ρ��ɥ�å�",
730 		"���ߥ�,�����饽��",
731 		"����������,���ߥ�",
732 		"�ҥʥ���,�������ȥԡ�",
733 		"������,�������",
734 		"�Х�,����������",
735 		"�ҥ�����,�������",
736 		"���饸���饹,����",
737 		"��������,������",
738 		"������,�����⥹",
739 		"����",
740 		"��������,�����襦�ҥ��饮,�ݥ�������",
741 	};
742 
743 	if (month < 1 || month > 12) {
744 		return (NULL);
745 	}
746 
747 	return (flowerstable[month - 1]);
748 }
749 
750 /*
751  * ����̾���֤�
752  */
GetNameofConstellation(int month,int day)753 const char *GetNameofConstellation(int month, int day)
754 {
755 	struct DATE_MD_T {
756 		char	month;
757 		char	day;
758 	};
759 	static const struct CONSTELLATION {
760 		struct DATE_MD_T	begin;			/* ���Ϸ��� */
761 		struct DATE_MD_T	end;			/* ��λ���� */
762 		const char			*constel;	/* ����̾ */
763 	} consteltable[12] = {
764 		{ {  3, 21 }, {  4, 20 }, "���Ӻ�" },
765 		{ {  4, 21 }, {  5, 21 }, "�����" },
766 		{ {  5, 22 }, {  6, 21 }, "�лҺ�" },
767 		{ {  6, 22 }, {  7, 23 }, "����"   },
768 		{ {  7, 24 }, {  8, 23 }, "��Һ�" },
769 		{ {  8, 24 }, {  9, 23 }, "������" },
770 		{ {  9, 24 }, { 10, 23 }, "ŷ���" },
771 		{ { 10, 24 }, { 11, 22 }, "긺�"   },
772 		{ { 11, 23 }, { 12, 22 }, "�ͼ��" },
773 		{ { 12, 23 }, {  1, 20 }, "���Ӻ�" },
774 		{ {  1, 21 }, {  2, 19 }, "���Ӻ�" },
775 		{ {  2, 20 }, {  3, 20 }, "����"   }
776 	};
777 	int	i;
778 
779 	for (i = 0; i < 12; i++) {
780 		if ((month == (int)consteltable[i].begin.month && day >= (int)consteltable[i].begin.day) ||
781 		    (month == (int)consteltable[i].end.month && day <= (int)consteltable[i].end.day)) {
782 			return (consteltable[i].constel);
783 		}
784 	}
785 
786 	return (NULL);
787 }
788 
789 /*
790  * �������β֤�̾���Ȳָ��դ��֤�
791  *
792  * ����ξ��ϡ���¤�� flower ���ͭ����ʸ��������
793  * ���顼�ξ��ϡ���¤�� flower ��� '\0' ��ؤ��Ƥ���
794  *
795  * use file: flower.tbl
796  *
797  * file format:
798  *   month day name language
799  */
GetLanguageofFlower(int month,int day)800 const struct FLOWER_T *GetLanguageofFlower(int month, int day)
801 {
802 #define MAXFLOWERNAME	64	/* �֤�̾�����ָ��եХåե� */
803 	static char	namebuf[MAXFLOWERNAME];
804 	static char	langbuf[MAXFLOWERNAME];
805 	static const struct FLOWER_T	flower = { namebuf, langbuf };
806 	char	*bp;
807 	char	*lasts;
808 
809 	memset(namebuf, '\0', sizeof(namebuf));
810 	memset(langbuf, '\0', sizeof(langbuf));
811 
812 	if (openfile(flower_file)) {
813 		return (&flower);
814 	}
815 
816 	while ((bp = getfile()) != NULL) {
817 		lasts = NULL;
818 		bp = strtok_r(bp, fmt_sep1, &lasts);
819 		if (bp == NULL || month != atoi(bp)) {
820 			continue;
821 		}
822 
823 		bp = strtok_r(NULL, fmt_sep3, &lasts);
824 		if (bp == NULL || day != atoi(bp)) {
825 			continue;
826 		}
827 
828 		bp = strtok_r(NULL, fmt_sep3, &lasts);
829 		if (bp == NULL) {
830 			continue;
831 		}
832 		strncpy(namebuf, bp, sizeof(namebuf) - 1);
833 
834 		bp = strtok_r(NULL, fmt_sep3, &lasts);
835 		if (bp == NULL) {
836 			continue;
837 		}
838 		strncpy(langbuf, bp, sizeof(langbuf) - 1);
839 
840 		break;
841 	}
842 
843 	closefile();
844 
845 	return (&flower);
846 }
847 
848 /*
849  * ���֤˱�������å��������֤�
850  */
GetTimemessage(int hour)851 const char *GetTimemessage(int hour)
852 {
853 	static const char	*timemessage[4] = {
854 		"���Ϥ褦�������ޤ�" MSG_PERIOD,		/* 0 */
855 		"����ˤ���" MSG_PERIOD,				/* 1 */
856 		"����Ф��" MSG_PERIOD,				/* 2 */
857 		"���Ф���ϫ�ͤǤ�" MSG_PERIOD,		/* 3 */
858 	};
859 	static const unsigned char	time_tbl[24] = {
860 		3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 1, 1,	/* ���ܸ�  0�� �� 11�� */
861 		1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3,	/*        12�� �� 23�� */
862 	};
863 
864 	return (timemessage[time_tbl[hour % 24]]);
865 }
866 
867 /*
868  * ������ơ��֥���ɤ߹���
869  *
870  * file format:
871  *   suffix_now:suffix_past
872  *
873  * return value:
874  *   LOAD_OK �ɤ߹�������
875  *   LOAD_NG ���顼ȯ��
876  */
Loading_SuffixTbl(void)877 int Loading_SuffixTbl(void)
878 {
879 	char		*half[2];
880 	char FAR	*p;
881 	int			i;
882 
883 	for (i = 0; i < 2; i++) {
884 		if (suffix_buflen[i] == 0) {
885 			suffix_buflen[i] = DEFAULT_SUFFIXLEN;
886 			suffix_bufptr[i] = xmalloc(suffix_buflen[i]);
887 		}
888 	}
889 
890 	if (suffix_file == NULL) {
891 		return (LOAD_OK);
892 	}
893 
894 	if (openfile(suffix_file)) {
895 		return (LOAD_NG);
896 	}
897 
898 	while ((half[0] = getfile()) != NULL && tbl_suffix_cnt < MAXTBL_SUFFIX) {
899 		half[1] = (char *)jstrchr((unsigned char *)half[0], ':');
900 		if (half[1] == NULL) {
901 			continue;
902 		}
903 		*half[1]++ = '\0';
904 		for (i = 0; i < 2; i++) {
905 			int	slen;
906 
907 			slen = strlen(strip(half[i])) + 1;
908 			p = XMALLOC(slen);
909 			tbl_suffix[tbl_suffix_cnt][i] = p;
910 			FSTRCPY(p, (char FAR *)half[i]);
911 
912 			if (slen > suffix_buflen[i]) {
913 				free(suffix_bufptr[i]);
914 				suffix_bufptr[i] = xmalloc(slen);
915 				suffix_buflen[i] = slen;
916 			}
917 		}
918 		tbl_suffix_cnt++;
919 	}
920 
921 	closefile();
922 
923 	return (LOAD_OK);
924 }
925 
926 /*
927  * �ǥե���Ȥ���������֤�
928  *
929  * type = 0:���߷�
930  *        1:����
931  *
932  * Notice_Message() �ȥХåե� suffix_bufptr[] ��
933  * ��ͭ���Ƥ���ΤǸƤӽФ��ˤ���դ�ɬ��
934  */
GetDefaultSuffix(int type)935 const char *GetDefaultSuffix(int type)
936 {
937 	const char FAR	*sp;
938 	int	slen;
939 
940 	type &= 1;
941 	if (tbl_suffix_cnt == 0) {
942 		return (defSuffix[type]);
943 	}
944 
945 	/*
946 	 * ���Ѥ���������� suffix_bufptr[] �����ꤹ��
947 	 * ������κǸ�� . ���դ��Ƥ�����������ä�
948 	 */
949 	sp = tbl_suffix[0][type];
950 	slen = FSTRLEN(sp);
951 	if (slen != 0 && sp[slen - 1] == '.') {
952 		*suffix_bufptr[type] = '\0';
953 	} else {
954 		FSTRCPY((char FAR *)suffix_bufptr[type], sp);
955 	}
956 
957 	return (suffix_bufptr[type]);
958 }
959 
960 /*
961  * ��å��������������ơ��֥��긡������
962  * ��������������� suffix_bufptr[] �˥��ԡ�����
963  */
964 static
check_suffix(char * word)965 void check_suffix(char *word)
966 {
967 	char		*wp;
968 	char		*wep;
969 	char FAR	*sp;
970 	int			i;
971 	int			wlen;
972 	int			slen;
973 	char		*find_ptr = NULL;
974 	int			find_index = -1;
975 	int			find_len = 0;
976 
977 	wep = strlastp(word);
978 	wlen = strlen(word);
979 
980 	for (i = 0; i < tbl_suffix_cnt; i++) {
981 		sp = tbl_suffix[i][0];
982 		slen = FSTRLEN(sp);
983 		if (slen != 0 && sp[slen - 1] == '.') {
984 			slen--;
985 		}
986 		if (wlen >= slen) {
987 			wp = wep - slen;
988 			/* ���Ĺ��ʸ����Ȥΰ��פ��ߤ� */
989 			if (slen > find_len &&
990 			    FSTRNCMP((char FAR *)wp, sp, slen) == 0) {
991 				find_ptr = wp;
992 				find_index = i;
993 				find_len = slen;
994 			}
995 		}
996 	}
997 
998 	/*
999 	 * �������ȯ�������餽��ʹߤ�������
1000 	 * Notice_Message ���������ƽи����֤����ƽи��Ƿ�礹�뤿��
1001 	 *
1002 	 * �����줬̵�����ϡ�������ơ��֥�κǽ���Ȥ߹�碌��
1003 	 * �����ƥ�Υǥե���Ȥ������쥻�åȤȤ��ƻ��Ѥ���
1004 	 */
1005 	if (find_index != -1) {
1006 		*find_ptr = '\0';	/* �������� */
1007 	} else {
1008 		if (tbl_suffix_cnt == 0) {
1009 			strcpy(suffix_bufptr[0], defSuffix[0]);
1010 			strcpy(suffix_bufptr[1], defSuffix[1]);
1011 			goto end_proc;
1012 		} else {
1013 			find_index = 0;	/* ������ơ��֥�κǽ���Ȥ߹�碌��Ȥ� */
1014 		}
1015 	}
1016 
1017 	/*
1018 	 * ���Ѥ���������� suffix_bufptr[] �����ꤹ��
1019 	 * ������κǸ�� . ���դ��Ƥ�����������ä�
1020 	 */
1021 	for (i = 0; i < 2; i++) {
1022 		sp = tbl_suffix[find_index][i];
1023 		slen = FSTRLEN(sp);
1024 		if (slen != 0 && sp[slen - 1] == '.') {
1025 			*suffix_bufptr[i] = '\0';
1026 		} else {
1027 			FSTRCPY((char FAR *)suffix_bufptr[i], sp);
1028 		}
1029 	}
1030 
1031 end_proc:;
1032 }
1033 
1034 /*
1035  * ����ͽ���å���������
1036  *
1037  * diffday: ����(��ñ��) ��������NOTICE_MONTH(0) ����礭�����Ϸ�ñ��
1038  */
Notice_Message(char * msg,int diffday,char ** end_msg)1039 const char *Notice_Message(char *msg, int diffday, char **end_msg)
1040 {
1041 #define MAXNOTICEBUF	32	/* ����ͽ���å������Хåե� */
1042 	static const char	*weeknum = "�������͸�ϻ��Ȭ��";
1043 	static char	buf[MAXNOTICEBUF];
1044 
1045 	check_suffix(msg);
1046 
1047 	*end_msg = suffix_bufptr[0];
1048 	memset(buf, '\0', sizeof(buf));
1049 
1050 	switch (diffday) {
1051 	case 0:
1052 		return ("������");
1053 	case -1:
1054 		*end_msg = suffix_bufptr[1];
1055 		return ("������");
1056 	case 1:
1057 		return ("������");
1058 	case 7:
1059 	case 14:
1060 	case 21:
1061 	case 28:
1062 		strncpy(buf, &weeknum[(diffday / 7) * 2], 2);
1063 		strcat(buf, "���ָ��");
1064 		break;
1065 	default:
1066 		if (diffday > NOTICE_MONTH(0)) {
1067 			strncpy(buf, &weeknum[(diffday - NOTICE_MONTH(0)) * 2], 2);
1068 #if 0
1069 			strcat(buf, "������");
1070 #else
1071 			strcat(buf, "������");
1072 #endif
1073 		} else {
1074 #if 0
1075 			char	tmp[4];
1076 			static const char	*numtbl = "��������������������";
1077 
1078 			if (diffday < 10) {
1079 				memset(tmp, '\0', sizeof(tmp));
1080 				strncpy(tmp, &numtbl[diffday * 2], 2);
1081 			} else {
1082 				sprintf(tmp, "%d", diffday);
1083 			}
1084 			sprintf(buf, "����%s����", tmp);
1085 #else
1086 			sprintf(buf, "����%d����", diffday);
1087 #endif
1088 		}
1089 		break;
1090 	}
1091 
1092 	return (buf);
1093 }
1094 
1095 /*
1096  * ���ߤ����դ����Ѥ��ƥե�����̾����
1097  *
1098  * call make_filename2()
1099  */
make_filename(const char * basename)1100 const char *make_filename(const char *basename)
1101 {
1102 	return (make_filename2(basename, calendar.year, calendar.month, calendar.day));
1103 }
1104 #endif /* !INCLUDE_CALENDAR */
1105 
1106 /*
1107  * �桼������������դ����Ѥ��ƥե�����̾����
1108  *
1109  * �ե�����̾��� %c, %y, %m, %d ��������
1110  * ���줾�졢������ǯ��������֤�������
1111  * %p �� �ץ���ID(5��) ���֤�������
1112  * ǯ�����Ȥ��2���ʸ�����Ѵ�, ǯ�ϲ���2��
1113  *
1114  * mkfile_status: %c, %y, %m, %d, %p ����Ѥ���ȥե饰������
1115  */
make_filename2(const char * basename,int year,int month,int day)1116 const char *make_filename2(const char *basename, int year, int month, int day)
1117 {
1118 	static char	fnamebuf[_T_MAXFNAMEBUF];
1119 	const char	*bp;
1120 	char		*dp;
1121 	int			cnt;
1122 
1123 	mkfile_status = 0;
1124 
1125 	bp = basename;
1126 	dp = fnamebuf;
1127 	cnt = sizeof(fnamebuf) - 1;
1128 	while (cnt > 0 && *bp != '\0') {
1129 		int	n;
1130 
1131 		if (*bp != '%') {
1132 			*dp++ = *bp++;
1133 			cnt--;
1134 			continue;
1135 		}
1136 		bp++;
1137 		switch (*bp) {
1138 		case '\0':
1139 			goto exit_loop;
1140 		case '%':
1141 			*dp++ = '%';
1142 			cnt--;
1143 			break;
1144 		case 'c':	/* year nnXX */
1145 			mkfile_status |= SET_MKF_CC;
1146 			n = year / 100;
1147 			goto store_2num;
1148 		case 'y':	/* year XXnn */
1149 			mkfile_status |= SET_MKF_YY;
1150 			n = year % 100;
1151 store_2num:
1152 			*dp++ = (char)(n / 10 + '0');
1153 			cnt--;
1154 			if (cnt <= 0) {
1155 				goto exit_loop;
1156 			}
1157 			*dp++ = (char)((n % 10) + '0');
1158 			cnt--;
1159 			break;
1160 		case 'm':	/* month nn */
1161 			mkfile_status |= SET_MKF_MM;
1162 			n = month;
1163 			goto store_2num;
1164 		case 'd':	/* day nn */
1165 			mkfile_status |= SET_MKF_DD;
1166 			n = day;
1167 			goto store_2num;
1168 		case 'p':	/* process id nnnnn */
1169 			{
1170 				char	pbuf[12];
1171 				const char	*pb;
1172 				int	i;
1173 
1174 				mkfile_status |= SET_MKF_PID;
1175 #if defined(_T_HUMAN68K)
1176 				sprintf(pbuf, "%06d", getpid() >> 4);
1177 				pb = pbuf + strlen(pbuf) - 5;
1178 #endif
1179 #if defined(_T_MSDOS) || defined(_T_UNIX)
1180 #ifndef __FreeBSD__
1181 				sprintf(pbuf, "%05d", getpid());
1182 #else
1183 				sprintf(pbuf, "%05ld", getpid());
1184 #endif
1185 				pb = pbuf;
1186 #endif
1187 #if defined(_T_WIN32CONSOLE) || defined(_T_WINDOWS)
1188 				sprintf(pbuf, "%05d", getpid() & 0xFFFF);
1189 				pb = pbuf;
1190 #endif
1191 				for (i = 0; i < 5; i++) {
1192 					if (*pb == '\0') {
1193 						break;
1194 					}
1195 					*dp++ = *pb++;
1196 					cnt--;
1197 					if (cnt <= 0) {
1198 						goto exit_loop;
1199 					}
1200 				}
1201 			}
1202 			break;
1203 		default:
1204 			*dp++ = '%';
1205 			cnt--;
1206 			if (cnt <= 0) {
1207 				goto exit_loop;
1208 			}
1209 			*dp++ = *bp;
1210 			cnt--;
1211 			break;
1212 		}
1213 		bp++;
1214 	}
1215 
1216 exit_loop:
1217 	*dp = '\0';
1218 
1219 	return (fnamebuf);
1220 }
1221 
1222 #ifndef INCLUDE_CALENDAR
1223 /*
1224  * ʸ�������Ƭ���ʸ�������ɤ���Ф�
1225  *
1226  * return value:
1227  *   ʸ��������
1228  *
1229  * int *byte;  ʸ�������ɤι����Х��ȿ�
1230  * int *width; ʸ�������ɤ�ʸ����
1231  *
1232  * ʸ�������ɤ��۾�ʾ��ϡ������Х��ȿ���ʸ������ 0 �ˤ���
1233  */
getcharcode(const unsigned char * ptr,int * byte,int * width)1234 unsigned int getcharcode(const unsigned char *ptr, int *byte, int *width)
1235 {
1236 #ifdef _T_SJIS
1237 	int	b, w;
1238 	unsigned int	c;
1239 
1240 	b = 0;
1241 	w = 0;
1242 	c = *ptr;
1243 	if (iskanji(c) != 0) {
1244 		int	c2;
1245 
1246 		c2 = *(ptr + 1);
1247 		if (iskanji2(c2) != 0) {
1248 			c = (c << 8) | c2;
1249 			b = 2;
1250 			w = 2;
1251 		}
1252 	} else {
1253 		b = 1;
1254 		w = 1;
1255 	}
1256 #endif /* _T_SJIS */
1257 #ifdef _T_EUC
1258 	int	b, w;
1259 	unsigned int	c;
1260 
1261 	b = 0;	/* skip bytes */
1262 	w = 0;	/* code width */
1263 	c = *ptr;
1264 	if (c == 0x8E) {	/* SS2 �����ɥ��å�2 */
1265 		int	c2;
1266 
1267 		c2 = *(ptr + 1);
1268 		if (c2 != '\0' && c2 >= 0xA0 && c2 <= 0xDF) {
1269 			c = (c << 8) | c2;
1270 			b = 2;
1271 			w = 1;
1272 		}
1273 	} else if (c == 0x8F) {	/* SS3 �����ɥ��å�3 */
1274 		int	c2, c3;
1275 
1276 		c2 = *(ptr + 1);
1277 		if (c2 != '\0' && c2 >= 0x80) {
1278 			c3 = *(ptr + 2);
1279 			if (c3 != '\0' && c3 >= 0x80) {
1280 				c = (c << 16) | (c2 << 8) | c3;
1281 				b = 3;
1282 				w = 2;
1283 			}
1284 		}
1285 	} else if (c >= 0xA0) {	/* �����ɥ��å�1 */
1286 		int	c2;
1287 
1288 		c2 = *(ptr + 1);
1289 		if (c2 != '\0' && c2 >= 0x80) {
1290 			c = (c << 8) | c2;
1291 			b = 2;
1292 			w = 2;
1293 		}
1294 	} else {
1295 		b = 1;
1296 		w = 1;
1297 	}
1298 #endif /* _T_EUC */
1299 
1300 	if (byte != NULL) {
1301 		*byte = b;
1302 	}
1303 	if (width != NULL) {
1304 		*width = w;
1305 	}
1306 	return (b != 0 ? c : 0);
1307 }
1308 
1309 /*
1310  * ʸ�����ʸ�������ɤ�������
1311  */
putcharcode(unsigned char * ptr,unsigned int code,int byte)1312 unsigned char *putcharcode(unsigned char *ptr, unsigned int code, int byte)
1313 {
1314 #ifdef _T_SJIS
1315 	if (byte > 1) {
1316 		*ptr++ = (unsigned char)(code >> 8);
1317 	}
1318 	*ptr++ = (unsigned char)code;
1319 #endif
1320 #ifdef _T_EUC
1321 	while (byte-- > 0) {
1322 		*ptr++ = (unsigned char)(code >> (8 * byte));
1323 	}
1324 #endif
1325 	return (ptr);
1326 }
1327 
1328 #ifdef _T_EUC
1329 /*
1330  * ʸ�����椫��ʸ�����������ΰ��֤��֤�
1331  *
1332  * use undertospace, Loading_SuffixTbl, message_fold(pager.c)
1333  */
jstrchr(const unsigned char * string,int code)1334 unsigned char *jstrchr(const unsigned char *string, int code)
1335 {
1336 	while (*string != '\0') {
1337 		unsigned int	cmpcode;
1338 		int	byte;
1339 
1340 		cmpcode = getcharcode(string, &byte, NULL);
1341 		if (byte == 0) {
1342 			break;
1343 		}
1344 		if (cmpcode == (unsigned int)code) {
1345 			return ((unsigned char *)string);
1346 		}
1347 		string += byte;
1348 	}
1349 	if (code == 0 && *string == '\0') {
1350 		return ((unsigned char *)string);
1351 	}
1352 	return (NULL);
1353 }
1354 #endif /* _T_EUC */
1355 #endif /* !INCLUDE_CALENDAR */
1356 
1357 /*
1358  * �������
1359  */
xmalloc(size_t size)1360 void *xmalloc(size_t size)
1361 {
1362 	void	*buf;
1363 
1364 	buf = malloc(size);
1365 	if (buf == NULL) {
1366 		memerr("xmalloc");
1367 	}
1368 	return (buf);
1369 }
1370 
1371 /*
1372  * ʸ�����ʣ��
1373  */
xstrdup(const char * str)1374 char *xstrdup(const char *str)
1375 {
1376 	size_t	len;
1377 	char	*buf;
1378 
1379 	len = strlen(str) + 1;
1380 	buf = malloc(len);
1381 	if (buf == NULL) {
1382 		memerr("xmalloc");
1383 	}
1384 	strcpy(buf, str);
1385 	return (buf);
1386 }
1387 
1388 #if defined(_T_MSDOS)
1389 /*
1390  * far �ҡ����ΰ褫��Υ������
1391  */
far_xmalloc(size_t size)1392 void FAR *far_xmalloc(size_t size)
1393 {
1394 	void FAR	*buf;
1395 
1396 	buf = farmalloc(size);
1397 	if (buf == NULL) {
1398 		errprint("far_xmalloc", ERR_PANIC, "virtual memory exhausted, program stop.");
1399 		terminate_program(TERM_MEMERROR);
1400 	}
1401 	return (buf);
1402 }
1403 
1404 /*
1405  * far �ҡ����ΰ�ؤ�ʸ�����ʣ��
1406  */
far_xstrdup(const char FAR * str)1407 char FAR *far_xstrdup(const char FAR *str)
1408 {
1409 	size_t		len;
1410 	char FAR	*buf;
1411 
1412 	len = FSTRLEN(str) + 1;
1413 	buf = farmalloc(len);
1414 	if (buf == NULL) {
1415 		errprint("far_xstrdup", ERR_PANIC, "virtual memory exhausted, program stop.");
1416 		terminate_program(TERM_MEMERROR);
1417 	}
1418 	FSTRCPY(buf, str);
1419 	return (buf);
1420 }
1421 #endif /* _T_MSDOS */
1422 
1423 /*
1424  * �ֿ��ص����פ�ͭ����Ƚ��
1425  *
1426  * return value:
1427  *   TRUE  ͭ��
1428  *   FALSE ̵��
1429  */
checkTransferHolidayJD(long jd)1430 int checkTransferHolidayJD(long jd)
1431 {
1432 	if (spHolspanJDTbl[0][0] <= jd && jd <= spHolspanJDTbl[0][1]) {
1433 		return (TRUE);
1434 	}
1435 	return (FALSE);
1436 }
1437 
1438 /*
1439  * �ֹ�̱�ε����פ�ͭ����Ƚ��
1440  *
1441  * return value:
1442  *   TRUE  ͭ��
1443  *   FALSE ̵��
1444  */
checkNationalHolidayJD(long jd)1445 int checkNationalHolidayJD(long jd)
1446 {
1447 	if (spHolspanJDTbl[1][0] <= jd && jd <= spHolspanJDTbl[1][1]) {
1448 		return (TRUE);
1449 	}
1450 	return (FALSE);
1451 }
1452 
1453 /*
1454  * �����������ǡ������ɤ߹���
1455  *
1456  * use file: holiday.tbl
1457  *
1458  * file format:
1459  *   00/nn yy/mm/dd-yy/mm/dd special_holiday_name
1460  *
1461  *   month/day yaer1-year2 holiday_name
1462  *   month/day year        holiday_name
1463  *   month/day year1-      holiday_name
1464  *   month/nWeek year1-year2 holiday_name
1465  *   month/nWeek year        holiday_name
1466  *   month/nWeek year1-      holiday_name
1467  *
1468  * return value:
1469  *   LOAD_OK �ɤ߹�������
1470  *   LOAD_NG ���顼ȯ��
1471  */
Loading_HolidayTbl(void)1472 int Loading_HolidayTbl(void)
1473 {
1474 #define ALLOC_HOLTBL	10
1475 	static const char	*weektbl = "SunMonTueWedThuFriSat";
1476 	char	*bp;
1477 	char	*lasts;
1478 	char	*dp;
1479 	char	*dp2;
1480 	char	weekbuf[4];
1481 	int		alloc;
1482 	int		use;
1483 	int		i;
1484 	int		yy1;
1485 	int		yy2;
1486 	int		mm;
1487 	int		dd;
1488 	int		week;
1489 	struct DATE_T	begin;
1490 	struct DATE_T	end;
1491 
1492 	if (openfile(holiday_file)) {
1493 		return (LOAD_NG);
1494 	}
1495 
1496 	alloc = 0;
1497 	use = 0;
1498 
1499 	while ((bp = getfile()) != NULL) {
1500 		lasts = NULL;
1501 		bp = strtok_r(bp, fmt_sep3, &lasts);
1502 		if (bp == NULL) {
1503 			continue;
1504 		}
1505 		week = -1;
1506 		switch (sscanf(bp, "%d/%d%3s", &mm, &dd, weekbuf)) {
1507 		case 2:
1508 			break;
1509 		case 3:
1510 			for (i = 0; i < 7; i++) {
1511 				if (strnicmp(weekbuf, &weektbl[i * 3], 3) == 0) {
1512 					week = i;
1513 					break;
1514 				}
1515 			}
1516 			if (week == -1) {
1517 				continue;
1518 			}
1519 			break;
1520 		default:
1521 			continue;
1522 		}
1523 
1524 		bp = strtok_r(NULL, fmt_sep3, &lasts);
1525 		if (bp == NULL) {
1526 			continue;
1527 		}
1528 		if (mm == 0) {	/* �ü����: ���ص���,��̱�ε��� */
1529 			if (dd < 1 || dd > MAX_SPHOLIDAY) {
1530 				continue;
1531 			}
1532 			dp = bp;
1533 			dp2 = strchr(bp, '-');
1534 			if (dp2 == NULL) {
1535 				continue;
1536 			}
1537 			*dp2++ = '\0';
1538 			if (read_date(0x01, dp, &begin, NULL) == DATE_NG ||
1539 			    read_date(0x01, dp2, &end, NULL) == DATE_NG) {
1540 				continue;
1541 			}
1542 			spHolspanJDTbl[dd - 1][0] = Julian(begin.year, begin.month, begin.day);
1543 			spHolspanJDTbl[dd - 1][1] = Julian(end.year, end.month, end.day);
1544 			yy1 = 0;
1545 			yy2 = 0;
1546 		} else {
1547 			if (analysis_year(bp, &yy1, NULL) == YEAR_NG) {
1548 				continue;
1549 			}
1550 			yy2 = yy1;
1551 			dp = strchr(bp, '-');
1552 			if (dp != NULL) {
1553 				dp++;
1554 				if (*dp == '\0') {
1555 					yy2 = 9999;
1556 				} else {
1557 					if (analysis_year(dp, &yy2, NULL) == YEAR_NG) {
1558 						continue;
1559 					}
1560 				}
1561 			}
1562 		}
1563 
1564 		bp = strtok_r(NULL, fmt_sep3, &lasts);
1565 		if (bp == NULL) {
1566 			continue;
1567 		}
1568 
1569 		if (use >= alloc) {
1570 			alloc += ALLOC_HOLTBL;
1571 			holidayTbl = (struct HOLIDAYTBL FAR *)FREALLOC(holidayTbl, alloc * sizeof(struct HOLIDAYTBL));
1572 			if (holidayTbl == NULL) {
1573 				memerr("Loading_HolidayTbl");
1574 			}
1575 		}
1576 		holidayTbl[use].yy1 = yy1;
1577 		holidayTbl[use].yy2 = yy2;
1578 		holidayTbl[use].mm = mm;
1579 		holidayTbl[use].dd = dd;
1580 		holidayTbl[use].week = week;
1581 		holidayTbl[use].name = XSTRDUP((const char FAR *)bp);
1582 		use++;
1583 	}
1584 
1585 	closefile();
1586 
1587 	max_holiday = use;
1588 
1589 	return (LOAD_OK);
1590 }
1591 
1592 /*
1593  * ���������������եơ��֥������
1594  *
1595  * ���Ѹ�� free ���뤳��
1596  */
GetHolidayTbl(int year,int month)1597 int *GetHolidayTbl(int year, int month)
1598 {
1599 	int	i;
1600 	int	*tbl;
1601 	int	dayofmonth;
1602 	int	first_dayofweek;
1603 	int	last_dayofweek;
1604 	int	day;
1605 	int	dayofweek;
1606 
1607 	if (holidayTbl == NULL) {
1608 		return (NULL);
1609 	}
1610 
1611 	tbl = NULL;
1612 	dayofmonth = GetDayofMonth(year, month);
1613 	first_dayofweek = GetDayofWeek(year, month, 1);
1614 	last_dayofweek = GetDayofWeek(year, month, dayofmonth);
1615 
1616 	for (i = 0; i < max_holiday; i++) {
1617 		if (holidayTbl[i].mm == month &&
1618 		    holidayTbl[i].yy1 <= year && year <= holidayTbl[i].yy2) {
1619 			day = holidayTbl[i].dd;
1620 			dayofweek = holidayTbl[i].week;
1621 			if (dayofweek != -1) {
1622 				if (day > 0) {
1623 					dayofweek = dayofweek - first_dayofweek + 1;
1624 					if (dayofweek <= 0) {
1625 						dayofweek += 7;
1626 					}
1627 					day = dayofweek + (day - 1) * 7;
1628 				} else if (day < 0) {
1629 					dayofweek = last_dayofweek - dayofweek;
1630 					if (dayofweek < 0) {
1631 						dayofweek += 7;
1632 					}
1633 					day = dayofmonth - dayofweek + (day + 1) * 7;
1634 				}
1635 			} else if (day == 0) {
1636 				switch (month) {
1637 				case 3:	/* ��ʬ */
1638 					GetSB(year, &day, NULL);
1639 					break;
1640 				case 9:	/* ��ʬ */
1641 					GetSB(year, NULL, &day);
1642 					break;
1643 				}
1644 			} else if (day < 0) {
1645 				day = day + dayofmonth + 1;
1646 			}
1647 			if (day > 0 && day <= dayofmonth && (tbl == NULL || tbl[day - 1] == 0)) {
1648 				if (tbl == NULL) {
1649 					tbl = malloc(sizeof(int) * MAX_DAYOFMONTH);
1650 					if (tbl == NULL) {
1651 						goto exit_proc;
1652 					}
1653 					memset(tbl, '\0', sizeof(int) * MAX_DAYOFMONTH);
1654 				}
1655 				tbl[day - 1] = i;
1656 			}
1657 		}
1658 	}
1659 
1660 exit_proc:
1661 	return (tbl);
1662 }
1663 
1664 #ifndef INCLUDE_CALENDAR
1665 /*
1666  * ������ơ��֥����Ͽ����
1667  * �ʤ����������������ξ��Ͽ��ص��������ꤹ��
1668  */
1669 static
setholiday(unsigned int * pHolTbl,int nameindex,long jd)1670 void setholiday(unsigned int *pHolTbl, int nameindex, long jd)
1671 {
1672 	pHolTbl[0] &= ~(MASK_HOLNAMEI | SET_OVRID);	/* ������³�������ο��ص����β�� */
1673 	pHolTbl[0] |= SET_HOLID | SET_HOLNAMEI(nameindex);
1674 	if ((pHolTbl[0] & SET_SUNID) != 0 &&
1675 	    checkTransferHolidayJD(jd + 1) == TRUE) {
1676 		pHolTbl[1] &= ~MASK_HOLNAMEI;
1677 		pHolTbl[1] |= SET_OVRID | SET_HOLID | SET_HOLNAMEI(0);	/* ���ص��� */
1678 		/*
1679 		 * event.skipHoliday() �Ǥϡ����������Ĥ�Ƚ�Ǥ� SET_OVRID ���Ƥ��ʤ�
1680 		 * ����Ū�˹ͤ��ơ��������ο��ص����Ϥ��ꤨ�ʤ��Τ���
1681 		 * �����Τ��� SET_HOLID �����ꤹ��
1682 		 */
1683 	}
1684 }
1685 
1686 /*
1687  * ����/�����ơ��֥����������
1688  */
makeHolidayTbl(void)1689 void makeHolidayTbl(void)
1690 {
1691 #define MAX_HOLTBLDAYS	(MAX_DAYOFMONTH * (MAX_MONTH_TBL + 2))
1692 	unsigned int	*tmpHolTbl;
1693 	unsigned int	flag;
1694 	unsigned int	*pHolTbl;
1695 	int	yy;
1696 	int	mm;
1697 	int	dayofweek;
1698 	int	dayofmonth;
1699 	int	first_dayofmonth;
1700 	int	i;
1701 	int	j;
1702 	int	*tbl;
1703 	long	jd;
1704 	long	first_jd;
1705 
1706 	tmpHolTbl = malloc(sizeof(unsigned int) * MAX_HOLTBLDAYS);
1707 	if (tmpHolTbl == NULL) {
1708 		memset(holiday_tbl, 0, sizeof(holiday_tbl));
1709 		return ;
1710 	}
1711 
1712 	yy = monthtbl[0].year;
1713 	mm = monthtbl[0].month - 1;
1714 	if (mm < 1) {
1715 		mm = 12;
1716 		yy--;
1717 	}
1718 
1719 	/* ���������� ����/���� */
1720 	dayofweek = GetDayofWeek(yy, mm, 1);
1721 	for (i = 0; i < MAX_HOLTBLDAYS; i++) {
1722 		switch (dayofweek) {
1723 		case 0:	/* sunday */
1724 			flag = SET_SUNID;
1725 			break;
1726 		case 6:	/* saturday */
1727 			flag = SET_SATID;
1728 			break;
1729 		default:
1730 			flag = 0;
1731 			break;
1732 		}
1733 		tmpHolTbl[i] = flag;
1734 		dayofweek = (dayofweek + 1) % 7;
1735 	}
1736 
1737 	first_jd = Julian(yy, mm, 1);
1738 	first_dayofmonth = GetDayofMonth(yy, mm);
1739 
1740 	/* ��������Ͽ */
1741 	pHolTbl = tmpHolTbl;
1742 	jd = first_jd;
1743 	for (j = 0; j < (MAX_MONTH_TBL + 2); j++) {
1744 		dayofmonth = GetDayofMonth(yy, mm);
1745 		tbl = GetHolidayTbl(yy, mm);
1746 		if (tbl != NULL) {
1747 			for (i = 0; i < dayofmonth; i++) {
1748 				if (tbl[i] != 0) {
1749 					setholiday(pHolTbl + i, tbl[i], jd + i);
1750 				}
1751 			}
1752 			free(tbl);
1753 		}
1754 		pHolTbl += dayofmonth;
1755 		jd += dayofmonth;
1756 		mm++;
1757 		if (mm > 12) {
1758 			mm = 1;
1759 			yy++;
1760 		}
1761 	}
1762 
1763 	/* �ֹ�̱�ε����פ���Ͽ */
1764 	jd = first_jd;
1765 	for (i = 0; i < (MAX_HOLTBLDAYS - 2); i++) {
1766 		if ((tmpHolTbl[i + 0] & SET_HOLID) != 0 &&
1767 		    (tmpHolTbl[i + 2] & SET_HOLID) != 0 &&
1768 		    (tmpHolTbl[i + 1] & (SET_HOLID | SET_OVRID | SET_SUNID)) == 0 &&
1769 		    checkNationalHolidayJD(jd + 1) == TRUE) {
1770 			tmpHolTbl[i + 1] &= MASK_HOLNAMEI;
1771 			tmpHolTbl[i + 1] |= SET_HOLID | SET_HOLNAMEI(1);	/* ��̱�ε��� */
1772 		}
1773 		jd++;
1774 	}
1775 
1776 	memcpy(holiday_tbl, &tmpHolTbl[first_dayofmonth], sizeof(holiday_tbl));
1777 	free(tmpHolTbl);
1778 }
1779 #endif /* !INCLUDE_CALENDAR */
1780 
1781 #if !defined(INCLUDE_CALENDAR) || (defined(_T_WINDOWS) && defined(INCLUDE_CALENDAR))
1782 /*
1783  * ������������̾��������
1784  *
1785  * ���Ѹ�� free ���뤳��
1786  */
GetHolidayName(int holiday_index)1787 char *GetHolidayName(int holiday_index)
1788 {
1789 	const char FAR	*name;
1790 	char	*buf;
1791 
1792 	if (holiday_index >= 0 && holiday_index < max_holiday) {
1793 		name = holidayTbl[holiday_index].name;
1794 		if (name != NULL) {
1795 			buf = malloc(FSTRLEN(name) + 1);
1796 			if (buf != NULL) {
1797 				FSTRCPY((char FAR *)buf, name);
1798 				return (buf);
1799 			}
1800 		}
1801 	}
1802 
1803 	return (NULL);
1804 }
1805 #endif /* !INCLUDE_CALENDAR || (_T_WINDOWS && INCLUDE_CALENDAR) */
1806 
1807 #ifndef _T_HAVE_STRTOK_R
1808 /*
1809  * ʸ����Υȡ�����ؤ�ʬ��
1810  */
strtok_r(char * s,const char * sep,char ** lasts)1811 char *strtok_r(char *s, const char *sep, char **lasts)
1812 {
1813 	char	*p;
1814 	char	c;
1815 
1816 	if (s == NULL) {
1817 		s = *lasts;
1818 		if (s == NULL) {
1819 			return (NULL);
1820 		}
1821 	}
1822 
1823 	while ((c = *s) != '\0') {
1824 		if (!strchr(sep, c)) {
1825 			break;
1826 		}
1827 		s++;
1828 	}
1829 
1830 	if (c == '\0') {
1831 		*lasts = NULL;
1832 		return (NULL);
1833 	}
1834 
1835 	for (p = s; (c = *++p) != '\0'; ) {
1836 		if (strchr(sep, c)) {
1837 			break;
1838 		}
1839 	}
1840 
1841 	if (c == '\0') {
1842 		*lasts = NULL;
1843 	} else {
1844 		*p++ = '\0';
1845 		*lasts = p;
1846 	}
1847 
1848 	return (s);
1849 }
1850 #endif /* !_T_HAVE_STRTOK_R */
1851