home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / adav313.zip / gnat-3_13p-os2-bin-20010916.zip / emx / gnatlib / g-catiio.adb < prev    next >
Text File  |  2000-07-19  |  14KB  |  460 lines

  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.5 $
  10. --                                                                          --
  11. --              Copyright (C) 1999 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.       else
  181.          return NIP (NIP'Last - Length + 1 .. NIP'Last);
  182.       end if;
  183.    end Image;
  184.  
  185.    -----------
  186.    -- Image --
  187.    -----------
  188.  
  189.    function Image
  190.      (Date    : Ada.Calendar.Time;
  191.       Picture : Picture_String)
  192.       return    String
  193.    is
  194.       Padding    : Padding_Mode := Zero;
  195.       --  Padding is set for one directive
  196.  
  197.       Result     : Unbounded_String;
  198.  
  199.       Year       : Year_Number;
  200.       Month      : Month_Number;
  201.       Day        : Day_Number;
  202.       Hour       : Hour_Number;
  203.       Minute     : Minute_Number;
  204.       Second     : Second_Number;
  205.       Sub_Second : Second_Duration;
  206.  
  207.       P          : Positive := Picture'First;
  208.  
  209.    begin
  210.       Split (Date, Year, Month, Day, Hour, Minute, Second, Sub_Second);
  211.  
  212.       loop
  213.          --  A directive has the following format "%[-_]."
  214.  
  215.          if Picture (P) = '%' then
  216.  
  217.             Padding := Zero;
  218.  
  219.             if P = Picture'Last then
  220.                raise Picture_Error;
  221.             end if;
  222.  
  223.             --  Check for GNU extension to change the padding
  224.  
  225.             if Picture (P + 1) = '-' then
  226.                Padding := None;
  227.                P := P + 1;
  228.             elsif Picture (P + 1) = '_' then
  229.                Padding := Space;
  230.                P := P + 1;
  231.             end if;
  232.  
  233.             if P = Picture'Last then
  234.                raise Picture_Error;
  235.             end if;
  236.  
  237.             case Picture (P + 1) is
  238.  
  239.                --  Literal %
  240.  
  241.                when '%' =>
  242.                   Result := Result & '%';
  243.  
  244.                --  A newline
  245.  
  246.                when 'n' =>
  247.                   Result := Result & ASCII.LF;
  248.  
  249.                --  A horizontal tab
  250.  
  251.                when 't' =>
  252.                   Result := Result & ASCII.HT;
  253.  
  254.                --  Hour (00..23)
  255.  
  256.                when 'H' =>
  257.                   Result := Result & Image (Hour, Padding, 2);
  258.  
  259.                --  Hour (01..12)
  260.  
  261.                when 'I' =>
  262.                   Result := Result & Image (Hour_12 (Hour), Padding, 2);
  263.  
  264.                --  Hour ( 0..23)
  265.  
  266.                when 'k' =>
  267.                   Result := Result & Image (Hour, Space, 2);
  268.  
  269.                --  Hour ( 1..12)
  270.  
  271.                when 'l' =>
  272.                   Result := Result & Image (Hour_12 (Hour), Space, 2);
  273.  
  274.                --  Minute (00..59)
  275.  
  276.                when 'M' =>
  277.                   Result := Result & Image (Minute, Padding, 2);
  278.  
  279.                --  AM/PM
  280.  
  281.                when 'p' =>
  282.                   Result := Result & Am_Pm (Hour);
  283.  
  284.                --  Time, 12-hour (hh:mm:ss [AP]M)
  285.  
  286.                when 'r' =>
  287.                   Result := Result &
  288.                     Image (Hour_12 (Hour), Padding, Length => 2) & ':' &
  289.                     Image (Minute, Padding, Length => 2) & ':' &
  290.                     Image (Second, Padding, Length => 2) & ' ' &
  291.                     Am_Pm (Hour);
  292.  
  293.                --   Seconds  since 1970-01-01  00:00:00 UTC
  294.                --   (a nonstandard extension)
  295.  
  296.                when 's' =>
  297.                   declare
  298.                      Sec : constant Long_Integer :=
  299.                              Long_Integer
  300.                                ((Julian_Day (Year, Month, Day) -
  301.                                   Julian_Day (1970, 1, 1)) * 86_400 +
  302.                                 Hour * 3_600 + Minute * 60 + Second);
  303.  
  304.                   begin
  305.                      Result := Result & Image (Sec, None);
  306.                   end;
  307.  
  308.                --  Second (00..59)
  309.  
  310.                when 'S' =>
  311.                   Result := Result & Image (Second, Padding, Length => 2);
  312.  
  313.                --  Time, 24-hour (hh:mm:ss)
  314.  
  315.                when 'T' =>
  316.                   Result := Result &
  317.                     Image (Hour, Padding, Length => 2) & ':' &
  318.                     Image (Minute, Padding, Length => 2) & ':' &
  319.                     Image (Second, Padding, Length => 2);
  320.  
  321.                --  Locale's abbreviated weekday name (Sun..Sat)
  322.  
  323.                when 'a' =>
  324.                   Result := Result &
  325.                     Image (Day_Name'Image (Day_Of_Week (Date)), 3);
  326.  
  327.                --  Locale's full weekday name, variable length
  328.                --  (Sunday..Saturday)
  329.  
  330.                when 'A' =>
  331.                   Result := Result &
  332.                     Image (Day_Name'Image (Day_Of_Week (Date)));
  333.  
  334.                --  Locale's abbreviated month name (Jan..Dec)
  335.  
  336.                when 'b' | 'h' =>
  337.                   Result := Result &
  338.                     Image (Month_Name'Image (Month_Name'Val (Month)), 3);
  339.  
  340.                --  Locale's full month name, variable length
  341.                --  (January..December)
  342.  
  343.                when 'B' =>
  344.                   Result := Result &
  345.                     Image (Month_Name'Image (Month_Name'Val (Month)));
  346.  
  347.                --  Locale's date and time (Sat Nov 04 12:02:33 EST 1989)
  348.  
  349.                when 'c' =>
  350.                   case Padding is
  351.                      when Zero =>
  352.                         Result := Result & Image (Date, "%a %b %d %T %Y");
  353.                      when Space =>
  354.                         Result := Result & Image (Date, "%a %b %_d %_T %Y");
  355.                      when None =>
  356.                         Result := Result & Image (Date, "%a %b %-d %-T %Y");
  357.                   end case;
  358.  
  359.                --   Day of month (01..31)
  360.  
  361.                when 'd' =>
  362.                   Result := Result & Image (Day, Padding, 2);
  363.  
  364.                --  Date (mm/dd/yy)
  365.  
  366.                when 'D' | 'x' =>
  367.                   Result := Result &
  368.                     Image (Month, Padding, 2) & '/' &
  369.                     Image (Day, Padding, 2) & '/' &
  370.                     Image (Year, Padding, 2);
  371.  
  372.                --  Day of year (001..366)
  373.  
  374.                when 'j' =>
  375.                   Result := Result & Image (Day_In_Year (Date), Padding, 3);
  376.  
  377.                --  Month (01..12)
  378.  
  379.                when 'm' =>
  380.                   Result := Result & Image (Month, Padding, 2);
  381.  
  382.                --  Week number of year with Sunday as first day of week
  383.                --  (00..53)
  384.  
  385.                when 'U' =>
  386.                   declare
  387.                      Offset : constant Natural :=
  388.                                 (Julian_Day (Year, 1, 1) + 1) mod 7;
  389.  
  390.                      Week : constant Natural :=
  391.                               1 + ((Day_In_Year (Date) - 1) + Offset) / 7;
  392.  
  393.                   begin
  394.  
  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.                   Result := Result & Image (Year, None, 2);
  424.  
  425.                --   Year (1970...)
  426.                when 'Y' =>
  427.                   Result := Result & Image (Year, None, 4);
  428.  
  429.                when others =>
  430.                   raise Picture_Error;
  431.             end case;
  432.  
  433.             P := P + 2;
  434.  
  435.          else
  436.             Result := Result & Picture (P);
  437.             P := P + 1;
  438.          end if;
  439.  
  440.          exit when P > Picture'Last;
  441.  
  442.       end loop;
  443.  
  444.       return To_String (Result);
  445.    end Image;
  446.  
  447.    --------------
  448.    -- Put_Time --
  449.    --------------
  450.  
  451.    procedure Put_Time
  452.      (Date    : Ada.Calendar.Time;
  453.       Picture : Picture_String)
  454.    is
  455.    begin
  456.       Ada.Text_IO.Put (Image (Date, Picture));
  457.    end Put_Time;
  458.  
  459. end GNAT.Calendar.Time_IO;
  460.