panic() cleanup.
[minix.git] / lib / libc / ansi / misc.c
blob9bb320dee1687ddf851dbc410983c9629365a7d2
1 /*
2 * misc - data and miscellaneous routines
3 */
4 /* $Header$ */
6 #include <ctype.h>
7 #include <time.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include "loc_time.h"
13 #define RULE_LEN 120
14 #define TZ_LEN 10
16 /* Make sure that the strings do not end up in ROM.
17 * These strings probably contain the wrong value, and we cannot obtain the
18 * right value from the system. TZ is the only help.
20 static char ntstr[TZ_LEN + 1] = "GMT"; /* string for normal time */
21 static char dststr[TZ_LEN + 1] = "GDT"; /* string for daylight saving */
23 long _timezone = 0;
24 long _dst_off = 60 * 60;
25 int _daylight = 0;
27 long timezone = 0;
28 int daylight = 0;
31 static struct dsttype {
32 char ds_type; /* Unknown, Julian, Zero-based or M */
33 int ds_date[3]; /* months, weeks, days */
34 long ds_sec; /* usually 02:00:00 */
35 } dststart = { 'U', { 0, 0, 0 }, 2 * 60 * 60 }
36 , dstend = { 'U', { 0, 0, 0 }, 2 * 60 * 60 };
38 const char *_days[] = {
39 "Sunday", "Monday", "Tuesday", "Wednesday",
40 "Thursday", "Friday", "Saturday"
43 const char *_months[] = {
44 "January", "February", "March",
45 "April", "May", "June",
46 "July", "August", "September",
47 "October", "November", "December"
50 const int _ytab[2][12] = {
51 { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
52 { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
55 static const char *
56 parseZoneName(register char *buf, register const char *p)
58 register int n = 0;
60 if (*p == ':') return NULL;
61 while (*p && !isdigit(*p) && *p != ',' && *p != '-' && *p != '+') {
62 if (n < TZ_LEN)
63 *buf++ = *p;
64 p++;
65 n++;
67 if (n < 3) return NULL; /* error */
68 *buf = '\0';
69 return p;
72 static const char *
73 parseTime(register long *tm, const char *p, register struct dsttype *dst)
75 register int n = 0;
76 register const char *q = p;
77 char ds_type = (dst ? dst->ds_type : '\0');
79 if (dst) dst->ds_type = 'U';
81 *tm = 0;
82 while(*p >= '0' && *p <= '9') {
83 n = 10 * n + (*p++ - '0');
85 if (q == p) return NULL; /* "The hour shall be required" */
86 if (n < 0 || n >= 24) return NULL;
87 *tm = n * 60 * 60;
88 if (*p == ':') {
89 p++;
90 n = 0;
91 while(*p >= '0' && *p <= '9') {
92 n = 10 * n + (*p++ - '0');
94 if (q == p) return NULL; /* format error */
95 if (n < 0 || n >= 60) return NULL;
96 *tm += n * 60;
97 if (*p == ':') {
98 p++;
99 n = 0;
100 while(*p >= '0' && *p <= '9') {
101 n = 10 * n + (*p++ - '0');
103 if (q == p) return NULL; /* format error */
104 if (n < 0 || n >= 60) return NULL;
105 *tm += n;
108 if (dst) {
109 dst->ds_type = ds_type;
110 dst->ds_sec = *tm;
112 return p;
115 static const char *
116 parseDate(register char *buf, register const char *p, struct dsttype *dstinfo)
118 register const char *q;
119 register int n = 0;
120 int cnt = 0;
121 const int bnds[3][2] = { { 1, 12 },
122 { 1, 5 },
123 { 0, 6}
125 char ds_type;
127 if (*p != 'M') {
128 if (*p == 'J') {
129 *buf++ = *p++;
130 ds_type = 'J';
132 else ds_type = 'Z';
133 q = p;
134 while(*p >= '0' && *p <= '9') {
135 n = 10 * n + (*p - '0');
136 *buf++ = *p++;
138 if (q == p) return NULL; /* format error */
139 if (n < (ds_type == 'J') || n > 365) return NULL;
140 dstinfo->ds_type = ds_type;
141 dstinfo->ds_date[0] = n;
142 return p;
144 ds_type = 'M';
145 do {
146 *buf++ = *p++;
147 q = p;
148 n = 0;
149 while(*p >= '0' && *p <= '9') {
150 n = 10 * n + (*p - '0');
151 *buf++ = *p++;
153 if (q == p) return NULL; /* format error */
154 if (n < bnds[cnt][0] || n > bnds[cnt][1]) return NULL;
155 dstinfo->ds_date[cnt] = n;
156 cnt++;
157 } while (cnt < 3 && *p == '.');
158 if (cnt != 3) return NULL;
159 *buf = '\0';
160 dstinfo->ds_type = ds_type;
161 return p;
164 static const char *
165 parseRule(register char *buf, register const char *p)
167 long time;
168 register const char *q;
170 if (!(p = parseDate(buf, p, &dststart))) return NULL;
171 buf += strlen(buf);
172 if (*p == '/') {
173 q = ++p;
174 if (!(p = parseTime(&time, p, &dststart))) return NULL;
175 while( p != q) *buf++ = *q++;
177 if (*p != ',') return NULL;
178 p++;
179 if (!(p = parseDate(buf, p, &dstend))) return NULL;
180 buf += strlen(buf);
181 if (*p == '/') {
182 q = ++p;
183 if (!(p = parseTime(&time, p, &dstend))) return NULL;
184 while(*buf++ = *q++);
186 if (*p) return NULL;
187 return p;
190 static int
191 last_sunday(register int day, register struct tm *timep)
193 int first = FIRSTSUNDAY(timep);
195 if (day >= 58 && LEAPYEAR(YEAR0 + timep->tm_year)) day++;
196 if (day < first) return first;
197 return day - (day - first) % 7;
200 static int
201 date_of(register struct dsttype *dst, struct tm *timep)
203 int leap = LEAPYEAR(YEAR0 + timep->tm_year);
204 int firstday, tmpday;
205 register int day, month;
207 if (dst->ds_type != 'M') {
208 return dst->ds_date[0] -
209 (dst->ds_type == 'J'
210 && leap
211 && dst->ds_date[0] < 58);
213 day = 0;
214 month = 1;
215 while (month < dst->ds_date[0]) {
216 day += _ytab[leap][month - 1];
217 month++;
219 firstday = (day + FIRSTDAYOF(timep)) % 7;
220 tmpday = day;
221 day += (dst->ds_date[2] - firstday + 7) % 7
222 + 7 * (dst->ds_date[1] - 1);
223 if (day >= tmpday + _ytab[leap][month-1]) day -= 7;
224 return day;