|
|
1.1 root 1: /*
2: * Copyright (c) 1989 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #if defined(LIBC_SCCS) && !defined(lint)
21: static char sccsid[] = "@(#)strftime.c 5.8 (Berkeley) 6/1/90";
22: #endif /* LIBC_SCCS and not lint */
23:
24: #include <sys/types.h>
25: #include <sys/time.h>
26: #include <tzfile.h>
27: #include <string.h>
28:
29: static char *afmt[] = {
30: "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
31: };
32: static char *Afmt[] = {
33: "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday",
34: "Saturday",
35: };
36: static char *bfmt[] = {
37: "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep",
38: "Oct", "Nov", "Dec",
39: };
40: static char *Bfmt[] = {
41: "January", "February", "March", "April", "May", "June", "July",
42: "August", "September", "October", "November", "December",
43: };
44:
45: static size_t gsize;
46: static char *pt;
47:
48: size_t
49: strftime(s, maxsize, format, t)
50: char *s;
51: char *format;
52: size_t maxsize;
53: struct tm *t;
54: {
55: size_t _fmt();
56:
57: pt = s;
58: if ((gsize = maxsize) < 1)
59: return(0);
60: if (_fmt(format, t)) {
61: *pt = '\0';
62: return(maxsize - gsize);
63: }
64: return(0);
65: }
66:
67: static size_t
68: _fmt(format, t)
69: register char *format;
70: struct tm *t;
71: {
72: for (; *format; ++format) {
73: if (*format == '%')
74: switch(*++format) {
75: case '\0':
76: --format;
77: break;
78: case 'A':
79: if (t->tm_wday < 0 || t->tm_wday > 6)
80: return(0);
81: if (!_add(Afmt[t->tm_wday]))
82: return(0);
83: continue;
84: case 'a':
85: if (t->tm_wday < 0 || t->tm_wday > 6)
86: return(0);
87: if (!_add(afmt[t->tm_wday]))
88: return(0);
89: continue;
90: case 'B':
91: if (t->tm_mon < 0 || t->tm_mon > 11)
92: return(0);
93: if (!_add(Bfmt[t->tm_mon]))
94: return(0);
95: continue;
96: case 'b':
97: case 'h':
98: if (t->tm_mon < 0 || t->tm_mon > 11)
99: return(0);
100: if (!_add(bfmt[t->tm_mon]))
101: return(0);
102: continue;
103: case 'C':
104: if (!_fmt("%a %b %e %H:%M:%S %Y", t))
105: return(0);
106: continue;
107: case 'c':
108: if (!_fmt("%m/%d/%y %H:%M:%S", t))
109: return(0);
110: continue;
111: case 'e':
112: if (!_conv(t->tm_mday, 2, ' '))
113: return(0);
114: continue;
115: case 'D':
116: if (!_fmt("%m/%d/%y", t))
117: return(0);
118: continue;
119: case 'd':
120: if (!_conv(t->tm_mday, 2, '0'))
121: return(0);
122: continue;
123: case 'H':
124: if (!_conv(t->tm_hour, 2, '0'))
125: return(0);
126: continue;
127: case 'I':
128: if (!_conv(t->tm_hour % 12 ?
129: t->tm_hour % 12 : 12, 2, '0'))
130: return(0);
131: continue;
132: case 'j':
133: if (!_conv(t->tm_yday + 1, 3, '0'))
134: return(0);
135: continue;
136: case 'k':
137: if (!_conv(t->tm_hour, 2, ' '))
138: return(0);
139: continue;
140: case 'l':
141: if (!_conv(t->tm_hour % 12 ?
142: t->tm_hour % 12 : 12, 2, ' '))
143: return(0);
144: continue;
145: case 'M':
146: if (!_conv(t->tm_min, 2, '0'))
147: return(0);
148: continue;
149: case 'm':
150: if (!_conv(t->tm_mon + 1, 2, '0'))
151: return(0);
152: continue;
153: case 'n':
154: if (!_add("\n"))
155: return(0);
156: continue;
157: case 'p':
158: if (!_add(t->tm_hour >= 12 ? "PM" : "AM"))
159: return(0);
160: continue;
161: case 'R':
162: if (!_fmt("%H:%M", t))
163: return(0);
164: continue;
165: case 'r':
166: if (!_fmt("%I:%M:%S %p", t))
167: return(0);
168: continue;
169: case 'S':
170: if (!_conv(t->tm_sec, 2, '0'))
171: return(0);
172: continue;
173: case 'T':
174: case 'X':
175: if (!_fmt("%H:%M:%S", t))
176: return(0);
177: continue;
178: case 't':
179: if (!_add("\t"))
180: return(0);
181: continue;
182: case 'U':
183: if (!_conv((t->tm_yday + 7 - t->tm_wday) / 7,
184: 2, '0'))
185: return(0);
186: continue;
187: case 'W':
188: if (!_conv((t->tm_yday + 7 -
189: (t->tm_wday ? (t->tm_wday - 1) : 6))
190: / 7, 2, '0'))
191: return(0);
192: continue;
193: case 'w':
194: if (!_conv(t->tm_wday, 1, '0'))
195: return(0);
196: continue;
197: case 'x':
198: if (!_fmt("%m/%d/%y", t))
199: return(0);
200: continue;
201: case 'y':
202: if (!_conv((t->tm_year + TM_YEAR_BASE)
203: % 100, 2, '0'))
204: return(0);
205: continue;
206: case 'Y':
207: if (!_conv(t->tm_year + TM_YEAR_BASE, 4, '0'))
208: return(0);
209: continue;
210: case 'Z':
211: if (!t->tm_zone || !_add(t->tm_zone))
212: return(0);
213: continue;
214: case '%':
215: /*
216: * X311J/88-090 (4.12.3.5): if conversion char is
217: * undefined, behavior is undefined. Print out the
218: * character itself as printf(3) does.
219: */
220: default:
221: break;
222: }
223: if (!gsize--)
224: return(0);
225: *pt++ = *format;
226: }
227: return(gsize);
228: }
229:
230: static
231: _conv(n, digits, pad)
232: int n, digits;
233: char pad;
234: {
235: static char buf[10];
236: register char *p;
237:
238: for (p = buf + sizeof(buf) - 2; n > 0 && p > buf; n /= 10, --digits)
239: *p-- = n % 10 + '0';
240: while (p > buf && digits-- > 0)
241: *p-- = pad;
242: return(_add(++p));
243: }
244:
245: static
246: _add(str)
247: register char *str;
248: {
249: for (;; ++pt, --gsize) {
250: if (!gsize)
251: return(0);
252: if (!(*pt = *str++))
253: return(1);
254: }
255: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.