Mercurial > emacs
annotate src/vmstime.c @ 24206:d3649b38bb37
(w32_wnd_proc): Fix bug introduced by previous change;
the lwindow, rwindow and apps keys could not be used as function
keys, because they were being passed to TranslateMessage which
ignores them. Also, key was being changed to SPC.
author | Andrew Innes <andrewi@gnu.org> |
---|---|
date | Wed, 27 Jan 1999 21:53:27 +0000 |
parents | 2bf083a9ad6a |
children |
rev | line source |
---|---|
2176 | 1 /* Time support for VMS. |
2 Copyright (C) 1993 Free Software Foundation. | |
3 | |
4 This file is part of GNU Emacs. | |
5 | |
6 GNU Emacs is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 2, or (at your option) | |
9 any later version. | |
10 | |
11 GNU Emacs is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
14186
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
4696
diff
changeset
|
18 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
ee40177f6c68
Update FSF's address in the preamble.
Erik Naggum <erik@naggum.no>
parents:
4696
diff
changeset
|
19 Boston, MA 02111-1307, USA. */ |
2176 | 20 |
4696
1fc792473491
Include <config.h> instead of "config.h".
Roland McGrath <roland@gnu.org>
parents:
2176
diff
changeset
|
21 #include <config.h> |
2174 | 22 #include "vmstime.h" |
23 | |
24 long timezone=0; | |
25 int daylight=0; | |
26 | |
27 static char tzname_default[20]=""; | |
28 static char tzname_dst[20]=""; | |
29 | |
30 char *tzname[2] = { tzname_default, tzname_dst }; | |
31 | |
32 static long internal_daylight=0; | |
33 static char daylight_set=0; | |
34 | |
35 static long read_time(const char *nptr, const char **endptr, | |
36 int sign_allowed_p) | |
37 { | |
38 int t; | |
39 | |
40 *endptr = nptr; | |
41 | |
42 /* This routine trusts the user very much, and does no checks! | |
43 The only exception is this: */ | |
44 if (!sign_allowed_p && (*nptr == '-' || *nptr == '+')) | |
45 return 0; | |
46 | |
47 t = strtol(*endptr, endptr, 10) * 3600; | |
48 if (**endptr != ':' || **endptr == '+' || **endptr == '-') | |
49 return t; | |
50 (*endptr)++; | |
51 | |
52 t = t + strtol(*endptr, endptr, 10) * 60; | |
53 if (**endptr != ':' || **endptr == '+' || **endptr == '-') | |
54 return t; | |
55 (*endptr)++; | |
56 | |
57 return t + strtol(*endptr, endptr, 10); | |
58 } | |
59 | |
60 static void read_dst_time(const char *nptr, const char **endptr, | |
61 int *m, int *n, int *d, | |
62 int *leap_p) | |
63 { | |
64 time_t bintim = time(0); | |
65 struct tm *lc = localtime(&bintim); | |
66 | |
67 *leap_p = 1; | |
68 *m = 0; /* When m and n are 0, a Julian */ | |
69 *n = 0; /* date has been inserted in d */ | |
70 | |
71 switch(*nptr) | |
72 { | |
73 case 'M': | |
74 { | |
75 /* This routine counts on the user to have specified "Mm.n.d", | |
76 where 1 <= n <= 5, 1 <= m <= 12, 0 <= d <= 6 */ | |
77 | |
78 *m = strtol(++nptr, endptr, 10); | |
79 (*endptr)++; /* Skip the dot */ | |
80 *n = strtol(*endptr, endptr, 10); | |
81 (*endptr)++; /* Skip the dot */ | |
82 *d = strtol(*endptr, endptr, 10); | |
83 | |
84 return; | |
85 } | |
86 case 'J': | |
87 *leap_p = 0; /* Never count with leap years */ | |
88 default: /* trust the user to have inserted a number! */ | |
89 *d = strtol(++nptr, endptr, 10); | |
90 return; | |
91 } | |
92 } | |
93 | |
94 struct vms_vectim | |
95 { | |
96 short year, month, day, hour, minute, second, centi_second; | |
97 }; | |
98 static void find_dst_time(int m, int n, long d, | |
99 int hour, int minute, int second, | |
100 int leap_p, | |
101 long vms_internal_time[2]) | |
102 { | |
103 long status = SYS$GETTIM(vms_internal_time); | |
104 struct vms_vectim vms_vectime; | |
105 status = SYS$NUMTIM(&vms_vectime, vms_internal_time); | |
106 | |
107 if (m == 0 && n == 0) | |
108 { | |
109 long tmp_vms_internal_time[2][2]; | |
110 long day_of_year; | |
111 long tmp_operation = LIB$K_DAY_OF_YEAR; | |
112 | |
113 status = LIB$CVT_FROM_INTERNAL_TIME(&tmp_operation, &day_of_year, | |
114 vms_internal_time); | |
115 | |
116 vms_vectime.month = 2; | |
117 vms_vectime.day = 29; | |
118 status = LIB$CVT_VECTIM(&vms_vectime, tmp_vms_internal_time[0]); | |
119 if (status & 1) /* This is a leap year */ | |
120 { | |
121 if (!leap_p && d > 59) | |
122 d ++; /* If we don't count with 29th Feb, | |
123 and this is a leap year, count up, | |
124 to make day 60 really become the | |
125 1st March. */ | |
126 } | |
127 /* 1st January, at midnight */ | |
128 vms_vectime.month = 1; | |
129 vms_vectime.day = 1; | |
130 vms_vectime.hour = hour; | |
131 vms_vectime.minute = minute; | |
132 vms_vectime.second = second; | |
133 vms_vectime.centi_second = 0; | |
134 status = LIB$CVT_VECTIM(&vms_vectime, tmp_vms_internal_time[0]); | |
135 tmp_operation = LIB$K_DELTA_DAYS; | |
136 status = LIB$CVT_TO_INTERNAL_TIME(&tmp_operation, &d, | |
137 tmp_vms_internal_time[1]); | |
138 /* now, tmp_vms_interval_time[0] contains 1st Jan, 00:00:00, | |
139 and tmp_vms_interval_time[1] contains delta time +d days. | |
140 Let's just add them together */ | |
141 status = LIB$ADD_TIMES(tmp_vms_internal_time[0], | |
142 tmp_vms_internal_time[1], | |
143 vms_internal_time); | |
144 } | |
145 else | |
146 { | |
147 long tmp_vms_internal_time[2]; | |
148 long day_of_week; | |
149 long tmp_operation = LIB$K_DAY_OF_YEAR; | |
150 | |
151 if (d == 0) /* 0 is Sunday, which isn't compatible with VMS, | |
152 where day_of_week is 1 -- 7, and 1 is Monday */ | |
153 { | |
154 d = 7; /* So a simple conversion is required */ | |
155 } | |
156 vms_vectime.month = m; | |
157 vms_vectime.day = 1; | |
158 vms_vectime.hour = hour; | |
159 vms_vectime.minute = minute; | |
160 vms_vectime.second = second; | |
161 vms_vectime.centi_second = 0; | |
162 status = LIB$CVT_VECTIM(&vms_vectime, tmp_vms_internal_time); | |
163 tmp_operation = LIB$K_DAY_OF_WEEK; | |
164 status = LIB$CVT_FROM_INTERNAL_TIME(&tmp_operation, &day_of_week, | |
165 tmp_vms_internal_time); | |
166 d -= day_of_week; | |
167 if (d < 0) | |
168 { | |
169 d += 7; | |
170 } | |
171 vms_vectime.day += (n-1)*7 + d; | |
172 status = LIB$CVT_VECTIM(&vms_vectime, vms_internal_time); | |
173 if (!(status & 1)) | |
174 { | |
175 vms_vectime.day -= 7; /* n was probably 5 */ | |
176 status = LIB$CVT_VECTIM(&vms_vectime, vms_internal_time); | |
177 } | |
178 } | |
179 } | |
180 | |
181 static cmp_vms_internal_times(long vms_internal_time1[2], | |
182 long vms_internal_time2[2]) | |
183 { | |
184 if (vms_internal_time1[1] < vms_internal_time2[1]) | |
185 return -1; | |
186 else | |
187 if (vms_internal_time1[1] > vms_internal_time2[1]) | |
188 return 1; | |
189 | |
190 if (vms_internal_time1[0] < vms_internal_time2[0]) | |
191 return -1; | |
192 else | |
193 if (vms_internal_time1[0] > vms_internal_time2[0]) | |
194 return 1; | |
195 | |
196 return 0; | |
197 } | |
198 | |
199 /* -------------------------- Global routines ------------------------------ */ | |
200 | |
201 #ifdef tzset | |
202 #undef tzset | |
203 #endif | |
204 void sys_tzset() | |
205 { | |
206 char *TZ; | |
207 char *p, *q; | |
208 | |
209 if (daylight_set) | |
210 return; | |
211 | |
212 daylight = 0; | |
213 | |
214 if ((TZ = getenv("TZ")) == 0) | |
215 return; | |
216 | |
217 p = TZ; | |
218 q = tzname[0]; | |
219 | |
220 while(*p != '\0' | |
221 && (*p <'0' || *p > '9') && *p != '-' && *p != '+' && *p != ',') | |
222 *q++ = *p++; | |
223 *q = '\0'; | |
224 | |
225 /* This is special for VMS, so I don't care if it doesn't exist anywhere | |
226 else */ | |
227 | |
228 timezone = read_time(p, &p, 1); | |
229 | |
230 q = tzname[1]; | |
231 | |
232 while(*p != '\0' | |
233 && (*p <'0' || *p > '9') && *p != '-' && *p != '+' && *p != ',') | |
234 *q++ = *p++; | |
235 *q = '\0'; | |
236 | |
237 if (*p != '-' && *p != '+' && !(*p >='0' && *p <= '9')) | |
238 internal_daylight = timezone - 3600; | |
239 else | |
240 internal_daylight = read_time(p, &p, 1); | |
241 | |
242 if (*p == ',') | |
243 { | |
244 int start_m; | |
245 int start_n; | |
246 int start_d; | |
247 int start_leap_p; | |
248 int start_hour=2, start_minute=0, start_second=0; | |
249 | |
250 p++; | |
251 read_dst_time(p, &p, &start_m, &start_n, &start_d, &start_leap_p); | |
252 if (*p == '/') | |
253 { | |
254 long tmp = read_time (++p, &p, 0); | |
255 start_hour = tmp / 3600; | |
256 start_minute = (tmp % 3600) / 60; | |
257 start_second = tmp % 60; | |
258 } | |
259 if (*p == ',') | |
260 { | |
261 int end_m; | |
262 int end_n; | |
263 int end_d; | |
264 int end_leap_p; | |
265 int end_hour=2, end_minute=0, end_second=0; | |
266 | |
267 p++; | |
268 read_dst_time(p, &p, &end_m, &end_n, &end_d, &end_leap_p); | |
269 if (*p == '/') | |
270 { | |
271 long tmp = read_time (++p, &p, 0); | |
272 end_hour = tmp / 3600; | |
273 end_minute = (tmp % 3600) / 60; | |
274 end_second = tmp % 60; | |
275 } | |
276 { | |
277 long vms_internal_time[3][2]; | |
278 find_dst_time(start_m, start_n, start_d, | |
279 start_hour, start_minute, start_second, | |
280 start_leap_p, | |
281 vms_internal_time[0]); | |
282 SYS$GETTIM(&vms_internal_time[1]); | |
283 find_dst_time(end_m, end_n, end_d, | |
284 end_hour, end_minute, end_second, | |
285 end_leap_p, | |
286 vms_internal_time[2]); | |
287 if (cmp_vms_internal_times(vms_internal_time[0], | |
288 vms_internal_time[1]) < 0 | |
289 && cmp_vms_internal_times(vms_internal_time[1], | |
290 vms_internal_time[2]) < 0) | |
291 daylight = 1; | |
292 } | |
293 } | |
294 } | |
295 } | |
296 | |
297 #ifdef localtime | |
298 #undef localtime | |
299 #endif | |
300 struct tm *sys_localtime(time_t *clock) | |
301 { | |
302 struct tm *tmp = localtime(clock); | |
303 | |
304 sys_tzset(); | |
305 tmp->tm_isdst = daylight; | |
306 | |
307 return tmp; | |
308 } | |
309 | |
310 #ifdef gmtime | |
311 #undef gmtime | |
312 #endif | |
313 struct tm *sys_gmtime(time_t *clock) | |
314 { | |
315 static struct tm gmt; | |
316 struct vms_vectim tmp_vectime; | |
317 long vms_internal_time[3][2]; | |
318 long tmp_operation = LIB$K_DELTA_SECONDS; | |
319 long status; | |
320 long tmp_offset; | |
321 char tmp_o_sign; | |
322 | |
323 sys_tzset(); | |
324 | |
325 if (daylight) | |
326 tmp_offset = internal_daylight; | |
327 else | |
328 tmp_offset = timezone; | |
329 | |
330 if (tmp_offset < 0) | |
331 { | |
332 tmp_o_sign = -1; | |
333 tmp_offset = -tmp_offset; | |
334 } | |
335 else | |
336 tmp_o_sign = 1; | |
337 | |
338 status = LIB$CVT_TO_INTERNAL_TIME(&tmp_operation, &tmp_offset, | |
339 vms_internal_time[1]); | |
340 status = SYS$GETTIM(vms_internal_time[0]); | |
341 if (tmp_o_sign < 0) | |
342 { | |
343 status = LIB$SUB_TIMES(vms_internal_time[0], | |
344 vms_internal_time[1], | |
345 vms_internal_time[2]); | |
346 } | |
347 else | |
348 { | |
349 status = LIB$ADD_TIMES(vms_internal_time[0], | |
350 vms_internal_time[1], | |
351 vms_internal_time[2]); | |
352 } | |
353 | |
354 status = SYS$NUMTIM(&tmp_vectime, vms_internal_time[2]); | |
355 gmt.tm_sec = tmp_vectime.second; | |
356 gmt.tm_min = tmp_vectime.minute; | |
357 gmt.tm_hour = tmp_vectime.hour; | |
358 gmt.tm_mday = tmp_vectime.day; | |
359 gmt.tm_mon = tmp_vectime.month - 1; | |
15666
2bf083a9ad6a
(sys_gmtime): Don't assume year < 2000.
Karl Heuer <kwzh@gnu.org>
parents:
14186
diff
changeset
|
360 gmt.tm_year = tmp_vectime.year - 1900; |
2174 | 361 |
362 tmp_operation = LIB$K_DAY_OF_WEEK; | |
363 status = LIB$CVT_FROM_INTERNAL_TIME(&tmp_operation, | |
364 &gmt.tm_wday, | |
365 vms_internal_time[2]); | |
366 if (gmt.tm_wday == 7) gmt.tm_wday = 0; | |
367 | |
368 tmp_operation = LIB$K_DAY_OF_YEAR; | |
369 status = LIB$CVT_FROM_INTERNAL_TIME(&tmp_operation, | |
370 &gmt.tm_yday, | |
371 vms_internal_time[2]); | |
372 gmt.tm_yday--; | |
373 gmt.tm_isdst = daylight; | |
374 | |
375 return &gmt; | |
376 } | |
377 |