OSDN Git Service

* doc/install.texi (xtensa-*-elf): New target.
[pf3gnuchains/gcc-fork.git] / gcc / ada / g-catiio.adb
1 ------------------------------------------------------------------------------
2 --                                                                          --
3 --                         GNAT RUN-TIME COMPONENTS                         --
4 --                                                                          --
5 --                G N A T . C A L E N D A R . T I M E _ I O                 --
6 --                                                                          --
7 --                                 B o d y                                  --
8 --                                                                          --
9 --                            $Revision: 1.9 $
10 --                                                                          --
11 --            Copyright (C) 1999-2001 Ada Core Technologies, Inc.           --
12 --                                                                          --
13 -- This specification is derived from the Ada Reference Manual for use with --
14 -- GNAT. The copyright notice above, and the license provisions that follow --
15 -- apply solely to the  contents of the part following the private keyword. --
16 --                                                                          --
17 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
18 -- terms of the  GNU General Public License as published  by the Free Soft- --
19 -- ware  Foundation;  either version 2,  or (at your option) any later ver- --
20 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
21 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
22 -- or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License --
23 -- for  more details.  You should have  received  a copy of the GNU General --
24 -- Public License  distributed with GNAT;  see file COPYING.  If not, write --
25 -- to  the Free Software Foundation,  59 Temple Place - Suite 330,  Boston, --
26 -- MA 02111-1307, USA.                                                      --
27 --                                                                          --
28 -- As a special exception,  if other files  instantiate  generics from this --
29 -- unit, or you link  this unit with other files  to produce an executable, --
30 -- this  unit  does not  by itself cause  the resulting  executable  to  be --
31 -- covered  by the  GNU  General  Public  License.  This exception does not --
32 -- however invalidate  any other reasons why  the executable file  might be --
33 -- covered by the  GNU Public License.                                      --
34 --                                                                          --
35 -- GNAT was originally developed  by the GNAT team at  New York University. --
36 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
37 --                                                                          --
38 ------------------------------------------------------------------------------
39
40 with Ada.Calendar;            use Ada.Calendar;
41 with Ada.Characters.Handling;
42 with Ada.Strings.Unbounded;   use Ada.Strings.Unbounded;
43 with Ada.Text_IO;
44
45 package body GNAT.Calendar.Time_IO is
46
47    type Month_Name is
48      (January,
49       Febuary,
50       March,
51       April,
52       May,
53       June,
54       July,
55       August,
56       September,
57       October,
58       November,
59       December);
60
61    type Padding_Mode is (None, Zero, Space);
62
63    -----------------------
64    -- Local Subprograms --
65    -----------------------
66
67    function Am_Pm (H : Natural) return String;
68    --  return AM or PM depending on the hour H
69
70    function Hour_12 (H : Natural) return Positive;
71    --  Convert a 1-24h format to a 0-12 hour format.
72
73    function Image (Str : String; Length : Natural := 0) return String;
74    --  Return Str capitalized and cut to length number of characters. If
75    --  length is set to 0 it does not cut it.
76
77    function Image
78      (N       : Long_Integer;
79       Padding : Padding_Mode := Zero;
80       Length  : Natural := 0)
81       return    String;
82    --  Return image of N. This number is eventually padded with zeros or
83    --  spaces depending of the length required. If length is 0 then no padding
84    --  occurs.
85
86    function Image
87      (N       : Integer;
88       Padding : Padding_Mode := Zero;
89       Length  : Natural := 0)
90       return    String;
91    --  As above with N provided in Integer format.
92
93    -----------
94    -- Am_Pm --
95    -----------
96
97    function Am_Pm (H : Natural) return String is
98    begin
99       if H = 0 or else H > 12 then
100          return "PM";
101       else
102          return "AM";
103       end if;
104    end Am_Pm;
105
106    -------------
107    -- Hour_12 --
108    -------------
109
110    function Hour_12 (H : Natural) return Positive is
111    begin
112       if H = 0 then
113          return 12;
114       elsif H <= 12 then
115          return H;
116       else --  H > 12
117          return H - 12;
118       end if;
119    end Hour_12;
120
121    -----------
122    -- Image --
123    -----------
124
125    function Image
126      (Str    : String;
127       Length : Natural := 0)
128       return   String
129    is
130       use Ada.Characters.Handling;
131       Local : String := To_Upper (Str (1)) & To_Lower (Str (2 .. Str'Last));
132
133    begin
134       if Length = 0 then
135          return Local;
136       else
137          return Local (1 .. Length);
138       end if;
139    end Image;
140
141    -----------
142    -- Image --
143    -----------
144
145    function Image
146      (N       : Integer;
147       Padding : Padding_Mode := Zero;
148       Length  : Natural := 0)
149       return    String
150    is
151    begin
152       return Image (Long_Integer (N), Padding, Length);
153    end Image;
154
155    function Image
156      (N       : Long_Integer;
157       Padding : Padding_Mode := Zero;
158       Length  : Natural := 0)
159       return    String
160    is
161       function Pad_Char return String;
162
163       function Pad_Char return String is
164       begin
165          case Padding is
166             when None  => return "";
167             when Zero  => return "00";
168             when Space => return "  ";
169          end case;
170       end Pad_Char;
171
172       NI  : constant String := Long_Integer'Image (N);
173       NIP : constant String := Pad_Char & NI (2 .. NI'Last);
174
175    --  Start of processing for Image
176
177    begin
178       if Length = 0 or else Padding = None then
179          return NI (2 .. NI'Last);
180
181       else
182          return NIP (NIP'Last - Length + 1 .. NIP'Last);
183       end if;
184    end Image;
185
186    -----------
187    -- Image --
188    -----------
189
190    function Image
191      (Date    : Ada.Calendar.Time;
192       Picture : Picture_String)
193       return    String
194    is
195       Padding    : Padding_Mode := Zero;
196       --  Padding is set for one directive
197
198       Result     : Unbounded_String;
199
200       Year       : Year_Number;
201       Month      : Month_Number;
202       Day        : Day_Number;
203       Hour       : Hour_Number;
204       Minute     : Minute_Number;
205       Second     : Second_Number;
206       Sub_Second : Second_Duration;
207
208       P : Positive := Picture'First;
209
210    begin
211       Split (Date, Year, Month, Day, Hour, Minute, Second, Sub_Second);
212
213       loop
214          --  A directive has the following format "%[-_]."
215
216          if Picture (P) = '%' then
217
218             Padding := Zero;
219
220             if P = Picture'Last then
221                raise Picture_Error;
222             end if;
223
224             --  Check for GNU extension to change the padding
225
226             if Picture (P + 1) = '-' then
227                Padding := None;
228                P := P + 1;
229             elsif Picture (P + 1) = '_' then
230                Padding := Space;
231                P := P + 1;
232             end if;
233
234             if P = Picture'Last then
235                raise Picture_Error;
236             end if;
237
238             case Picture (P + 1) is
239
240                --  Literal %
241
242                when '%' =>
243                   Result := Result & '%';
244
245                --  A newline
246
247                when 'n' =>
248                   Result := Result & ASCII.LF;
249
250                --  A horizontal tab
251
252                when 't' =>
253                   Result := Result & ASCII.HT;
254
255                --  Hour (00..23)
256
257                when 'H' =>
258                   Result := Result & Image (Hour, Padding, 2);
259
260                --  Hour (01..12)
261
262                when 'I' =>
263                   Result := Result & Image (Hour_12 (Hour), Padding, 2);
264
265                --  Hour ( 0..23)
266
267                when 'k' =>
268                   Result := Result & Image (Hour, Space, 2);
269
270                --  Hour ( 1..12)
271
272                when 'l' =>
273                   Result := Result & Image (Hour_12 (Hour), Space, 2);
274
275                --  Minute (00..59)
276
277                when 'M' =>
278                   Result := Result & Image (Minute, Padding, 2);
279
280                --  AM/PM
281
282                when 'p' =>
283                   Result := Result & Am_Pm (Hour);
284
285                --  Time, 12-hour (hh:mm:ss [AP]M)
286
287                when 'r' =>
288                   Result := Result &
289                     Image (Hour_12 (Hour), Padding, Length => 2) & ':' &
290                     Image (Minute, Padding, Length => 2) & ':' &
291                     Image (Second, Padding, Length => 2) & ' ' &
292                     Am_Pm (Hour);
293
294                --   Seconds  since 1970-01-01  00:00:00 UTC
295                --   (a nonstandard extension)
296
297                when 's' =>
298                   declare
299                      Sec : constant Long_Integer :=
300                              Long_Integer
301                                ((Julian_Day (Year, Month, Day) -
302                                   Julian_Day (1970, 1, 1)) * 86_400 +
303                                 Hour * 3_600 + Minute * 60 + Second);
304
305                   begin
306                      Result := Result & Image (Sec, None);
307                   end;
308
309                --  Second (00..59)
310
311                when 'S' =>
312                   Result := Result & Image (Second, Padding, Length => 2);
313
314                --  Time, 24-hour (hh:mm:ss)
315
316                when 'T' =>
317                   Result := Result &
318                     Image (Hour, Padding, Length => 2) & ':' &
319                     Image (Minute, Padding, Length => 2) & ':' &
320                     Image (Second, Padding, Length => 2);
321
322                --  Locale's abbreviated weekday name (Sun..Sat)
323
324                when 'a' =>
325                   Result := Result &
326                     Image (Day_Name'Image (Day_Of_Week (Date)), 3);
327
328                --  Locale's full weekday name, variable length
329                --  (Sunday..Saturday)
330
331                when 'A' =>
332                   Result := Result &
333                     Image (Day_Name'Image (Day_Of_Week (Date)));
334
335                --  Locale's abbreviated month name (Jan..Dec)
336
337                when 'b' | 'h' =>
338                   Result := Result &
339                     Image (Month_Name'Image (Month_Name'Val (Month - 1)), 3);
340
341                --  Locale's full month name, variable length
342                --  (January..December)
343
344                when 'B' =>
345                   Result := Result &
346                     Image (Month_Name'Image (Month_Name'Val (Month - 1)));
347
348                --  Locale's date and time (Sat Nov 04 12:02:33 EST 1989)
349
350                when 'c' =>
351                   case Padding is
352                      when Zero =>
353                         Result := Result & Image (Date, "%a %b %d %T %Y");
354                      when Space =>
355                         Result := Result & Image (Date, "%a %b %_d %_T %Y");
356                      when None =>
357                         Result := Result & Image (Date, "%a %b %-d %-T %Y");
358                   end case;
359
360                --   Day of month (01..31)
361
362                when 'd' =>
363                   Result := Result & Image (Day, Padding, 2);
364
365                --  Date (mm/dd/yy)
366
367                when 'D' | 'x' =>
368                   Result := Result &
369                     Image (Month, Padding, 2) & '/' &
370                     Image (Day, Padding, 2) & '/' &
371                     Image (Year, Padding, 2);
372
373                --  Day of year (001..366)
374
375                when 'j' =>
376                   Result := Result & Image (Day_In_Year (Date), Padding, 3);
377
378                --  Month (01..12)
379
380                when 'm' =>
381                   Result := Result & Image (Month, Padding, 2);
382
383                --  Week number of year with Sunday as first day of week
384                --  (00..53)
385
386                when 'U' =>
387                   declare
388                      Offset : constant Natural :=
389                                 (Julian_Day (Year, 1, 1) + 1) mod 7;
390
391                      Week : constant Natural :=
392                               1 + ((Day_In_Year (Date) - 1) + Offset) / 7;
393
394                   begin
395                      Result := Result & Image (Week, Padding, 2);
396                   end;
397
398                --  Day of week (0..6) with 0 corresponding to Sunday
399
400                when 'w' =>
401                   declare
402                      DOW : Natural range 0 .. 6;
403
404                   begin
405                      if Day_Of_Week (Date) = Sunday then
406                         DOW := 0;
407                      else
408                         DOW := Day_Name'Pos (Day_Of_Week (Date));
409                      end if;
410
411                      Result := Result & Image (DOW, Length => 1);
412                   end;
413
414                --  Week number of year with Monday as first day of week
415                --  (00..53)
416
417                when 'W' =>
418                   Result := Result & Image (Week_In_Year (Date), Padding, 2);
419
420                --  Last two digits of year (00..99)
421
422                when 'y' =>
423                   declare
424                      Y : constant Natural := Year - (Year / 100) * 100;
425
426                   begin
427                      Result := Result & Image (Y, Padding, 2);
428                   end;
429
430                --   Year (1970...)
431
432                when 'Y' =>
433                   Result := Result & Image (Year, None, 4);
434
435                when others =>
436                   raise Picture_Error;
437             end case;
438
439             P := P + 2;
440
441          else
442             Result := Result & Picture (P);
443             P := P + 1;
444          end if;
445
446          exit when P > Picture'Last;
447
448       end loop;
449
450       return To_String (Result);
451    end Image;
452
453    --------------
454    -- Put_Time --
455    --------------
456
457    procedure Put_Time
458      (Date    : Ada.Calendar.Time;
459       Picture : Picture_String)
460    is
461    begin
462       Ada.Text_IO.Put (Image (Date, Picture));
463    end Put_Time;
464
465 end GNAT.Calendar.Time_IO;