⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zic.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
			(void) perror(fullname);			(void) exit(EXIT_FAILURE);		}	}	convert(eitol(typecnt), tzh.tzh_ttisstdcnt);	convert(eitol(leapcnt), tzh.tzh_leapcnt);	convert(eitol(timecnt), tzh.tzh_timecnt);	convert(eitol(typecnt), tzh.tzh_typecnt);	convert(eitol(charcnt), tzh.tzh_charcnt);	(void) fwrite((void *) &tzh, (size_t) sizeof tzh, (size_t) 1, fp);	for (i = 0; i < timecnt; ++i) {		j = leapcnt;		while (--j >= 0)			if (ats[i] >= trans[j]) {				ats[i] = tadd(ats[i], corr[j]);				break;			}		puttzcode((long) ats[i], fp);	}	if (timecnt > 0)		(void) fwrite((void *) types, (size_t) sizeof types[0],		    (size_t) timecnt, fp);	for (i = 0; i < typecnt; ++i) {		puttzcode((long) gmtoffs[i], fp);		(void) putc(isdsts[i], fp);		(void) putc(abbrinds[i], fp);	}	if (charcnt != 0)		(void) fwrite((void *) chars, (size_t) sizeof chars[0],			(size_t) charcnt, fp);	for (i = 0; i < leapcnt; ++i) {		if (roll[i]) {			if (timecnt == 0 || trans[i] < ats[0]) {				j = 0;				while (isdsts[j])					if (++j >= typecnt) {						j = 0;						break;					}			} else {				j = 1;				while (j < timecnt && trans[i] >= ats[j])					++j;				j = types[j - 1];			}			puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp);		} else	puttzcode((long) trans[i], fp);		puttzcode((long) corr[i], fp);	}	for (i = 0; i < typecnt; ++i)		(void) putc(ttisstds[i], fp);	if (ferror(fp) || fclose(fp)) {		(void) fprintf(stderr, "%s: Write error on ", progname);		(void) perror(fullname);		(void) exit(EXIT_FAILURE);	}}static voidoutzone(zpfirst, zonecount)const struct zone * const	zpfirst;const int			zonecount;{	register const struct zone *	zp;	register struct rule *		rp;	register int			i, j;	register int			usestart, useuntil;	register time_t			starttime, untiltime;	register long			gmtoff;	register long			stdoff;	register int			year;	register long			startoff;	register int			startisdst;	register int			startttisstd;	register int			type;	char				startbuf[BUFSIZ];	/*	** Now. . .finally. . .generate some useful data!	*/	timecnt = 0;	typecnt = 0;	charcnt = 0;	/*	** Two guesses. . .the second may well be corrected later.	*/	gmtoff = zpfirst->z_gmtoff;	stdoff = 0;	starttime = 0;	startttisstd = FALSE;	for (i = 0; i < zonecount; ++i) {		usestart = i > 0;		useuntil = i < (zonecount - 1);		zp = &zpfirst[i];		eat(zp->z_filename, zp->z_linenum);		startisdst = -1;		if (zp->z_nrules == 0) {			type = addtype(oadd(zp->z_gmtoff, zp->z_stdoff),				zp->z_format, zp->z_stdoff != 0,				startttisstd);			if (usestart)				addtt(starttime, type);			gmtoff = zp->z_gmtoff;			stdoff = zp->z_stdoff;		} else for (year = min_year; year <= max_year; ++year) {			if (useuntil && year > zp->z_untilrule.r_hiyear)				break;			/*			** Mark which rules to do in the current year.			** For those to do, calculate rpytime(rp, year);			*/			for (j = 0; j < zp->z_nrules; ++j) {				rp = &zp->z_rules[j];				eats(zp->z_filename, zp->z_linenum,					rp->r_filename, rp->r_linenum);				rp->r_todo = year >= rp->r_loyear &&						year <= rp->r_hiyear &&						yearistype(year, rp->r_yrtype);				if (rp->r_todo)					rp->r_temp = rpytime(rp, year);			}			for ( ; ; ) {				register int	k;				register time_t	jtime, ktime;				register long	offset;				char		buf[BUFSIZ];				if (useuntil) {					/*					** Turn untiltime into GMT					** assuming the current gmtoff and					** stdoff values.					*/					offset = gmtoff;					if (!zp->z_untilrule.r_todisstd)						offset = oadd(offset, stdoff);					untiltime = tadd(zp->z_untiltime,						-offset);				}				/*				** Find the rule (of those to do, if any)				** that takes effect earliest in the year.				*/				k = -1;#ifdef lint				ktime = 0;#endif /* defined lint */				for (j = 0; j < zp->z_nrules; ++j) {					rp = &zp->z_rules[j];					if (!rp->r_todo)						continue;					eats(zp->z_filename, zp->z_linenum,						rp->r_filename, rp->r_linenum);					offset = gmtoff;					if (!rp->r_todisstd)						offset = oadd(offset, stdoff);					jtime = rp->r_temp;					if (jtime == min_time ||						jtime == max_time)							continue;					jtime = tadd(jtime, -offset);					if (k < 0 || jtime < ktime) {						k = j;						ktime = jtime;					}				}				if (k < 0)					break;	/* go on to next year */				rp = &zp->z_rules[k];				rp->r_todo = FALSE;				if (useuntil && ktime >= untiltime)					break;				if (usestart) {					if (ktime < starttime) {						stdoff = rp->r_stdoff;						startoff = oadd(zp->z_gmtoff,							rp->r_stdoff);						(void) sprintf(startbuf,							zp->z_format,							rp->r_abbrvar);						startisdst =							rp->r_stdoff != 0;						continue;					}					if (ktime != starttime &&						startisdst >= 0)addtt(starttime, addtype(startoff, startbuf, startisdst, startttisstd));					usestart = FALSE;				}				eats(zp->z_filename, zp->z_linenum,					rp->r_filename, rp->r_linenum);				(void) sprintf(buf, zp->z_format,					rp->r_abbrvar);				offset = oadd(zp->z_gmtoff, rp->r_stdoff);				type = addtype(offset, buf, rp->r_stdoff != 0,					rp->r_todisstd);				if (timecnt != 0 || rp->r_stdoff != 0)					addtt(ktime, type);				gmtoff = zp->z_gmtoff;				stdoff = rp->r_stdoff;			}		}		/*		** Now we may get to set starttime for the next zone line.		*/		if (useuntil) {			starttime = tadd(zp->z_untiltime,				-gmtoffs[types[timecnt - 1]]);			startttisstd = zp->z_untilrule.r_todisstd;		}	}	writezone(zpfirst->z_name);}static voidaddtt(starttime, type)const time_t	starttime;const int	type;{	if (timecnt != 0 && type == types[timecnt - 1])		return;	/* easy enough! */	if (timecnt >= TZ_MAX_TIMES) {		error("too many transitions?!");		(void) exit(EXIT_FAILURE);	}	ats[timecnt] = starttime;	types[timecnt] = type;	++timecnt;}static intaddtype(gmtoff, abbr, isdst, ttisstd)const long		gmtoff;const char * const	abbr;const int		isdst;const int		ttisstd;{	register int	i, j;	/*	** See if there's already an entry for this zone type.	** If so, just return its index.	*/	for (i = 0; i < typecnt; ++i) {		if (gmtoff == gmtoffs[i] && isdst == isdsts[i] &&			strcmp(abbr, &chars[abbrinds[i]]) == 0 &&			ttisstd == ttisstds[i])				return i;	}	/*	** There isn't one; add a new one, unless there are already too	** many.	*/	if (typecnt >= TZ_MAX_TYPES) {		error("too many local time types");		(void) exit(EXIT_FAILURE);	}	gmtoffs[i] = gmtoff;	isdsts[i] = isdst;	ttisstds[i] = ttisstd;	for (j = 0; j < charcnt; ++j)		if (strcmp(&chars[j], abbr) == 0)			break;	if (j == charcnt)		newabbr(abbr);	abbrinds[i] = j;	++typecnt;	return i;}static voidaddleap(t, positive, rolling)const time_t	t;const int	positive;const int	rolling;{	register int	i, j;	if (leapcnt >= TZ_MAX_LEAPS) {		error("too many leap seconds");		(void) exit(EXIT_FAILURE);	}	for (i = 0; i < leapcnt; ++i)		if (t <= trans[i]) {			if (t == trans[i]) {				error("repeated leap second moment");				(void) exit(EXIT_FAILURE);			}			break;		}	for (j = leapcnt; j > i; --j) {		trans[j] = trans[j-1];		corr[j] = corr[j-1];		roll[j] = roll[j-1];	}	trans[i] = t;	corr[i] = (positive ? 1L : -1L);	roll[i] = rolling;	++leapcnt;}static voidadjleap(){	register int	i;	register long	last = 0;	/*	** propagate leap seconds forward	*/	for (i = 0; i < leapcnt; ++i) {		trans[i] = tadd(trans[i], last);		last = corr[i] += last;	}}static intyearistype(year, type)const int		year;const char * const	type;{	char	buf[BUFSIZ];	int	result;	if (type == NULL || *type == '\0')		return TRUE;	if (strcmp(type, "uspres") == 0)		return (year % 4) == 0;	if (strcmp(type, "nonpres") == 0)		return (year % 4) != 0;	(void) sprintf(buf, "yearistype %d %s", year, type);	result = system(buf);	if (result == 0)		return TRUE;	if (result == (1 << 8))		return FALSE;	error("Wild result from command execution");	(void) fprintf(stderr, "%s: command was '%s', result was %d\n",		progname, buf, result);	for ( ; ; )		(void) exit(EXIT_FAILURE);}static intlowerit(a)const int	a;{	return (isascii(a) && isupper(a)) ? tolower(a) : a;}static intciequal(ap, bp)		/* case-insensitive equality */register const char *	ap;register const char *	bp;{	while (lowerit(*ap) == lowerit(*bp++))		if (*ap++ == '\0')			return TRUE;	return FALSE;}static intitsabbr(abbr, word)register const char *	abbr;register const char *	word;{	if (lowerit(*abbr) != lowerit(*word))		return FALSE;	++word;	while (*++abbr != '\0')		do if (*word == '\0')			return FALSE;				while (lowerit(*word++) != lowerit(*abbr));	return TRUE;}static const struct lookup *byword(word, table)register const char * const		word;register const struct lookup * const	table;{	register const struct lookup *	foundlp;	register const struct lookup *	lp;	if (word == NULL || table == NULL)		return NULL;	/*	** Look for exact match.	*/	for (lp = table; lp->l_word != NULL; ++lp)		if (ciequal(word, lp->l_word))			return lp;	/*	** Look for inexact match.	*/	foundlp = NULL;	for (lp = table; lp->l_word != NULL; ++lp)		if (itsabbr(word, lp->l_word))			if (foundlp == NULL)				foundlp = lp;			else	return NULL;	/* multiple inexact matches */	return foundlp;}static char **getfields(cp)register char *	cp;{	register char *		dp;	register char **	array;	register int		nsubs;	if (cp == NULL)		return NULL;	array = (char **) emalloc((int) ((strlen(cp) + 1) * sizeof *array));	nsubs = 0;	for ( ; ; ) {		while (isascii(*cp) && isspace(*cp))			++cp;		if (*cp == '\0' || *cp == '#')			break;		array[nsubs++] = dp = cp;		do {			if ((*dp = *cp++) != '"')				++dp;			else while ((*dp = *cp++) != '"')				if (*dp != '\0')					++dp;				else	error("Odd number of quotation marks");		} while (*cp != '\0' && *cp != '#' &&			(!isascii(*cp) || !isspace(*cp)));		if (isascii(*cp) && isspace(*cp))			++cp;		*dp = '\0';	}	array[nsubs] = NULL;	return array;}static longoadd(t1, t2)const long	t1;const long	t2;{	register long	t;	t = t1 + t2;	if (t2 > 0 && t <= t1 || t2 < 0 && t >= t1) {		error("time overflow");		(void) exit(EXIT_FAILURE);	}	return t;}static time_ttadd(t1, t2)const time_t	t1;const long	t2;{	register time_t	t;	if (t1 == max_time && t2 > 0)		return max_time;	if (t1 == min_time && t2 < 0)		return min_time;	t = t1 + t2;	if (t2 > 0 && t <= t1 || t2 < 0 && t >= t1) {		error("time overflow");		(void) exit(EXIT_FAILURE);	}	return t;}/*** Given a rule, and a year, compute the date - in seconds since January 1,** 1970, 00:00 LOCAL time - in that year that the rule refers to.*/static time_trpytime(rp, wantedy)register const struct rule * const	rp;register const int			wantedy;{	register int	y, m, i;	register long	dayoff;			/* with a nod to Margaret O. */	register time_t	t;	dayoff = 0;	m = TM_JANUARY;	y = EPOCH_YEAR;	while (wantedy != y) {		if (wantedy > y) {			i = len_years[isleap(y)];			++y;		} else {			--y;			i = -len_years[isleap(y)];		}		dayoff = oadd(dayoff, eitol(i));	}	while (m != rp->r_month) {		i = len_months[isleap(y)][m];		dayoff = oadd(dayoff, eitol(i));		++m;	}	i = rp->r_dayofmonth;	if (m == TM_FEBRUARY && i == 29 && !isleap(y)) {		if (rp->r_dycode == DC_DOWLEQ)			--i;		else {			error("use of 2/29 in non leap-year");			(void) exit(EXIT_FAILURE);		}	}	--i;	dayoff = oadd(dayoff, eitol(i));	if (rp->r_dycode == DC_DOWGEQ || rp->r_dycode == DC_DOWLEQ) {		register long	wday;#define LDAYSPERWEEK	((long) DAYSPERWEEK)		wday = eitol(EPOCH_WDAY);		/*		** Don't trust mod of negative numbers.		*/		if (dayoff >= 0)			wday = (wday + dayoff) % LDAYSPERWEEK;		else {			wday -= ((-dayoff) % LDAYSPERWEEK);			if (wday < 0)				wday += LDAYSPERWEEK;		}		while (wday != eitol(rp->r_wday))			if (rp->r_dycode == DC_DOWGEQ) {				dayoff = oadd(dayoff, (long) 1);				if (++wday >= LDAYSPERWEEK)					wday = 0;				++i;			} else {				dayoff = oadd(dayoff, (long) -1);				if (--wday < 0)					wday = LDAYSPERWEEK - 1;				--i;			}		if (i < 0 || i >= len_months[isleap(y)][m]) {			error("no day in month matches rule");			(void) exit(EXIT_FAILURE);		}	}	if (dayoff < 0 && !tt_signed) {		if (wantedy == rp->r_loyear)			return min_time;		error("time before zero");		(void) exit(EXIT_FAILURE);	}	t = (time_t) dayoff * SECSPERDAY;	/*	** Cheap overflow check.	*/	if (t / SECSPERDAY != dayoff) {		if (wantedy == rp->r_hiyear)			return max_time;		if (wantedy == rp->r_loyear)			return min_time;		error("time overflow");		(void) exit(EXIT_FAILURE);	}	return tadd(t, rp->r_tod);}static voidnewabbr(string)const char * const	string;{	register int	i;	i = strlen(string) + 1;	if (charcnt + i >= TZ_MAX_CHARS) {		error("too many, or too long, time zone abbreviations");		(void) exit(EXIT_FAILURE);	}	(void) strcpy(&chars[charcnt], string);	charcnt += eitol(i);}static intmkdirs(name)char * const	name;{	register char *	cp;	if ((cp = name) == NULL || *cp == '\0')		return 0;	while ((cp = strchr(cp + 1, '/')) != 0) {		*cp = '\0';		if (!itsdir(name)) {			/*			** It doesn't seem to exist, so we try to create it.			*/			if (mkdir(name, 0755) != 0) {				(void) fprintf(stderr,					"%s: Can't create directory ",					progname);				(void) perror(name);				return -1;			}		}		*cp = '/';	}	return 0;}static longeitol(i)const int	i;{	long	l;	l = i;	if (i < 0 && l >= 0 || i == 0 && l != 0 || i > 0 && l <= 0) {		(void) fprintf(stderr, "%s: %d did not sign extend correctly\n",			progname, i);		(void) exit(EXIT_FAILURE);	}	return l;}/*** UNIX is a registered trademark of AT&T.*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -