stdio: puts() and vprintf()
[neatlibc.git] / strftime.c
blob513e258ccb4c8b4979feb2452bdd4e6ddc85c1a6
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/time.h>
4 #include <time.h>
6 static char *wday_ab[] = {
7 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
8 };
9 static char *wday[] = {
10 "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
12 static char *mon_ab[] = {
13 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
14 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
16 static char *mon[] = {
17 "January", "February", "March", "April", "May", "June",
18 "July", "August", "September", "October", "November", "December"
21 static char *putstr(char *d, char *s)
23 while (*s)
24 *d++ = *s++;
25 return d;
28 static char *puti(char *s, unsigned long n, int wid, int zpad)
30 int i;
31 for (i = wid - 1; i >= 0; i--) {
32 if (!n) {
33 if (!zpad && i < wid - 1)
34 s[i] = ' ';
35 else
36 s[i] = '0';
37 } else {
38 s[i] = '0' + n % 10;
39 n /= 10;
42 return s + wid;
45 static char *puttz(char *s)
47 int d = timezone / 60;
48 if (d < 0) {
49 *s++ = '+';
50 d = -d;
51 } else {
52 *s++ = '-';
54 s = puti(s, d / 60, 2, 1);
55 s = puti(s, d % 60, 2, 1);
56 return s;
59 long strftime(char *s, long n, char *f, struct tm *tm)
61 int val;
62 char *beg = s;
63 char *e = s + n;
64 while (s + 1 < e && *f) {
65 int c = *f++;
66 if (c != '%') {
67 *s++ = c;
68 continue;
70 c = *f++;
71 switch (c) {
72 case '%':
73 *s++ = '%';
74 break;
75 case 'a':
76 s = putstr(s, wday_ab[tm->tm_wday]);
77 break;
78 case 'A':
79 s = putstr(s, wday[tm->tm_wday]);
80 break;
81 case 'b':
82 case 'h':
83 s = putstr(s, mon_ab[tm->tm_mon]);
84 break;
85 case 'B':
86 s = putstr(s, mon[tm->tm_mon]);
87 break;
88 case 'c':
89 s += strftime(s, e - s, "%b %a %d %k:%M:%S %Z %Y", tm);
90 break;
91 case 'C':
92 s = puti(s, (1900 + tm->tm_year) / 100, 2, 1);
93 break;
94 case 'd':
95 s = puti(s, tm->tm_mday, 2, 1);
96 break;
97 case 'D':
98 s += strftime(s, e - s, "%m/%d/%y", tm);
99 break;
100 case 'e':
101 s = puti(s, tm->tm_mday, 2, 0);
102 break;
103 case 'F':
104 s += strftime(s, e - s, "%Y/%m/%d", tm);
105 break;
106 case 'H':
107 s = puti(s, tm->tm_hour, 2, 1);
108 break;
109 case 'I':
110 val = tm->tm_hour > 12 ? tm->tm_hour - 12 : tm->tm_hour;
111 s = puti(s, val ? val : 12, 2, 1);
112 break;
113 case 'j':
114 s = puti(s, tm->tm_yday + 1, 3, 1);
115 break;
116 case 'k':
117 s = puti(s, tm->tm_hour, 2, 1);
118 break;
119 case 'm':
120 s = puti(s, tm->tm_mon + 1, 2, 1);
121 break;
122 case 'M':
123 s = puti(s, tm->tm_min, 2, 1);
124 break;
125 case 'n':
126 *s++ = '\n';
127 break;
128 case 'p':
129 s = putstr(s, tm->tm_hour >= 12 ? "PM" : "AM");
130 break;
131 case 'P':
132 s = putstr(s, tm->tm_hour >= 12 ? "pm" : "am");
133 break;
134 case 'r':
135 s += strftime(s, e - s, "%I:%M:%S %p", tm);
136 break;
137 case 'R':
138 s += strftime(s, e - s, "%H:%M", tm);
139 break;
140 case 'S':
141 s = puti(s, tm->tm_sec, 2, 1);
142 break;
143 case 't':
144 *s++ = '\t';
145 break;
146 case 'T':
147 s += strftime(s, e - s, "%H:%M:%S", tm);
148 break;
149 case 'u':
150 s = puti(s, tm->tm_wday ? tm->tm_wday : 7, 1, 0);
151 break;
152 case 'w':
153 s = puti(s, tm->tm_wday, 1, 0);
154 break;
155 case 'x':
156 s += strftime(s, e - s, "%b %a %d", tm);
157 break;
158 case 'X':
159 s += strftime(s, e - s, "%k:%M:%S", tm);
160 break;
161 case 'y':
162 s = puti(s, tm->tm_year % 100, 2, 1);
163 break;
164 case 'Y':
165 s = puti(s, 1900 + tm->tm_year, 4, 1);
166 break;
167 case 'z':
168 s = puttz(s);
169 break;
170 default:
171 break;
174 *s = '\0';
175 return s - beg;