14887Schin /***********************************************************************
24887Schin * *
34887Schin * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
54887Schin * and is licensed under the *
64887Schin * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
84887Schin * *
94887Schin * A copy of the License is available at *
104887Schin * http://www.opensource.org/licenses/cpl1.0.txt *
114887Schin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
124887Schin * *
134887Schin * Information and Software Systems Research *
144887Schin * AT&T Research *
154887Schin * Florham Park NJ *
164887Schin * *
174887Schin * Glenn Fowler <gsf@research.att.com> *
184887Schin * David Korn <dgk@research.att.com> *
194887Schin * Phong Vo <kpv@research.att.com> *
204887Schin * *
214887Schin ***********************************************************************/
224887Schin #pragma prototyped
234887Schin /*
244887Schin * Glenn Fowler
254887Schin * AT&T Research
264887Schin *
274887Schin * Time_t conversion support
284887Schin */
294887Schin
304887Schin #include <tmx.h>
314887Schin #include <ctype.h>
324887Schin
334887Schin #define warped(t,n) ((t)<((n)-tmxsns(6L*30L*24L*60L*60L,0))||(t)>((n)+tmxsns(24L*60L*60L,0)))
344887Schin
354887Schin /*
364887Schin * format n with padding p into s
374887Schin * return end of s
384887Schin *
394887Schin * p: <0 blank padding
404887Schin * 0 no padding
414887Schin * >0 0 padding
424887Schin */
434887Schin
444887Schin static char*
number(register char * s,register char * e,register long n,register int p,int w,int pad)454887Schin number(register char* s, register char* e, register long n, register int p, int w, int pad)
464887Schin {
474887Schin char* b;
484887Schin
498462SApril.Chin@Sun.COM if (w)
508462SApril.Chin@Sun.COM {
518462SApril.Chin@Sun.COM if (p > 0 && (pad == 0 || pad == '0'))
528462SApril.Chin@Sun.COM while (w > p)
538462SApril.Chin@Sun.COM {
548462SApril.Chin@Sun.COM p++;
558462SApril.Chin@Sun.COM n *= 10;
568462SApril.Chin@Sun.COM }
578462SApril.Chin@Sun.COM else if (w > p)
588462SApril.Chin@Sun.COM p = w;
598462SApril.Chin@Sun.COM }
604887Schin switch (pad)
614887Schin {
624887Schin case '-':
634887Schin p = 0;
644887Schin break;
654887Schin case '_':
664887Schin if (p > 0)
674887Schin p = -p;
684887Schin break;
694887Schin case '0':
704887Schin if (p < 0)
714887Schin p = -p;
724887Schin break;
734887Schin }
744887Schin b = s;
754887Schin if (p > 0)
764887Schin s += sfsprintf(s, e - s, "%0*lu", p, n);
774887Schin else if (p < 0)
784887Schin s += sfsprintf(s, e - s, "%*lu", -p, n);
794887Schin else
804887Schin s += sfsprintf(s, e - s, "%lu", n);
814887Schin if (w && (s - b) > w)
824887Schin *(s = b + w) = 0;
834887Schin return s;
844887Schin }
854887Schin
864887Schin typedef struct Stack_s
874887Schin {
884887Schin char* format;
894887Schin int delimiter;
904887Schin } Stack_t;
914887Schin
924887Schin /*
934887Schin * format t into buf of length len
944887Schin * end of buf is returned
954887Schin */
964887Schin
974887Schin char*
tmxfmt(char * buf,size_t len,const char * format,Time_t t)984887Schin tmxfmt(char* buf, size_t len, const char* format, Time_t t)
994887Schin {
1004887Schin register char* cp;
1014887Schin register char* ep;
1024887Schin register char* p;
1034887Schin register int n;
1044887Schin int c;
1054887Schin int i;
1064887Schin int flags;
10710898Sroland.mainz@nrubsig.org int alt;
1084887Schin int pad;
1094887Schin int delimiter;
1104887Schin int width;
1114887Schin int prec;
1124887Schin int parts;
11310898Sroland.mainz@nrubsig.org char* arg;
1144887Schin char* f;
1154887Schin const char* oformat;
11610898Sroland.mainz@nrubsig.org Tm_t* tm;
1174887Schin Tm_zone_t* zp;
1184887Schin Time_t now;
1194887Schin Stack_t* sp;
1204887Schin Stack_t stack[8];
12110898Sroland.mainz@nrubsig.org Tm_t ts;
12210898Sroland.mainz@nrubsig.org char argbuf[256];
1234887Schin char fmt[32];
1244887Schin
1254887Schin tmlocale();
12610898Sroland.mainz@nrubsig.org tm = tmxtm(&ts, t, NiL);
1274887Schin if (!format || !*format)
1284887Schin format = tm_info.deformat;
1294887Schin oformat = format;
1304887Schin flags = tm_info.flags;
1314887Schin sp = &stack[0];
1324887Schin cp = buf;
1334887Schin ep = buf + len;
1344887Schin delimiter = 0;
1354887Schin for (;;)
1364887Schin {
1374887Schin if ((c = *format++) == delimiter)
1384887Schin {
1394887Schin delimiter = 0;
1404887Schin if (sp <= &stack[0])
1414887Schin break;
1424887Schin sp--;
1434887Schin format = sp->format;
1444887Schin delimiter = sp->delimiter;
1454887Schin continue;
1464887Schin }
1474887Schin if (c != '%')
1484887Schin {
1494887Schin if (cp < ep)
1504887Schin *cp++ = c;
1514887Schin continue;
1524887Schin }
15310898Sroland.mainz@nrubsig.org alt = 0;
15410898Sroland.mainz@nrubsig.org arg = 0;
1554887Schin pad = 0;
1564887Schin width = 0;
1574887Schin prec = 0;
1584887Schin parts = 0;
1594887Schin for (;;)
1604887Schin {
1614887Schin switch (c = *format++)
1624887Schin {
1634887Schin case '_':
1644887Schin case '-':
1654887Schin pad = c;
1664887Schin continue;
1674887Schin case 'E':
1684887Schin case 'O':
1694887Schin if (!isalpha(*format))
1704887Schin break;
17110898Sroland.mainz@nrubsig.org alt = c;
1724887Schin continue;
1734887Schin case '0':
1744887Schin if (!parts)
1754887Schin {
1764887Schin pad = c;
1774887Schin continue;
1784887Schin }
1794887Schin /*FALLTHROUGH*/
1804887Schin case '1':
1814887Schin case '2':
1824887Schin case '3':
1834887Schin case '4':
1844887Schin case '5':
1854887Schin case '6':
1864887Schin case '7':
1874887Schin case '8':
1884887Schin case '9':
1894887Schin switch (parts)
1904887Schin {
1914887Schin case 0:
1924887Schin parts++;
1934887Schin /*FALLTHROUGH*/
1944887Schin case 1:
1954887Schin width = width * 10 + (c - '0');
1964887Schin break;
1974887Schin case 2:
1984887Schin prec = prec * 10 + (c - '0');
1994887Schin break;
2004887Schin }
2014887Schin continue;
2024887Schin case '.':
2034887Schin if (!parts++)
2044887Schin parts++;
2054887Schin continue;
20610898Sroland.mainz@nrubsig.org case '(':
20710898Sroland.mainz@nrubsig.org i = 1;
20810898Sroland.mainz@nrubsig.org arg = argbuf;
20910898Sroland.mainz@nrubsig.org for (;;)
21010898Sroland.mainz@nrubsig.org {
21110898Sroland.mainz@nrubsig.org if (!(c = *format++))
21210898Sroland.mainz@nrubsig.org {
21310898Sroland.mainz@nrubsig.org format--;
21410898Sroland.mainz@nrubsig.org break;
21510898Sroland.mainz@nrubsig.org }
21610898Sroland.mainz@nrubsig.org else if (c == '(')
21710898Sroland.mainz@nrubsig.org i++;
21810898Sroland.mainz@nrubsig.org else if (c == ')' && !--i)
21910898Sroland.mainz@nrubsig.org break;
22010898Sroland.mainz@nrubsig.org else if (arg < &argbuf[sizeof(argbuf) - 1])
22110898Sroland.mainz@nrubsig.org *arg++ = c;
22210898Sroland.mainz@nrubsig.org }
22310898Sroland.mainz@nrubsig.org *arg = 0;
22410898Sroland.mainz@nrubsig.org arg = argbuf;
22510898Sroland.mainz@nrubsig.org continue;
2264887Schin default:
2274887Schin break;
2284887Schin }
2294887Schin break;
2304887Schin }
2314887Schin switch (c)
2324887Schin {
2334887Schin case 0:
2344887Schin format--;
2354887Schin continue;
2364887Schin case '%':
2374887Schin if (cp < ep)
2384887Schin *cp++ = '%';
2394887Schin continue;
2404887Schin case '?':
2414887Schin if (tm_info.deformat != tm_info.format[TM_DEFAULT])
2424887Schin format = tm_info.deformat;
2434887Schin else if (!*format)
2444887Schin format = tm_info.format[TM_DEFAULT];
2454887Schin continue;
2464887Schin case 'a': /* abbreviated day of week name */
24710898Sroland.mainz@nrubsig.org n = TM_DAY_ABBREV + tm->tm_wday;
2484887Schin goto index;
2494887Schin case 'A': /* day of week name */
25010898Sroland.mainz@nrubsig.org n = TM_DAY + tm->tm_wday;
2514887Schin goto index;
2524887Schin case 'b': /* abbreviated month name */
2534887Schin case 'h':
25410898Sroland.mainz@nrubsig.org n = TM_MONTH_ABBREV + tm->tm_mon;
2554887Schin goto index;
2564887Schin case 'B': /* month name */
25710898Sroland.mainz@nrubsig.org n = TM_MONTH + tm->tm_mon;
2584887Schin goto index;
2594887Schin case 'c': /* `ctime(3)' date sans newline */
2604887Schin p = tm_info.format[TM_CTIME];
2614887Schin goto push;
2624887Schin case 'C': /* 2 digit century */
26310898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)(1900 + tm->tm_year) / 100, 2, width, pad);
2644887Schin continue;
2654887Schin case 'd': /* day of month */
26610898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_mday, 2, width, pad);
2674887Schin continue;
2684887Schin case 'D': /* date */
2694887Schin p = tm_info.format[TM_DATE];
2704887Schin goto push;
2714887Schin case 'E': /* OBSOLETE no pad day of month */
27210898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_mday, 0, width, pad);
2734887Schin continue;
2744887Schin case 'e': /* blank padded day of month */
27510898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_mday, -2, width, pad);
2764887Schin continue;
2774887Schin case 'f': /* TM_DEFAULT override */
2784887Schin p = tm_info.deformat;
2794887Schin goto push;
2808462SApril.Chin@Sun.COM case 'F': /* ISO 8601:2000 standard date format */
2818462SApril.Chin@Sun.COM p = "%Y-%m-%d";
2824887Schin goto push;
2834887Schin case 'g': /* %V 2 digit year */
2844887Schin case 'G': /* %V 4 digit year */
28510898Sroland.mainz@nrubsig.org n = tm->tm_year + 1900;
28610898Sroland.mainz@nrubsig.org if (tm->tm_yday < 7)
2874887Schin {
28810898Sroland.mainz@nrubsig.org if (tmweek(tm, 2, -1, -1) >= 52)
2894887Schin n--;
2904887Schin }
29110898Sroland.mainz@nrubsig.org else if (tm->tm_yday > 358)
2924887Schin {
29310898Sroland.mainz@nrubsig.org if (tmweek(tm, 2, -1, -1) <= 1)
2944887Schin n++;
2954887Schin }
2964887Schin if (c == 'g')
2974887Schin {
2984887Schin n %= 100;
2994887Schin c = 2;
3004887Schin }
3014887Schin else
3024887Schin c = 4;
3034887Schin cp = number(cp, ep, (long)n, c, width, pad);
3044887Schin continue;
3054887Schin case 'H': /* hour (0 - 23) */
30610898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_hour, 2, width, pad);
3074887Schin continue;
3084887Schin case 'i': /* international `date(1)' date */
3094887Schin p = tm_info.format[TM_INTERNATIONAL];
3104887Schin goto push;
3114887Schin case 'I': /* hour (0 - 12) */
31210898Sroland.mainz@nrubsig.org if ((n = tm->tm_hour) > 12) n -= 12;
3134887Schin else if (n == 0) n = 12;
3144887Schin cp = number(cp, ep, (long)n, 2, width, pad);
3154887Schin continue;
3164887Schin case 'J': /* Julian date (0 offset) */
31710898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_yday, 3, width, pad);
3184887Schin continue;
3194887Schin case 'j': /* Julian date (1 offset) */
32010898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)(tm->tm_yday + 1), 3, width, pad);
3214887Schin continue;
3224887Schin case 'k': /* `date(1)' date */
3234887Schin p = tm_info.format[TM_DATE_1];
3244887Schin goto push;
3254887Schin case 'K':
32610898Sroland.mainz@nrubsig.org switch (alt)
32710898Sroland.mainz@nrubsig.org {
32810898Sroland.mainz@nrubsig.org case 'E':
32910898Sroland.mainz@nrubsig.org p = (pad == '_') ? "%Y-%m-%d %H:%M:%S.%N %z" : "%Y-%m-%d+%H:%M:%S.%N%z";
33010898Sroland.mainz@nrubsig.org break;
33110898Sroland.mainz@nrubsig.org case 'O':
33210898Sroland.mainz@nrubsig.org p = (pad == '_') ? "%Y-%m-%d %H:%M:%S.%N" : "%Y-%m-%d+%H:%M:%S.%N";
33310898Sroland.mainz@nrubsig.org break;
33410898Sroland.mainz@nrubsig.org default:
33510898Sroland.mainz@nrubsig.org p = (pad == '_') ? "%Y-%m-%d %H:%M:%S" : "%Y-%m-%d+%H:%M:%S";
33610898Sroland.mainz@nrubsig.org break;
33710898Sroland.mainz@nrubsig.org }
3384887Schin goto push;
3394887Schin case 'l': /* `ls -l' date */
3404887Schin if (t)
3414887Schin {
3424887Schin now = tmxgettime();
3434887Schin if (warped(t, now))
3444887Schin {
3454887Schin p = tm_info.format[TM_DISTANT];
3464887Schin goto push;
3474887Schin }
3484887Schin }
3494887Schin p = tm_info.format[TM_RECENT];
3504887Schin goto push;
3518462SApril.Chin@Sun.COM case 'L': /* TM_DEFAULT */
3528462SApril.Chin@Sun.COM case 'O': /* OBSOLETE */
3538462SApril.Chin@Sun.COM p = tm_info.format[TM_DEFAULT];
3548462SApril.Chin@Sun.COM goto push;
3554887Schin case 'm': /* month number */
35610898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)(tm->tm_mon + 1), 2, width, pad);
3574887Schin continue;
3584887Schin case 'M': /* minutes */
35910898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_min, 2, width, pad);
3604887Schin continue;
3614887Schin case 'n':
3624887Schin if (cp < ep)
3634887Schin *cp++ = '\n';
3644887Schin continue;
3654887Schin case 'N': /* nanosecond part */
36610898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_nsec, 9, width, pad);
3674887Schin continue;
36810898Sroland.mainz@nrubsig.org case 'o': /* set options */
36910898Sroland.mainz@nrubsig.org if (arg)
37010898Sroland.mainz@nrubsig.org goto options;
37110898Sroland.mainz@nrubsig.org /*OBSOLETE*/
37210898Sroland.mainz@nrubsig.org p = tm_info.deformat;
37310898Sroland.mainz@nrubsig.org goto push;
3744887Schin case 'p': /* meridian */
37510898Sroland.mainz@nrubsig.org n = TM_MERIDIAN + (tm->tm_hour >= 12);
3764887Schin goto index;
3774887Schin case 'q': /* time zone type (nation code) */
3784887Schin if (!(flags & TM_UTC))
3794887Schin {
38010898Sroland.mainz@nrubsig.org if ((zp = tm->tm_zone) != tm_info.local)
3814887Schin for (; zp >= tm_data.zone; zp--)
3824887Schin if (p = zp->type)
3834887Schin goto string;
3844887Schin else if (p = zp->type)
3854887Schin goto string;
3864887Schin }
3874887Schin continue;
3884887Schin case 'Q': /* %Q<alpha> or %Q<delim>recent<delim>distant<delim> */
3894887Schin if (c = *format)
3904887Schin {
3914887Schin format++;
3924887Schin if (isalpha(c))
3934887Schin {
3944887Schin switch (c)
3954887Schin {
3964887Schin case 'd': /* `ls -l' distant date */
3974887Schin p = tm_info.format[TM_DISTANT];
3984887Schin goto push;
3994887Schin case 'r': /* `ls -l' recent date */
4004887Schin p = tm_info.format[TM_RECENT];
4014887Schin goto push;
4024887Schin default:
4034887Schin format--;
4044887Schin break;
4054887Schin }
4064887Schin }
4074887Schin else
4084887Schin {
4094887Schin if (t)
4104887Schin {
4114887Schin now = tmxgettime();
4124887Schin p = warped(t, now) ? (char*)0 : (char*)format;
4134887Schin }
4144887Schin else
4154887Schin p = (char*)format;
4164887Schin i = 0;
4174887Schin while (n = *format)
4184887Schin {
4194887Schin format++;
4204887Schin if (n == c)
4214887Schin {
4224887Schin if (!p)
4234887Schin p = (char*)format;
4244887Schin if (++i == 2)
4254887Schin goto push_delimiter;
4264887Schin }
4274887Schin }
4284887Schin }
4294887Schin }
4304887Schin continue;
4314887Schin case 'r':
4324887Schin p = tm_info.format[TM_MERIDIAN_TIME];
4334887Schin goto push;
4344887Schin case 'R':
4354887Schin p = "%H:%M";
4364887Schin goto push;
4374887Schin case 's': /* seconds[.nanoseconds] since the epoch */
4384887Schin case '#':
43910898Sroland.mainz@nrubsig.org now = t;
4404887Schin f = fmt;
4414887Schin *f++ = '%';
4424887Schin if (pad == '0')
4434887Schin *f++ = pad;
4444887Schin if (width)
4454887Schin f += sfsprintf(f, &fmt[sizeof(fmt)] - f, "%d", width);
4464887Schin f += sfsprintf(f, &fmt[sizeof(fmt)] - f, "I%du", sizeof(Tmxsec_t));
4474887Schin cp += sfsprintf(cp, ep - cp, fmt, tmxsec(now));
4484887Schin if (parts > 1)
4494887Schin {
4504887Schin n = sfsprintf(cp, ep - cp, ".%09I*u", sizeof(Tmxnsec_t), tmxnsec(now));
4514887Schin if (prec && n >= prec)
4524887Schin n = prec + 1;
4534887Schin cp += n;
4544887Schin }
4554887Schin continue;
4564887Schin case 'S': /* seconds */
45710898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_sec, 2, width, pad);
4584887Schin if ((flags & TM_SUBSECOND) && (format - 2) != oformat)
4594887Schin {
4604887Schin p = ".%N";
4614887Schin goto push;
4624887Schin }
4634887Schin continue;
4644887Schin case 't':
4654887Schin if (cp < ep)
4664887Schin *cp++ = '\t';
4674887Schin continue;
4684887Schin case 'T':
4694887Schin p = tm_info.format[TM_TIME];
4704887Schin goto push;
4714887Schin case 'u': /* weekday number [1(Monday)-7] */
47210898Sroland.mainz@nrubsig.org if (!(i = tm->tm_wday))
4734887Schin i = 7;
4744887Schin cp = number(cp, ep, (long)i, 0, width, pad);
4754887Schin continue;
4764887Schin case 'U': /* week number, Sunday as first day */
47710898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tmweek(tm, 0, -1, -1), 2, width, pad);
4784887Schin continue;
4794887Schin case 'V': /* ISO week number */
48010898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tmweek(tm, 2, -1, -1), 2, width, pad);
4814887Schin continue;
4824887Schin case 'W': /* week number, Monday as first day */
48310898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tmweek(tm, 1, -1, -1), 2, width, pad);
4844887Schin continue;
4854887Schin case 'w': /* weekday number [0(Sunday)-6] */
48610898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)tm->tm_wday, 0, width, pad);
4874887Schin continue;
4884887Schin case 'x':
4894887Schin p = tm_info.format[TM_DATE];
4904887Schin goto push;
4914887Schin case 'X':
4924887Schin p = tm_info.format[TM_TIME];
4934887Schin goto push;
4944887Schin case 'y': /* year in the form yy */
49510898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)(tm->tm_year % 100), 2, width, pad);
4964887Schin continue;
4974887Schin case 'Y': /* year in the form ccyy */
49810898Sroland.mainz@nrubsig.org cp = number(cp, ep, (long)(1900 + tm->tm_year), 4, width, pad);
4994887Schin continue;
5004887Schin case 'z': /* time zone west offset */
50110898Sroland.mainz@nrubsig.org if (arg)
50210898Sroland.mainz@nrubsig.org {
50310898Sroland.mainz@nrubsig.org if ((zp = tmzone(arg, &f, 0, 0)) && !*f && tm->tm_zone != zp)
50410898Sroland.mainz@nrubsig.org tm = tmxtm(tm, tmxtime(tm, tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0)), zp);
50510898Sroland.mainz@nrubsig.org continue;
50610898Sroland.mainz@nrubsig.org }
5074887Schin if ((ep - cp) >= 16)
50810898Sroland.mainz@nrubsig.org cp = tmpoff(cp, ep - cp, "", (flags & TM_UTC) ? 0 : tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0), 24 * 60);
5094887Schin continue;
5104887Schin case 'Z': /* time zone */
51110898Sroland.mainz@nrubsig.org if (arg)
51210898Sroland.mainz@nrubsig.org {
51310898Sroland.mainz@nrubsig.org if ((zp = tmzone(arg, &f, 0, 0)) && !*f && tm->tm_zone != zp)
51410898Sroland.mainz@nrubsig.org tm = tmxtm(tm, tmxtime(tm, tm->tm_zone->west + (tm->tm_isdst ? tm->tm_zone->dst : 0)), zp);
51510898Sroland.mainz@nrubsig.org continue;
51610898Sroland.mainz@nrubsig.org }
51710898Sroland.mainz@nrubsig.org p = (flags & TM_UTC) ? tm_info.format[TM_UT] : tm->tm_isdst && tm->tm_zone->daylight ? tm->tm_zone->daylight : tm->tm_zone->standard;
5184887Schin goto string;
5194887Schin case '+': /* old %+flag */
5204887Schin case '!': /* old %!flag */
5214887Schin format--;
5224887Schin /*FALLTHROUGH*/
52310898Sroland.mainz@nrubsig.org case '=': /* old %=[=][+-]flag */
52410898Sroland.mainz@nrubsig.org for (arg = argbuf; *format == '=' || *format == '-' || *format == '+' || *format == '!'; format++)
52510898Sroland.mainz@nrubsig.org if (arg < &argbuf[sizeof(argbuf) - 2])
52610898Sroland.mainz@nrubsig.org *arg++ = *format;
52710898Sroland.mainz@nrubsig.org if (*arg++ = *format)
5284887Schin format++;
52910898Sroland.mainz@nrubsig.org *arg = 0;
53010898Sroland.mainz@nrubsig.org arg = argbuf;
53110898Sroland.mainz@nrubsig.org goto options;
5324887Schin default:
5334887Schin if (cp < ep)
5344887Schin *cp++ = '%';
5354887Schin if (cp < ep)
5364887Schin *cp++ = c;
5374887Schin continue;
5384887Schin }
5394887Schin index:
5404887Schin p = tm_info.format[n];
5414887Schin string:
5424887Schin while (cp < ep && (*cp = *p++))
5434887Schin cp++;
5444887Schin continue;
54510898Sroland.mainz@nrubsig.org options:
54610898Sroland.mainz@nrubsig.org c = '+';
54710898Sroland.mainz@nrubsig.org i = 0;
54810898Sroland.mainz@nrubsig.org for (;;)
54910898Sroland.mainz@nrubsig.org {
55010898Sroland.mainz@nrubsig.org switch (*arg++)
55110898Sroland.mainz@nrubsig.org {
55210898Sroland.mainz@nrubsig.org case 0:
55310898Sroland.mainz@nrubsig.org n = 0;
55410898Sroland.mainz@nrubsig.org break;
55510898Sroland.mainz@nrubsig.org case '=':
55610898Sroland.mainz@nrubsig.org i = !i;
55710898Sroland.mainz@nrubsig.org continue;
55810898Sroland.mainz@nrubsig.org case '+':
55910898Sroland.mainz@nrubsig.org case '-':
56010898Sroland.mainz@nrubsig.org case '!':
56110898Sroland.mainz@nrubsig.org c = *(arg - 1);
56210898Sroland.mainz@nrubsig.org continue;
56310898Sroland.mainz@nrubsig.org case 'l':
56410898Sroland.mainz@nrubsig.org n = TM_LEAP;
56510898Sroland.mainz@nrubsig.org break;
56610898Sroland.mainz@nrubsig.org case 'n':
56710898Sroland.mainz@nrubsig.org case 's':
56810898Sroland.mainz@nrubsig.org n = TM_SUBSECOND;
56910898Sroland.mainz@nrubsig.org break;
57010898Sroland.mainz@nrubsig.org case 'u':
57110898Sroland.mainz@nrubsig.org n = TM_UTC;
57210898Sroland.mainz@nrubsig.org break;
57310898Sroland.mainz@nrubsig.org default:
57410898Sroland.mainz@nrubsig.org continue;
57510898Sroland.mainz@nrubsig.org }
57610898Sroland.mainz@nrubsig.org if (!n)
57710898Sroland.mainz@nrubsig.org break;
57810898Sroland.mainz@nrubsig.org
57910898Sroland.mainz@nrubsig.org /*
58010898Sroland.mainz@nrubsig.org * right, the global state stinks
58110898Sroland.mainz@nrubsig.org * but we respect its locale-like status
58210898Sroland.mainz@nrubsig.org */
58310898Sroland.mainz@nrubsig.org
58410898Sroland.mainz@nrubsig.org if (c == '+')
58510898Sroland.mainz@nrubsig.org {
58610898Sroland.mainz@nrubsig.org if (!(flags & n))
58710898Sroland.mainz@nrubsig.org {
58810898Sroland.mainz@nrubsig.org flags |= n;
58910898Sroland.mainz@nrubsig.org tm_info.flags |= n;
59010898Sroland.mainz@nrubsig.org tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
59110898Sroland.mainz@nrubsig.org if (!i)
59210898Sroland.mainz@nrubsig.org tm_info.flags &= ~n;
59310898Sroland.mainz@nrubsig.org }
59410898Sroland.mainz@nrubsig.org }
59510898Sroland.mainz@nrubsig.org else if (flags & n)
59610898Sroland.mainz@nrubsig.org {
59710898Sroland.mainz@nrubsig.org flags &= ~n;
59810898Sroland.mainz@nrubsig.org tm_info.flags &= ~n;
59910898Sroland.mainz@nrubsig.org tm = tmxtm(tm, t, (flags & TM_UTC) ? &tm_data.zone[2] : tm->tm_zone);
60010898Sroland.mainz@nrubsig.org if (!i)
60110898Sroland.mainz@nrubsig.org tm_info.flags |= n;
60210898Sroland.mainz@nrubsig.org }
60310898Sroland.mainz@nrubsig.org }
60410898Sroland.mainz@nrubsig.org continue;
6054887Schin push:
6064887Schin c = 0;
6074887Schin push_delimiter:
6084887Schin if (sp < &stack[elementsof(stack)])
6094887Schin {
6104887Schin sp->format = (char*)format;
6114887Schin format = p;
6124887Schin sp->delimiter = delimiter;
6134887Schin delimiter = c;
6144887Schin sp++;
6154887Schin }
6164887Schin continue;
6174887Schin }
6184887Schin tm_info.flags = flags;
6194887Schin if (cp >= ep)
6204887Schin cp = ep - 1;
6214887Schin *cp = 0;
6224887Schin return cp;
6234887Schin }
624