* config/rs6000/rs6000.md: Document why a pattern is not
[official-gcc.git] / gcc / ada / 4vcalend.adb
blob74c2923cbf2ffaf343676fee56c70c91e0c96af8
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) 1992-2003 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, 59 Temple Place - Suite 330, Boston, --
20 -- MA 02111-1307, 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 Alpha/VMS version.
36 with System.Aux_DEC; use System.Aux_DEC;
38 package body Ada.Calendar is
40 ------------------------------
41 -- Use of Pragma Unsuppress --
42 ------------------------------
44 -- This implementation of Calendar takes advantage of the permission in
45 -- Ada 95 of using arithmetic overflow checks to check for out of bounds
46 -- time values. This means that we must catch the constraint error that
47 -- results from arithmetic overflow, so we use pragma Unsuppress to make
48 -- sure that overflow is enabled, using software overflow checking if
49 -- necessary. That way, compiling Calendar with options to suppress this
50 -- checking will not affect its correctness.
52 ------------------------
53 -- Local Declarations --
54 ------------------------
56 Ada_Year_Min : constant := 1901;
57 Ada_Year_Max : constant := 2099;
59 -- Some basic constants used throughout
61 function To_Relative_Time (D : Duration) return Time;
63 function To_Relative_Time (D : Duration) return Time is
64 begin
65 return Time (Long_Integer'Integer_Value (D) / 100);
66 end To_Relative_Time;
68 ---------
69 -- "+" --
70 ---------
72 function "+" (Left : Time; Right : Duration) return Time is
73 pragma Unsuppress (Overflow_Check);
74 begin
75 return (Left + To_Relative_Time (Right));
77 exception
78 when Constraint_Error =>
79 raise Time_Error;
80 end "+";
82 function "+" (Left : Duration; Right : Time) return Time is
83 pragma Unsuppress (Overflow_Check);
84 begin
85 return (To_Relative_Time (Left) + Right);
87 exception
88 when Constraint_Error =>
89 raise Time_Error;
90 end "+";
92 ---------
93 -- "-" --
94 ---------
96 function "-" (Left : Time; Right : Duration) return Time is
97 pragma Unsuppress (Overflow_Check);
98 begin
99 return Left - To_Relative_Time (Right);
101 exception
102 when Constraint_Error =>
103 raise Time_Error;
104 end "-";
106 function "-" (Left : Time; Right : Time) return Duration is
107 pragma Unsuppress (Overflow_Check);
108 begin
109 return Duration'Fixed_Value
110 ((Long_Integer (Left) - Long_Integer (Right)) * 100);
112 exception
113 when Constraint_Error =>
114 raise Time_Error;
115 end "-";
117 ---------
118 -- "<" --
119 ---------
121 function "<" (Left, Right : Time) return Boolean is
122 begin
123 return Long_Integer (Left) < Long_Integer (Right);
124 end "<";
126 ----------
127 -- "<=" --
128 ----------
130 function "<=" (Left, Right : Time) return Boolean is
131 begin
132 return Long_Integer (Left) <= Long_Integer (Right);
133 end "<=";
135 ---------
136 -- ">" --
137 ---------
139 function ">" (Left, Right : Time) return Boolean is
140 begin
141 return Long_Integer (Left) > Long_Integer (Right);
142 end ">";
144 ----------
145 -- ">=" --
146 ----------
148 function ">=" (Left, Right : Time) return Boolean is
149 begin
150 return Long_Integer (Left) >= Long_Integer (Right);
151 end ">=";
153 -----------
154 -- Clock --
155 -----------
157 -- The Ada.Calendar.Clock function gets the time.
158 -- Note that on other targets a soft-link is used to get a different clock
159 -- depending whether tasking is used or not. On VMS this isn't needed
160 -- since all clock calls end up using SYS$GETTIM, so call the
161 -- OS_Primitives version for efficiency.
163 function Clock return Time is
164 begin
165 return Time (OSP.OS_Clock);
166 end Clock;
168 ---------
169 -- Day --
170 ---------
172 function Day (Date : Time) return Day_Number is
173 DY : Year_Number;
174 DM : Month_Number;
175 DD : Day_Number;
176 DS : Day_Duration;
178 begin
179 Split (Date, DY, DM, DD, DS);
180 return DD;
181 end Day;
183 -----------
184 -- Month --
185 -----------
187 function Month (Date : Time) return Month_Number is
188 DY : Year_Number;
189 DM : Month_Number;
190 DD : Day_Number;
191 DS : Day_Duration;
193 begin
194 Split (Date, DY, DM, DD, DS);
195 return DM;
196 end Month;
198 -------------
199 -- Seconds --
200 -------------
202 function Seconds (Date : Time) return Day_Duration is
203 DY : Year_Number;
204 DM : Month_Number;
205 DD : Day_Number;
206 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)
224 procedure Numtim (
225 Status : out Unsigned_Longword;
226 Timbuf : out Unsigned_Word_Array;
227 Timadr : in Time);
229 pragma Interface (External, Numtim);
231 pragma Import_Valued_Procedure (Numtim, "SYS$NUMTIM",
232 (Unsigned_Longword, Unsigned_Word_Array, Time),
233 (Value, Reference, Reference));
235 Status : Unsigned_Longword;
236 Timbuf : Unsigned_Word_Array (1 .. 7);
238 Subsecs : constant Time := Date mod 10_000_000;
239 Date_Secs : constant Time := Date - Subsecs;
241 begin
242 Numtim (Status, Timbuf, Date_Secs);
244 if Status mod 2 /= 1
245 or else Timbuf (1) not in Ada_Year_Min .. Ada_Year_Max
246 then
247 raise Time_Error;
248 end if;
250 Seconds := Day_Duration (Timbuf (6)
251 + 60 * (Timbuf (5) + 60 * Timbuf (4)))
252 + Duration (Subsecs) / 10_000_000.0;
254 Day := Integer (Timbuf (3));
255 Month := Integer (Timbuf (2));
256 Year := Integer (Timbuf (1));
257 end Split;
259 -------------
260 -- Time_Of --
261 -------------
263 function Time_Of
264 (Year : Year_Number;
265 Month : Month_Number;
266 Day : Day_Number;
267 Seconds : Day_Duration := 0.0)
268 return Time
271 procedure Cvt_Vectim (
272 Status : out Unsigned_Longword;
273 Input_Time : in Unsigned_Word_Array;
274 Resultant_Time : out Time);
276 pragma Interface (External, Cvt_Vectim);
278 pragma Import_Valued_Procedure (Cvt_Vectim, "LIB$CVT_VECTIM",
279 (Unsigned_Longword, Unsigned_Word_Array, Time),
280 (Value, Reference, Reference));
282 Status : Unsigned_Longword;
283 Timbuf : Unsigned_Word_Array (1 .. 7);
284 Date : Time;
285 Int_Secs : Integer;
286 Day_Hack : Boolean := False;
287 Subsecs : Day_Duration;
289 begin
290 -- The following checks are redundant with respect to the constraint
291 -- error checks that should normally be made on parameters, but we
292 -- decide to raise Constraint_Error in any case if bad values come
293 -- in (as a result of checks being off in the caller, or for other
294 -- erroneous or bounded error cases).
296 if not Year 'Valid
297 or else not Month 'Valid
298 or else not Day 'Valid
299 or else not Seconds'Valid
300 then
301 raise Constraint_Error;
302 end if;
304 -- Truncate seconds value by subtracting 0.5 and rounding,
305 -- but be careful with 0.0 since that will give -1.0 unless
306 -- it is treated specially.
308 if Seconds > 0.0 then
309 Int_Secs := Integer (Seconds - 0.5);
310 else
311 Int_Secs := Integer (Seconds);
312 end if;
314 Subsecs := Seconds - Day_Duration (Int_Secs);
316 -- Cvt_Vectim barfs on the largest Day_Duration, so trick it by
317 -- setting it to zero and then adding the difference after conversion.
319 if Int_Secs = 86_400 then
320 Int_Secs := 0;
321 Day_Hack := True;
322 end if;
324 Timbuf (7) := 0;
325 Timbuf (6) := Unsigned_Word (Int_Secs mod 60);
326 Timbuf (5) := Unsigned_Word ((Int_Secs / 60) mod 60);
327 Timbuf (4) := Unsigned_Word (Int_Secs / 3600);
328 Timbuf (3) := Unsigned_Word (Day);
329 Timbuf (2) := Unsigned_Word (Month);
330 Timbuf (1) := Unsigned_Word (Year);
332 Cvt_Vectim (Status, Timbuf, Date);
334 if Status mod 2 /= 1 then
335 raise Time_Error;
336 end if;
338 if Day_Hack then
339 Date := Date + 10_000_000 * 86_400;
340 end if;
342 Date := Date + Time (10_000_000.0 * Subsecs);
343 return Date;
344 end Time_Of;
346 ----------
347 -- Year --
348 ----------
350 function Year (Date : Time) return Year_Number is
351 DY : Year_Number;
352 DM : Month_Number;
353 DD : Day_Number;
354 DS : Day_Duration;
356 begin
357 Split (Date, DY, DM, DD, DS);
358 return DY;
359 end Year;
361 end Ada.Calendar;