Esempio n. 1
0
int
tmxsettime(Time_t t)
{
	Tv_t	tv;

	tv.tv_sec = tmxsec(t);
	tv.tv_nsec = tmxnsec(t);
	return tvsettime(&tv);
}
Esempio n. 2
0
int
tmxtouch(const char* path, Time_t at, Time_t mt, Time_t ct, int flags)
{
	Tv_t	av;
	Tv_t	mv;
	Tv_t	cv;
	Tv_t*	ap;
	Tv_t*	mp;
	Tv_t*	cp;

	if (at == TMX_NOTIME && !(flags & PATH_TOUCH_VERBATIM))
		ap = TV_TOUCH_RETAIN;
	else if (!at && !(flags & PATH_TOUCH_VERBATIM))
		ap = 0;
	else
	{
		av.tv_sec = tmxsec(at);
		av.tv_nsec = tmxnsec(at);
		ap = &av;
	}
	if (mt == TMX_NOTIME && !(flags & PATH_TOUCH_VERBATIM))
		mp = TV_TOUCH_RETAIN;
	else if (!mt && !(flags & PATH_TOUCH_VERBATIM))
		mp = 0;
	else
	{
		mv.tv_sec = tmxsec(mt);
		mv.tv_nsec = tmxnsec(mt);
		mp = &mv;
	}
	if (ct == TMX_NOTIME && !(flags & PATH_TOUCH_VERBATIM))
		cp = TV_TOUCH_RETAIN;
	else if (!ct && !(flags & PATH_TOUCH_VERBATIM))
		cp = 0;
	else
	{
		cv.tv_sec = tmxsec(ct);
		cv.tv_nsec = tmxnsec(ct);
		cp = &cv;
	}
	return tvtouch(path, ap, mp, cp, flags & 1);
}
Esempio n. 3
0
Time_t
tmxtime(register Tm_t* tm, int west)
{
	register Time_t		t;
	register Tm_leap_t*	lp;
	register int32_t	y;
	int			n;
	int			sec;
	time_t			now;
	struct tm*		tl;
	Tm_t*			to;
	Tm_t			ts;

	ts = *tm;
	to = tm;
	tm = &ts;
	tmset(tm_info.zone);
	tmfix(tm);
	y = tm->tm_year;
	if (y < 69 || y > (TMX_MAXYEAR - 1900))
		return TMX_NOTIME;
	y--;
	t = y * 365 + y / 4 - y / 100 + (y + (1900 - 1600)) / 400 - (1970 - 1901) * 365 - (1970 - 1901) / 4;
	if ((n = tm->tm_mon) > 11)
		n = 11;
	y += 1901;
	if (n > 1 && tmisleapyear(y))
		t++;
	t += tm_data.sum[n] + tm->tm_mday - 1;
	t *= 24;
	t += tm->tm_hour;
	t *= 60;
	t += tm->tm_min;
	t *= 60;
	t += sec = tm->tm_sec;
	if (west != TM_UTCZONE && !(tm_info.flags & TM_UTC))
	{
		/*
		 * time zone adjustments
		 */

		if (west == TM_LOCALZONE)
		{
			t += tm_info.zone->west * 60;
			if (!tm_info.zone->daylight)
				tm->tm_isdst = 0;
			else
			{
				y = tm->tm_year;
				tm->tm_year = tmequiv(tm) - 1900;
				now = tmxsec(tmxtime(tm, tm_info.zone->west));
				tm->tm_year = y;
				if (!(tl = tmlocaltime(&now)))
					return TMX_NOTIME;
				if (tm->tm_isdst = tl->tm_isdst)
					t += tm_info.zone->dst * 60;
			}
		}
		else
		{
			t += west * 60;
			if (!tm_info.zone->daylight)
				tm->tm_isdst = 0;
			else if (tm->tm_isdst < 0)
			{
				y = tm->tm_year;
				tm->tm_year = tmequiv(tm) - 1900;
				tm->tm_isdst = 0;
				now = tmxsec(tmxtime(tm, tm_info.zone->west));
				tm->tm_year = y;
				if (!(tl = tmlocaltime(&now)))
					return TMX_NOTIME;
				tm->tm_isdst = tl->tm_isdst;
			}
		}
	}
	else if (tm->tm_isdst)
		tm->tm_isdst = 0;
	*to = *tm;
	if (tm_info.flags & TM_LEAP)
	{
		/*
		 * leap second adjustments
		 */

		for (lp = &tm_data.leap[0]; t < lp->time - (lp+1)->total; lp++);
		t += lp->total;
		n = lp->total - (lp+1)->total;
		if (t <= (lp->time + n) && (n > 0 && sec > 59 || n < 0 && sec > (59 + n) && sec <= 59))
			t -= n;
	}
	return tmxsns(t, tm->tm_nsec);
}
Esempio n. 4
0
time_t
tmtime(register Tm_t* tm, int west)
{
	return tmxsec(tmxtime(tm, west));
}
Esempio n. 5
0
int
b_date(int argc, register char** argv, void* context)
{
	register int	n;
	register char*	s;
	register Fmt_t*	f;
	char*		t;
	unsigned long	u;
	Time_t		now;
	Time_t		ts;
	Time_t		te;
	Time_t		e;
	char		buf[1024];
	Fmt_t*		fmts;
	Fmt_t		fmt;
	struct stat	st;

	char*		cmd = argv[0];	/* original command path	*/
	char*		format = 0;	/* tmxfmt() format		*/
	char*		string = 0;	/* date string			*/
	int		elapsed = 0;	/* args are start/stop pairs	*/
	int		filetime = 0;	/* use this st_ time field	*/
	int		increment = 0;	/* incrementally adjust time	*/
	int		last = 0;	/* display the last time arg	*/
	Tm_zone_t*	listzones = 0;	/* known time zone table	*/
	int		network = 0;	/* don't set network time	*/
	int		show = 0;	/* show date and don't set	*/
	int		unelapsed = 0;	/* fmtelapsed() => strelapsed	*/

	cmdinit(argc, argv, context, ERROR_CATALOG, 0);
	tm_info.flags = TM_DATESTYLE;
	fmts = &fmt;
	fmt.format = "";
	fmt.next = 0;
	for (;;)
	{
		switch (optget(argv, usage))
		{
		case 'a':
		case 'c':
		case 'm':
			filetime = opt_info.option[1];
			continue;
		case 'd':
			string = opt_info.arg;
			show = 1;
			continue;
		case 'e':
			format = "%#";
			continue;
		case 'E':
			elapsed = 1;
			continue;
		case 'f':
			format = opt_info.arg;
			continue;
		case 'i':
			increment = 1;
			continue;
		case 'l':
			tm_info.flags |= TM_LEAP;
			continue;
		case 'L':
			last = 1;
			continue;
		case 'n':
			network = 1;
			continue;
		case 'p':
			if (!(f = newof(0, Fmt_t, 1, 0)))
				error(ERROR_SYSTEM|3, "out of space [format]");
			f->next = fmts;
			f->format = opt_info.arg;
			fmts = f;
			continue;
		case 's':
			show = 1;
			continue;
		case 'u':
			tm_info.flags |= TM_UTC;
			continue;
		case 'U':
			unelapsed = (int)opt_info.num;
			continue;
		case 'z':
			listzones = tm_data.zone;
			continue;
		case '?':
			error(ERROR_USAGE|4, "%s", opt_info.arg);
			continue;
		case ':':
			error(2, "%s", opt_info.arg);
			continue;
		}
		break;
	}
	argv += opt_info.index;
	if (error_info.errors)
		error(ERROR_USAGE|4, "%s", optusage(NiL));
	now = tmxgettime();
	if (listzones)
	{
		s = "-";
		while (listzones->standard)
		{
			if (listzones->type)
				s = listzones->type;
			sfprintf(sfstdout, "%3s %4s %4s %4d %4d\n", s, *listzones->standard ? listzones->standard : "-", listzones->daylight ? listzones->daylight : "-", listzones->west, listzones->dst);
			listzones++;
			show = 1;
		}
	}
	else if (elapsed)
	{
		e = 0;
		while (s = *argv++)
		{
			if (!(t = *argv++))
			{
				argv--;
				t = "now";
			}
			ts = convert(fmts, s, now);
			te = convert(fmts, t, now);
			if (te > ts)
				e += te - ts;
			else
				e += ts - te;
		}
		sfputr(sfstdout, fmtelapsed((unsigned long)tmxsec(e), 1), '\n');
		show = 1;
	}
	else if (unelapsed)
	{
		while (s = *argv++)
		{
			u = strelapsed(s, &t, unelapsed);
			if (*t)
				error(3, "%s: invalid elapsed time", s);
			sfprintf(sfstdout, "%lu\n", u);
		}
		show = 1;
	}
	else if (filetime)
	{
		if (!*argv)
			error(ERROR_USAGE|4, "%s", optusage(NiL));
		n = argv[1] != 0;
		while (s = *argv++)
		{
			if (stat(s, &st))
				error(2, "%s: not found", s);
			else
			{
				switch (filetime)
				{
				case 'a':
					now = tmxgetatime(&st);
					break;
				case 'c':
					now = tmxgetctime(&st);
					break;
				default:
					now = tmxgetmtime(&st);
					break;
				}
				tmxfmt(buf, sizeof(buf), format, now);
				if (n)
					sfprintf(sfstdout, "%s: %s\n", s, buf);
				else
					sfprintf(sfstdout, "%s\n", buf);
				show = 1;
			}
		}
	}
	else
	{
		if ((s = *argv) && !format && *s == '+')
		{
			format = s + 1;
			argv++;
			s = *argv;
		}
		if (s || (s = string))
		{
			if (*argv && string)
				error(ERROR_USAGE|4, "%s", optusage(NiL));
			now = convert(fmts, s, now);
			if (*argv && (s = *++argv))
			{
				show = 1;
				do
				{
					if (!last)
					{
						tmxfmt(buf, sizeof(buf), format, now);
						sfprintf(sfstdout, "%s\n", buf);
					}
					now = convert(fmts, s, now);
				} while (s = *++argv);
			}
		}
		else
			show = 1;
		if (format || show)
		{
			tmxfmt(buf, sizeof(buf), format, now);
			sfprintf(sfstdout, "%s\n", buf);
		}
		else if (settime(context, cmd, now, increment, network))
			error(ERROR_SYSTEM|3, "cannot set system time");
	}
	while (fmts != &fmt)
	{
		f = fmts;
		fmts = fmts->next;
		free(f);
	}
	tm_info.flags = 0;
	if (show && sfsync(sfstdout))
		error(ERROR_system(0), "write error");
	return error_info.errors != 0;
}
Esempio n. 6
0
char*
tmxfmt(char* buf, size_t len, const char* format, Time_t t)
{
	register char*	cp;
	register char*	ep;
	register char*	p;
	register int	n;
	int		c;
	int		i;
	int		flags;
	int		alt;
	int		pad;
	int		delimiter;
	int		width;
	int		prec;
	int		parts;
	char*		arg;
	char*		f;
	const char*	oformat;
	Tm_t*		tm;
	Tm_zone_t*	zp;
	Time_t		now;
	Stack_t*	sp;
	Stack_t		stack[8];
	Tm_t		ts;
	char		argbuf[256];
	char		fmt[32];

	tmlocale();
	tm = tmxtm(&ts, t, NiL);
	if (!format || !*format)
		format = tm_info.deformat;
	oformat = format;
	flags = tm_info.flags;
	sp = &stack[0];
	cp = buf;
	ep = buf + len;
	delimiter = 0;
	for (;;)
	{
		if ((c = *format++) == delimiter)
		{
			delimiter = 0;
			if (sp <= &stack[0])
				break;
			sp--;
			format = sp->format;
			delimiter = sp->delimiter;
			continue;
		}
		if (c != '%')
		{
			if (cp < ep)
				*cp++ = c;
			continue;
		}
		alt = 0;
		arg = 0;
		pad = 0;
		width = 0;
		prec = 0;
		parts = 0;
		for (;;)
		{
			switch (c = *format++)
			{
			case '_':
			case '-':
				pad = c;
				continue;
			case 'E':
			case 'O':
				if (!isalpha(*format))
					break;
				alt = c;
				continue;
			case '0':
				if (!parts)
				{
					pad = c;
					continue;
				}
				/*FALLTHROUGH*/
			case '1':
			case '2':
			case '3':
			case '4':
			case '5':
			case '6':
			case '7':
			case '8':
			case '9':
				switch (parts)
				{
				case 0:
					parts++;
					/*FALLTHROUGH*/
				case 1:
					width = width * 10 + (c - '0');
					break;
				case 2:
					prec = prec * 10 + (c - '0');
					break;
				}
				continue;
			case '.':
				if (!parts++)
					parts++;
				continue;
			case '(':
				i = 1;
				arg = argbuf;
				for (;;)
				{
					if (!(c = *format++))
					{
						format--;
						break;
					}
					else if (c == '(')
						i++;
					else if (c == ')' && !--i)
						break;
					else if (arg < &argbuf[sizeof(argbuf) - 1])
						*arg++ = c;
				}
				*arg = 0;
				arg = argbuf;
				continue;
			default:
				break;
			}
			break;
		}
		switch (c)
		{
		case 0:
			format--;
			continue;
		case '%':
			if (cp < ep)
				*cp++ = '%';
			continue;
		case '?':
			if (tm_info.deformat != tm_info.format[TM_DEFAULT])
				format = tm_info.deformat;
			else if (!*format)
				format = tm_info.format[TM_DEFAULT];
			continue;
		case 'a':	/* abbreviated day of week name */
			n = TM_DAY_ABBREV + tm->tm_wday;
			goto index;
		case 'A':	/* day of week name */
			n = TM_DAY + tm->tm_wday;
			goto index;
		case 'b':	/* abbreviated month name */
		case 'h':
			n = TM_MONTH_ABBREV + tm->tm_mon;
			goto index;
		case 'B':	/* month name */
			n = TM_MONTH + tm->tm_mon;
			goto index;
		case 'c':	/* `ctime(3)' date sans newline */
			p = tm_info.format[TM_CTIME];
			goto push;
		case 'C':	/* 2 digit century */
			cp = number(cp, ep, (long)(1900 + tm->tm_year) / 100, 2, width, pad);
			continue;
		case 'd':	/* day of month */
			cp = number(cp, ep, (long)tm->tm_mday, 2, width, pad);
			continue;
		case 'D':	/* date */
			p = tm_info.format[TM_DATE];
			goto push;
		case 'e':       /* blank padded day of month */
			cp = number(cp, ep, (long)tm->tm_mday, -2, width, pad);
			continue;
		case 'f':	/* (AST) OBSOLETE use %Qf */
			p = "%Qf";
			goto push;
		case 'F':	/* ISO 8601:2000 standard date format */
			p = "%Y-%m-%d";
			goto push;
		case 'g':	/* %V 2 digit year */
		case 'G':	/* %V 4 digit year */
			n = tm->tm_year + 1900;
			if (tm->tm_yday < 7)
			{
				if (tmweek(tm, 2, -1, -1) >= 52)
					n--;
			}
			else if (tm->tm_yday > 358)
			{
				if (tmweek(tm, 2, -1, -1) <= 1)
					n++;
			}
			if (c == 'g')
			{
				n %= 100;
				c = 2;
			}
			else
				c = 4;
			cp = number(cp, ep, (long)n, c, width, pad);
			continue;
		case 'H':	/* hour (0 - 23) */
			cp = number(cp, ep, (long)tm->tm_hour, 2, width, pad);
			continue;
		case 'i':	/* (AST) OBSOLETE use %QI */
			p = "%QI";
			goto push;
		case 'I':	/* hour (0 - 12) */
			if ((n = tm->tm_hour) > 12) n -= 12;
			else if (n == 0) n = 12;
			cp = number(cp, ep, (long)n, 2, width, pad);
			continue;
		case 'j':	/* Julian date (1 offset) */
			cp = number(cp, ep, (long)(tm->tm_yday + 1), 3, width, pad);
			continue;
		case 'J':	/* Julian date (0 offset) */
			cp = number(cp, ep, (long)tm->tm_yday, 3, width, pad);
			continue;
		case 'k':	/* (AST) OBSOLETE use %QD */
			p = "%QD";
			goto push;
		case 'K':	/* (AST) largest to smallest */
			switch (alt)
			{
			case 'E':
				p = (pad == '_') ? "%Y-%m-%d %H:%M:%S.%N %z" : "%Y-%m-%d+%H:%M:%S.%N%z";
				break;
			case 'O':
				p = (pad == '_') ? "%Y-%m-%d %H:%M:%S.%N" : "%Y-%m-%d+%H:%M:%S.%N";
				break;
			default:
				p = (pad == '_') ? "%Y-%m-%d %H:%M:%S" : "%Y-%m-%d+%H:%M:%S";
				break;
			}
			goto push;
		case 'l':	/* (AST) OBSOLETE use %QL */
			p = "%QL";
			goto push;
		case 'L':	/* (AST) OBSOLETE use %Ql */
			p = "%Ql";
			goto push;
		case 'm':	/* month number */
			cp = number(cp, ep, (long)(tm->tm_mon + 1), 2, width, pad);
			continue;
		case 'M':	/* minutes */
			cp = number(cp, ep, (long)tm->tm_min, 2, width, pad);
			continue;
		case 'n':
			if (cp < ep)
				*cp++ = '\n';
			continue;
		case 'N':	/* (AST|GNU) nanosecond part */
			cp = number(cp, ep, (long)tm->tm_nsec, 9, width, pad);
			continue;
#if 0
		case 'o':	/* (UNUSED) */
			continue;
#endif
		case 'p':	/* meridian */
			n = TM_MERIDIAN + (tm->tm_hour >= 12);
			goto index;
		case 'P':	/* (AST|GNU) lower case meridian */
			p = tm_info.format[TM_MERIDIAN + (tm->tm_hour >= 12)];
			while (cp < ep && (n = *p++))
				*cp++ = isupper(n) ? tolower(n) : n;
			continue;
		case 'q':	/* (AST) OBSOLETE use %Qz */
			p = "%Qz";
			goto push;
		case 'Q':	/* (AST) %Q<alpha> or %Q<delim>recent<delim>distant<delim> */
			if (c = *format)
			{
				format++;
				if (isalpha(c))
				{
					switch (c)
					{
					case 'd':	/* `ls -l' distant date */
						p = tm_info.format[TM_DISTANT];
						goto push;
					case 'D':	/* `date(1)' date */
						p = tm_info.format[TM_DATE_1];
						goto push;
					case 'f':	/* TM_DEFAULT override */
						p = tm_info.deformat;
						goto push;
					case 'I':	/* international `date(1)' date */
						p = tm_info.format[TM_INTERNATIONAL];
						goto push;
					case 'l':	/* TM_DEFAULT */
						p = tm_info.format[TM_DEFAULT];
						goto push;
					case 'L':	/* `ls -l' date */
						if (t)
						{
							now = tmxgettime();
							if (warped(t, now))
							{
								p = tm_info.format[TM_DISTANT];
								goto push;
							}
						}
						p = tm_info.format[TM_RECENT];
						goto push;
					case 'o':	/* set options ( %([+-]flag...)o ) */
						if (arg)
						{
							c = '+';
							i = 0;
							for (;;)
							{
								switch (*arg++)
								{
								case 0:
									n = 0;
									break;
								case '=':
									i = !i;
									continue;
								case '+':
								case '-':
								case '!':
									c = *(arg - 1);
									continue;
								case 'l':
									n = TM_LEAP;
									break;
								case 'n':
								case 's':
									n = TM_SUBSECOND;
									break;
								case 'u':
									n = TM_UTC;
									break;
								default:
									continue;
								}
								if (!n)
									break;
					
								/*
								 * right, the global state stinks
								 * but we respect its locale-like status
								 */
					
								if (c == '+')
								{
									if (!(flags & n))
									{
										flags |= n;
										tm_info.flags |= n;
										tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
										if (!i)
											tm_info.flags &= ~n;
									}
								}
								else if (flags & n)
								{
									flags &= ~n;
									tm_info.flags &= ~n;
									tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
									if (!i)
										tm_info.flags |= n;
								}
							}
						}
						break;
					case 'r':	/* `ls -l' recent date */
						p = tm_info.format[TM_RECENT];
						goto push;
					case 'z':	/* time zone nation code */
						if (!(flags & TM_UTC))
						{
							if ((zp = tm->tm_zone) != tm_info.local)
								for (; zp >= tm_data.zone; zp--)
									if (p = zp->type)
										goto string;
							else if (p = zp->type)
								goto string;
						}
						break;
					default:
						format--;
						break;
					}
				}
				else
				{
					if (t)
					{
						now = tmxgettime();
						p = warped(t, now) ? (char*)0 : (char*)format;
					}
					else
						p = (char*)format;
					i = 0;
					while (n = *format)
					{
						format++;
						if (n == c)
						{
							if (!p)
								p = (char*)format;
							if (++i == 2)
								goto push_delimiter;
						}
					}
				}
			}
			continue;
		case 'r':
			p = tm_info.format[TM_MERIDIAN_TIME];
			goto push;
		case 'R':
			p = "%H:%M";
			goto push;
		case 's':	/* (DEFACTO) seconds[.nanoseconds] since the epoch */
		case '#':
			now = t;
			f = fmt;
			*f++ = '%';
			if (pad == '0')
				*f++ = pad;
			if (width)
				f += sfsprintf(f, &fmt[sizeof(fmt)] - f, "%d", width);
			f += sfsprintf(f, &fmt[sizeof(fmt)] - f, "I%du", sizeof(Tmxsec_t));
			cp += sfsprintf(cp, ep - cp, fmt, tmxsec(now));
			if (parts > 1)
			{
				n = sfsprintf(cp, ep - cp, ".%09I*u", sizeof(Tmxnsec_t), tmxnsec(now));
				if (prec && n >= prec)
					n = prec + 1;
				cp += n;
			}
			continue;
		case 'S':	/* seconds */
			cp = number(cp, ep, (long)tm->tm_sec, 2, width, pad);
			if ((flags & TM_SUBSECOND) && (format - 2) != oformat)
			{
				p = ".%N";
				goto push;
			}
			continue;
		case 't':
			if (cp < ep)
				*cp++ = '\t';
			continue;
		case 'T':
			p = tm_info.format[TM_TIME];
			goto push;
		case 'u':	/* weekday number [1(Monday)-7] */
			if (!(i = tm->tm_wday))
				i = 7;
			cp = number(cp, ep, (long)i, 0, width, pad);
			continue;
		case 'U':	/* week number, Sunday as first day */
			cp = number(cp, ep, (long)tmweek(tm, 0, -1, -1), 2, width, pad);
			continue;
#if 0
		case 'v':	/* (UNUSED) */
			continue;
#endif
		case 'V':	/* ISO week number */
			cp = number(cp, ep, (long)tmweek(tm, 2, -1, -1), 2, width, pad);
			continue;
		case 'W':	/* week number, Monday as first day */
			cp = number(cp, ep, (long)tmweek(tm, 1, -1, -1), 2, width, pad);
			continue;
		case 'w':	/* weekday number [0(Sunday)-6] */
			cp = number(cp, ep, (long)tm->tm_wday, 0, width, pad);
			continue;
		case 'x':
			p = tm_info.format[TM_DATE];
			goto push;
		case 'X':
			p = tm_info.format[TM_TIME];
			goto push;
		case 'y':	/* year in the form yy */
			cp = number(cp, ep, (long)(tm->tm_year % 100), 2, width, pad);
			continue;
		case 'Y':	/* year in the form ccyy */
			cp = number(cp, ep, (long)(1900 + tm->tm_year), 4, width, pad);
			continue;
		case 'z':	/* time zone west offset */
			if (arg)
			{
				if ((zp = tmzone(arg, &f, 0, 0)) && !*f && tm->tm_zone != zp)
					tm = tmxtm(tm, tmxtime(tm, tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0)), zp);
				continue;
			}
			if ((ep - cp) >= 16)
				cp = tmpoff(cp, ep - cp, "", (flags & TM_UTC) ? 0 : tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0), pad == '_' ? -24 * 60 : 24 * 60);
			continue;
		case 'Z':	/* time zone */
			if (arg)
			{
				if ((zp = tmzone(arg, &f, 0, 0)) && !*f && tm->tm_zone != zp)
					tm = tmxtm(tm, tmxtime(tm, tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0)), zp);
				continue;
			}
			p = (flags & TM_UTC) ? tm_info.format[TM_UT] : tm->tm_isdst && tm->tm_zone->daylight ? tm->tm_zone->daylight : tm->tm_zone->standard;
			goto string;
		case '=':	/* (AST) OBSOLETE use %([+-]flag...)Qo (old %=[=][+-]flag) */
			for (arg = argbuf; *format == '=' || *format == '-' || *format == '+' || *format == '!'; format++)
				if (arg < &argbuf[sizeof(argbuf) - 2])
					*arg++ = *format;
			if (*arg++ = *format)
				format++;
			*arg = 0;
			arg = argbuf;
			goto options;
		default:
			if (cp < ep)
				*cp++ = '%';
			if (cp < ep)
				*cp++ = c;
			continue;
		}
	index:
		p = tm_info.format[n];
	string:
		while (cp < ep && (*cp = *p++))
			cp++;
		continue;
	options:
		c = '+';
		i = 0;
		for (;;)
		{
			switch (*arg++)
			{
			case 0:
				n = 0;
				break;
			case '=':
				i = !i;
				continue;
			case '+':
			case '-':
			case '!':
				c = *(arg - 1);
				continue;
			case 'l':
				n = TM_LEAP;
				break;
			case 'n':
			case 's':
				n = TM_SUBSECOND;
				break;
			case 'u':
				n = TM_UTC;
				break;
			default:
				continue;
			}
			if (!n)
				break;

			/*
			 * right, the global state stinks
			 * but we respect its locale-like status
			 */

			if (c == '+')
			{
				if (!(flags & n))
				{
					flags |= n;
					tm_info.flags |= n;
					tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
					if (!i)
						tm_info.flags &= ~n;
				}
			}
			else if (flags & n)
			{
				flags &= ~n;
				tm_info.flags &= ~n;
				tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
				if (!i)
					tm_info.flags |= n;
			}
		}
		continue;
	push:
		c = 0;
	push_delimiter:
		if (sp < &stack[elementsof(stack)])
		{
			sp->format = (char*)format;
			format = p;
			sp->delimiter = delimiter;
			delimiter = c;
			sp++;
		}
		continue;
	}
	tm_info.flags = flags;
	if (cp >= ep)
		cp = ep - 1;
	*cp = 0;
	return cp;
}
Esempio n. 7
0
Tm_t*
tmxtm(register Tm_t* tm, Time_t t, Tm_zone_t* zone)
{
	register struct tm*	tp;
	register Tm_leap_t*	lp;
	Time_t			x;
	time_t			now;
	int			leapsec;
	int			y;
	uint32_t		n;
	int32_t			o;
#if TMX_FLOAT
	Time_t			z;
	uint32_t		i;
#endif

	tmset(tm_info.zone);
	leapsec = 0;
	if ((tm_info.flags & (TM_ADJUST|TM_LEAP)) == (TM_ADJUST|TM_LEAP) && (n = tmxsec(t)))
	{
		for (lp = &tm_data.leap[0]; n < lp->time; lp++);
		if (lp->total)
		{
			if (n == lp->time && (leapsec = (lp->total - (lp+1)->total)) < 0)
				leapsec = 0;
			t = tmxsns(n - lp->total, tmxnsec(t));
		}
	}
	x = tmxsec(t);
	if (!(tm->tm_zone = zone))
	{
		if (tm_info.flags & TM_UTC)
			tm->tm_zone = &tm_data.zone[2];
		else
			tm->tm_zone = tm_info.zone;
	}
	if ((o = 60 * tm->tm_zone->west) && x > o)
	{
		x -= o;
		o = 0;
	}
#if TMX_FLOAT
	i = x / (24 * 60 * 60);
	z = i;
	n = x - z * (24 * 60 * 60);
	tm->tm_sec = n % 60 + leapsec;
	n /= 60;
	tm->tm_min = n % 60;
	n /= 60;
	tm->tm_hour = n % 24;
#define x	i
#else
	tm->tm_sec = x % 60 + leapsec;
	x /= 60;
	tm->tm_min = x % 60;
	x /= 60;
	tm->tm_hour = x % 24;
	x /= 24;
#endif
	tm->tm_wday = (x + 4) % 7;
	tm->tm_year = (400 * (x + 25202)) / 146097 + 1;
	n = tm->tm_year - 1;
	x -= n * 365 + n / 4 - n / 100 + (n + (1900 - 1600)) / 400 - (1970 - 1901) * 365 - (1970 - 1901) / 4;
	tm->tm_mon = 0;
	tm->tm_mday = x + 1;
	tm->tm_nsec = tmxnsec(t);
	tmfix(tm);
	n += 1900;
	tm->tm_isdst = 0;
	if (tm->tm_zone->daylight)
	{
		if ((y = tmequiv(tm) - 1900) == tm->tm_year)
			now = tmxsec(t);
		else
		{
			Tm_t	te;

			te = *tm;
			te.tm_year = y;
			now = tmxsec(tmxtime(&te, tm->tm_zone->west));
		}
		if ((tp = tmlocaltime(&now)) && ((tm->tm_isdst = tp->tm_isdst) || o))
		{
			tm->tm_min -= o / 60 + (tm->tm_isdst ? tm->tm_zone->dst : 0);
			tmfix(tm);
		}
	}
	return tm;
}
Esempio n. 8
0
time_t
tmleap(register time_t* clock)
{
	return tmxsec(tmxleap(tmxclock(clock)));
}
Esempio n. 9
0
time_t
tmscan(const char* s, char** e, const char* format, char** f, time_t* clock, long flags)
{
	return tmxsec(tmxscan(s, e, format, f, tmxclock(clock), flags));
}