Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / gcc / ada / a-calend-mingw.adb
blob0ec1ca94a8c34dfd16c5492ff24c13bf3c341617
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT RUN-TIME COMPONENTS --
4 -- --
5 -- A D A . C A L E N D A R --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 1997-2005, Free Software Foundation, Inc. --
10 -- --
11 -- GNAT is free software; you can redistribute it and/or modify it under --
12 -- terms of the GNU General Public License as published by the Free Soft- --
13 -- ware Foundation; either version 2, or (at your option) any later ver- --
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
16 -- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
21 -- --
22 -- As a special exception, if other files instantiate generics from this --
23 -- unit, or you link this unit with other files to produce an executable, --
24 -- this unit does not by itself cause the resulting executable to be --
25 -- covered by the GNU General Public License. This exception does not --
26 -- however invalidate any other reasons why the executable file might be --
27 -- covered by the GNU Public License. --
28 -- --
29 -- GNAT was originally developed by the GNAT team at New York University. --
30 -- Extensive contributions were provided by Ada Core Technologies Inc. --
31 -- --
32 ------------------------------------------------------------------------------
34 -- This is the Windows NT/95 version
36 -- Why do we need separate version ???
37 -- Do we need *this* much code duplication???
39 with System.OS_Primitives;
40 -- used for Clock
42 with System.OS_Interface;
44 package body Ada.Calendar is
46 use System.OS_Interface;
48 ------------------------------
49 -- Use of Pragma Unsuppress --
50 ------------------------------
52 -- This implementation of Calendar takes advantage of the permission in
53 -- Ada 95 of using arithmetic overflow checks to check for out of bounds
54 -- time values. This means that we must catch the constraint error that
55 -- results from arithmetic overflow, so we use pragma Unsuppress to make
56 -- sure that overflow is enabled, using software overflow checking if
57 -- necessary. That way, compiling Calendar with options to suppress this
58 -- checking will not affect its correctness.
60 ------------------------
61 -- Local Declarations --
62 ------------------------
64 Ada_Year_Min : constant := 1901;
65 Ada_Year_Max : constant := 2099;
67 -- Win32 time constants
69 epoch_1970 : constant := 16#19D_B1DE_D53E_8000#; -- win32 UTC epoch
70 system_time_ns : constant := 100; -- 100 ns per tick
71 Sec_Unit : constant := 10#1#E9;
73 ---------
74 -- "+" --
75 ---------
77 function "+" (Left : Time; Right : Duration) return Time is
78 pragma Unsuppress (Overflow_Check);
79 begin
80 return (Left + Time (Right));
82 exception
83 when Constraint_Error =>
84 raise Time_Error;
85 end "+";
87 function "+" (Left : Duration; Right : Time) return Time is
88 pragma Unsuppress (Overflow_Check);
89 begin
90 return (Time (Left) + Right);
92 exception
93 when Constraint_Error =>
94 raise Time_Error;
95 end "+";
97 ---------
98 -- "-" --
99 ---------
101 function "-" (Left : Time; Right : Duration) return Time is
102 pragma Unsuppress (Overflow_Check);
103 begin
104 return Left - Time (Right);
106 exception
107 when Constraint_Error =>
108 raise Time_Error;
109 end "-";
111 function "-" (Left : Time; Right : Time) return Duration is
112 pragma Unsuppress (Overflow_Check);
113 begin
114 return Duration (Left) - Duration (Right);
116 exception
117 when Constraint_Error =>
118 raise Time_Error;
119 end "-";
121 ---------
122 -- "<" --
123 ---------
125 function "<" (Left, Right : Time) return Boolean is
126 begin
127 return Duration (Left) < Duration (Right);
128 end "<";
130 ----------
131 -- "<=" --
132 ----------
134 function "<=" (Left, Right : Time) return Boolean is
135 begin
136 return Duration (Left) <= Duration (Right);
137 end "<=";
139 ---------
140 -- ">" --
141 ---------
143 function ">" (Left, Right : Time) return Boolean is
144 begin
145 return Duration (Left) > Duration (Right);
146 end ">";
148 ----------
149 -- ">=" --
150 ----------
152 function ">=" (Left, Right : Time) return Boolean is
153 begin
154 return Duration (Left) >= Duration (Right);
155 end ">=";
157 -----------
158 -- Clock --
159 -----------
161 -- The Ada.Calendar.Clock function gets the time from the soft links
162 -- interface which will call the appropriate function depending wether
163 -- tasking is involved or not.
165 function Clock return Time is
166 begin
167 return Time (System.OS_Primitives.Clock);
168 end Clock;
170 ---------
171 -- Day --
172 ---------
174 function Day (Date : Time) return Day_Number is
175 DY : Year_Number;
176 DM : Month_Number;
177 DD : Day_Number;
178 DS : Day_Duration;
179 begin
180 Split (Date, DY, DM, DD, DS);
181 return DD;
182 end Day;
184 -----------
185 -- Month --
186 -----------
188 function Month (Date : Time) return Month_Number is
189 DY : Year_Number;
190 DM : Month_Number;
191 DD : Day_Number;
192 DS : Day_Duration;
194 begin
195 Split (Date, DY, DM, DD, DS);
196 return DM;
197 end Month;
199 -------------
200 -- Seconds --
201 -------------
203 function Seconds (Date : Time) return Day_Duration is
204 DY : Year_Number;
205 DM : Month_Number;
206 DD : Day_Number;
207 DS : Day_Duration;
208 begin
209 Split (Date, DY, DM, DD, DS);
210 return DS;
211 end Seconds;
213 -----------
214 -- Split --
215 -----------
217 procedure Split
218 (Date : Time;
219 Year : out Year_Number;
220 Month : out Month_Number;
221 Day : out Day_Number;
222 Seconds : out Day_Duration)
225 Date_Int : aliased Long_Long_Integer;
226 Date_Loc : aliased Long_Long_Integer;
227 Timbuf : aliased SYSTEMTIME;
228 Int_Date : Long_Long_Integer;
229 Sub_Seconds : Duration;
231 begin
232 -- We take the sub-seconds (decimal part) of Date and this is added
233 -- to compute the Seconds. This way we keep the precision of the
234 -- high-precision clock that was lost with the Win32 API calls
235 -- below.
237 if Date < 0.0 then
239 -- this is a Date before Epoch (January 1st, 1970)
241 Sub_Seconds := Duration (Date) -
242 Duration (Long_Long_Integer (Date + Duration'(0.5)));
244 Int_Date := Long_Long_Integer (Date - Sub_Seconds);
246 -- For Date = -86400.1 we are 2 days before Epoch at 0.1 seconds
247 -- from day 1 before Epoch. It means that it is 23h 59m 59.9s.
248 -- here we adjust for that.
250 if Sub_Seconds < 0.0 then
251 Int_Date := Int_Date - 1;
252 Sub_Seconds := 1.0 + Sub_Seconds;
253 end if;
255 else
257 -- this is a Date after Epoch (January 1st, 1970)
259 Sub_Seconds := Duration (Date) -
260 Duration (Long_Long_Integer (Date - Duration'(0.5)));
262 Int_Date := Long_Long_Integer (Date - Sub_Seconds);
264 end if;
266 -- Date_Int is the number of seconds from Epoch
268 Date_Int := Long_Long_Integer
269 (Int_Date * Sec_Unit / system_time_ns) + epoch_1970;
271 if not FileTimeToLocalFileTime (Date_Int'Access, Date_Loc'Access) then
272 raise Time_Error;
273 end if;
275 if not FileTimeToSystemTime (Date_Loc'Access, Timbuf'Access) then
276 raise Time_Error;
277 end if;
279 if Timbuf.wYear not in Ada_Year_Min .. Ada_Year_Max then
280 raise Time_Error;
281 end if;
283 Seconds :=
284 Duration (Timbuf.wHour) * 3_600.0 +
285 Duration (Timbuf.wMinute) * 60.0 +
286 Duration (Timbuf.wSecond) +
287 Sub_Seconds;
289 Day := Integer (Timbuf.wDay);
290 Month := Integer (Timbuf.wMonth);
291 Year := Integer (Timbuf.wYear);
292 end Split;
294 -------------
295 -- Time_Of --
296 -------------
298 function Time_Of
299 (Year : Year_Number;
300 Month : Month_Number;
301 Day : Day_Number;
302 Seconds : Day_Duration := 0.0)
303 return Time
306 Timbuf : aliased SYSTEMTIME;
307 Now : aliased Long_Long_Integer;
308 Loc : aliased Long_Long_Integer;
309 Int_Secs : Integer;
310 Secs : Integer;
311 Add_One_Day : Boolean := False;
312 Date : Time;
314 begin
315 -- The following checks are redundant with respect to the constraint
316 -- error checks that should normally be made on parameters, but we
317 -- decide to raise Constraint_Error in any case if bad values come
318 -- in (as a result of checks being off in the caller, or for other
319 -- erroneous or bounded error cases).
321 if not Year 'Valid
322 or else not Month 'Valid
323 or else not Day 'Valid
324 or else not Seconds'Valid
325 then
326 raise Constraint_Error;
327 end if;
329 if Seconds = 0.0 then
330 Int_Secs := 0;
331 else
332 Int_Secs := Integer (Seconds - 0.5);
333 end if;
335 -- Timbuf.wMillisec is to keep the msec. We can't use that because the
336 -- high-resolution clock has a precision of 1 Microsecond.
337 -- Anyway the sub-seconds part is not needed to compute the number
338 -- of seconds in UTC.
340 if Int_Secs = 86_400 then
341 Secs := 0;
342 Add_One_Day := True;
343 else
344 Secs := Int_Secs;
345 end if;
347 Timbuf.wMilliseconds := 0;
348 Timbuf.wSecond := WORD (Secs mod 60);
349 Timbuf.wMinute := WORD ((Secs / 60) mod 60);
350 Timbuf.wHour := WORD (Secs / 3600);
351 Timbuf.wDay := WORD (Day);
352 Timbuf.wMonth := WORD (Month);
353 Timbuf.wYear := WORD (Year);
355 if not SystemTimeToFileTime (Timbuf'Access, Loc'Access) then
356 raise Time_Error;
357 end if;
359 if not LocalFileTimeToFileTime (Loc'Access, Now'Access) then
360 raise Time_Error;
361 end if;
363 -- Here we have the UTC now translate UTC to Epoch time (UNIX style
364 -- time based on 1 january 1970) and add there the sub-seconds part.
366 declare
367 Sub_Sec : constant Duration := Seconds - Duration (Int_Secs);
368 begin
369 Date := Time ((Now - epoch_1970) * system_time_ns / Sec_Unit) +
370 Sub_Sec;
371 end;
373 if Add_One_Day then
374 Date := Date + Duration (86400.0);
375 end if;
377 return Date;
378 end Time_Of;
380 ----------
381 -- Year --
382 ----------
384 function Year (Date : Time) return Year_Number is
385 DY : Year_Number;
386 DM : Month_Number;
387 DD : Day_Number;
388 DS : Day_Duration;
390 begin
391 Split (Date, DY, DM, DD, DS);
392 return DY;
393 end Year;
395 begin
396 System.OS_Primitives.Initialize;
397 end Ada.Calendar;