a-calend-vms.adb, [...]: Add a section on leap seconds control along with two entitie...
authorHristian Kirtchev <kirtchev@adacore.com>
Wed, 26 Sep 2007 10:41:35 +0000 (12:41 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Wed, 26 Sep 2007 10:41:35 +0000 (12:41 +0200)
2007-09-26  Hristian Kirtchev  <kirtchev@adacore.com>

* a-calend-vms.adb, a-calend.adb:
Add a section on leap seconds control along with two entities used to
enable and disable leap seconds support. The array Leap_Second_Times is
now constant and contains hard time values pre-generated. Remove
all elaboration code used to populate the table of leap seconds.

* bindgen.adb:
Add entity Leap_Seconds_Support to the list of global run-time variables
along with a comment on its usage and values.
(Gen_Adainit_Ada): Add code to generate the declaration and import of
Integer variable Leap_Seconds_Support. Set its value to zero (disabled)
or one (enabled) depending on the presence of binder switch "-y".
(Gen_Adainit_C): Add code to generate the declaration of external int
__gl_leap_seconds_support. Set is value to zero (disabled) or one
(enabled) depending on the presence of binder switch "-y".

* init.c: Add __gl_leap_seconds_support to the list of global values
computed by the binder.

From-SVN: r128780

gcc/ada/a-calend-vms.adb
gcc/ada/a-calend.adb
gcc/ada/bindgen.adb
gcc/ada/init.c

index c115c8a220d439a60f56e78433002f8fb0d19cdf..bcfc3dd49bff7d24dee1fcb5c27f71f3192142ba 100644 (file)
@@ -112,17 +112,27 @@ package body Ada.Calendar is
    --  Unchecked_Conversion was employed, the resulting values would be off
    --  by 100.
 
-   ---------------------
-   -- Local Constants --
-   ---------------------
+   --------------------------
+   -- Leap seconds control --
+   --------------------------
 
-   --  Currently none of the GNAT targets support leap seconds. At some point
-   --  it might be necessary to query a C function to determine if the target
-   --  supports leap seconds, but for now this is deemed unnecessary.
+   Flag : Integer;
+   pragma Import (C, Flag, "__gl_leap_seconds_support");
+   --  This imported value is used to determine whether the compilation had
+   --  binder flag "-y" present which enables leap seconds. A value of zero
+   --  signifies no leap seconds support while a value of one enables the
+   --  support.
+
+   Leap_Support : constant Boolean := Flag = 1;
+   --  The above flag controls the usage of leap seconds in all Ada.Calendar
+   --  routines.
 
-   Leap_Support       : constant Boolean := False;
    Leap_Seconds_Count : constant Natural := 23;
 
+   ---------------------
+   -- Local Constants --
+   ---------------------
+
    --  The range of Ada time expressed as milis since the VMS Epoch
 
    Ada_Low  : constant Time :=  (10 * 366 +  32 * 365 + 45) * Milis_In_Day;
@@ -141,14 +151,33 @@ package body Ada.Calendar is
    End_Of_Time   : constant Time := Ada_High + Time (3) * Milis_In_Day;
    Start_Of_Time : constant Time := Ada_Low  - Time (3) * Milis_In_Day;
 
-   Cumulative_Days_Before_Month :
-     constant array (Month_Number) of Natural :=
-       (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
-
-   Leap_Second_Times : array (1 .. Leap_Seconds_Count) of Time;
-   --  Each value represents a time value which is one second before a leap
-   --  second occurence. This table is populated during the elaboration of
-   --  Ada.Calendar.
+   --  The following table contains the hard time values of all existing leap
+   --  seconds. The values are produced by the utility program xleaps.adb.
+
+   Leap_Second_Times : constant array (1 .. Leap_Seconds_Count) of Time :=
+     (35855136000000000,
+      36014112010000000,
+      36329472020000000,
+      36644832030000000,
+      36960192040000000,
+      37276416050000000,
+      37591776060000000,
+      37907136070000000,
+      38222496080000000,
+      38695104090000000,
+      39010464100000000,
+      39325824110000000,
+      39957408120000000,
+      40747104130000000,
+      41378688140000000,
+      41694048150000000,
+      42166656160000000,
+      42482016170000000,
+      42797376180000000,
+      43271712190000000,
+      43744320200000000,
+      44218656210000000,
+      46427904220000000);
 
    ---------
    -- "+" --
@@ -1062,78 +1091,4 @@ package body Ada.Calendar is
          return get_gmtoff;
       end UTC_Time_Offset;
    end Time_Zones_Operations;
-
---  Start of elaboration code for Ada.Calendar
-
-begin
-   --  Population of the leap seconds table
-
-   if Leap_Support then
-      declare
-         type Leap_Second_Date is record
-            Year  : Year_Number;
-            Month : Month_Number;
-            Day   : Day_Number;
-         end record;
-
-         Leap_Second_Dates :
-           constant array (1 .. Leap_Seconds_Count) of Leap_Second_Date :=
-             ((1972,  6, 30), (1972, 12, 31), (1973, 12, 31), (1974, 12, 31),
-              (1975, 12, 31), (1976, 12, 31), (1977, 12, 31), (1978, 12, 31),
-              (1979, 12, 31), (1981,  6, 30), (1982,  6, 30), (1983,  6, 30),
-              (1985,  6, 30), (1987, 12, 31), (1989, 12, 31), (1990, 12, 31),
-              (1992,  6, 30), (1993,  6, 30), (1994,  6, 30), (1995, 12, 31),
-              (1997,  6, 30), (1998, 12, 31), (2005, 12, 31));
-
-         Ada_Min_Year       : constant Year_Number := Year_Number'First;
-         Days_In_Four_Years : constant := 365 * 3 + 366;
-         VMS_Days           : constant := 10 * 366 + 32 * 365 + 45;
-
-         Days  : Natural;
-         Leap  : Leap_Second_Date;
-         Years : Natural;
-
-      begin
-         for Index in 1 .. Leap_Seconds_Count loop
-            Leap := Leap_Second_Dates (Index);
-
-            --  Calculate the number of days from the start of Ada time until
-            --  the current leap second occurence. Non-leap centenial years
-            --  are not accounted for in these calculations since there are
-            --  no leap seconds after 2100 yet.
-
-            Years := Leap.Year - Ada_Min_Year;
-            Days  := (Years / 4) * Days_In_Four_Years;
-            Years := Years mod 4;
-
-            if Years = 1 then
-               Days := Days + 365;
-
-            elsif Years = 2 then
-               Days := Days + 365 * 2;
-
-            elsif Years = 3 then
-               Days := Days + 365 * 3;
-            end if;
-
-            Days := Days + Cumulative_Days_Before_Month (Leap.Month);
-
-            if Is_Leap (Leap.Year)
-              and then Leap.Month > 2
-            then
-               Days := Days + 1;
-            end if;
-
-            --  Add the number of days since the start of VMS time till the
-            --  start of Ada time.
-
-            Days := Days + Leap.Day + VMS_Days;
-
-            --  Index - 1 previous leap seconds are added to Time (Index)
-
-            Leap_Second_Times (Index) :=
-              (Time (Days) * Secs_In_Day + Time (Index - 1)) * Mili;
-         end loop;
-      end;
-   end if;
 end Ada.Calendar;
index 9acac9bf6d726ed749186d1fd4b2556586d7b701..eb77eac37b20536f20fd3ca54671b21db3085c2d 100644 (file)
@@ -127,17 +127,27 @@ package body Ada.Calendar is
 
    type Time_Dur is range 0 .. 2 ** 63 - 1;
 
-   ---------------------
-   -- Local Constants --
-   ---------------------
+   --------------------------
+   -- Leap seconds control --
+   --------------------------
+
+   Flag : Integer;
+   pragma Import (C, Flag, "__gl_leap_seconds_support");
+   --  This imported value is used to determine whether the compilation had
+   --  binder flag "-y" present which enables leap seconds. A value of zero
+   --  signifies no leap seconds support while a value of one enables the
+   --  support.
 
-   --  Currently none of the GNAT targets support leap seconds. At some point
-   --  it might be necessary to query a C function to determine if the target
-   --  supports leap seconds, but for now this is deemed unnecessary.
+   Leap_Support : constant Boolean := Flag = 1;
+   --  The above flag controls the usage of leap seconds in all Ada.Calendar
+   --  routines.
 
-   Leap_Support       : constant Boolean := False;
    Leap_Seconds_Count : constant Natural := 23;
 
+   ---------------------
+   -- Local Constants --
+   ---------------------
+
    Ada_Min_Year          : constant Year_Number := Year_Number'First;
    Secs_In_Four_Years    : constant := (3 * 365 + 366) * Secs_In_Day;
    Secs_In_Non_Leap_Year : constant := 365 * Secs_In_Day;
@@ -174,10 +184,33 @@ package body Ada.Calendar is
      constant array (Month_Number) of Natural :=
        (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334);
 
-   Leap_Second_Times : array (1 .. Leap_Seconds_Count) of Time_Rep;
-   --  Each value represents a time value which is one second before a leap
-   --  second occurence. This table is populated during the elaboration of
-   --  Ada.Calendar.
+   --  The following table contains the hard time values of all existing leap
+   --  seconds. The values are produced by the utility program xleaps.adb.
+
+   Leap_Second_Times : constant array (1 .. Leap_Seconds_Count) of Time_Rep :=
+     (-5601484800000000000,
+      -5585587199000000000,
+      -5554051198000000000,
+      -5522515197000000000,
+      -5490979196000000000,
+      -5459356795000000000,
+      -5427820794000000000,
+      -5396284793000000000,
+      -5364748792000000000,
+      -5317487991000000000,
+      -5285951990000000000,
+      -5254415989000000000,
+      -5191257588000000000,
+      -5112287987000000000,
+      -5049129586000000000,
+      -5017593585000000000,
+      -4970332784000000000,
+      -4938796783000000000,
+      -4907260782000000000,
+      -4859827181000000000,
+      -4812566380000000000,
+      -4765132779000000000,
+      -4544207978000000000);
 
    ---------
    -- "+" --
@@ -1318,71 +1351,4 @@ package body Ada.Calendar is
 
 begin
    System.OS_Primitives.Initialize;
-
-   --  Population of the leap seconds table
-
-   if Leap_Support then
-      declare
-         type Leap_Second_Date is record
-            Year  : Year_Number;
-            Month : Month_Number;
-            Day   : Day_Number;
-         end record;
-
-         Leap_Second_Dates :
-           constant array (1 .. Leap_Seconds_Count) of Leap_Second_Date :=
-             ((1972,  6, 30), (1972, 12, 31), (1973, 12, 31), (1974, 12, 31),
-              (1975, 12, 31), (1976, 12, 31), (1977, 12, 31), (1978, 12, 31),
-              (1979, 12, 31), (1981,  6, 30), (1982,  6, 30), (1983,  6, 30),
-              (1985,  6, 30), (1987, 12, 31), (1989, 12, 31), (1990, 12, 31),
-              (1992,  6, 30), (1993,  6, 30), (1994,  6, 30), (1995, 12, 31),
-              (1997,  6, 30), (1998, 12, 31), (2005, 12, 31));
-
-         Days_In_Four_Years : constant := 365 * 3 + 366;
-
-         Days  : Natural;
-         Leap  : Leap_Second_Date;
-         Years : Natural;
-
-      begin
-         for Index in 1 .. Leap_Seconds_Count loop
-            Leap := Leap_Second_Dates (Index);
-
-            --  Calculate the number of days from the start of Ada time until
-            --  the current leap second occurence. Non-leap centenial years
-            --  are not accounted for in these calculations since there are
-            --  no leap seconds after 2100 yet.
-
-            Years := Leap.Year - Ada_Min_Year;
-            Days  := (Years / 4) * Days_In_Four_Years;
-            Years := Years mod 4;
-
-            if Years = 1 then
-               Days := Days + 365;
-
-            elsif Years = 2 then
-               Days := Days + 365 * 2;
-
-            elsif Years = 3 then
-               Days := Days + 365 * 3;
-            end if;
-
-            Days := Days + Cumulative_Days_Before_Month (Leap.Month);
-
-            if Is_Leap (Leap.Year)
-              and then Leap.Month > 2
-            then
-               Days := Days + 1;
-            end if;
-
-            Days := Days + Leap.Day;
-
-            --  Index - 1 previous leap seconds are added to Time (Index) as
-            --  well as the lower buffer for time zones.
-
-            Leap_Second_Times (Index) := Ada_Low +
-              (Time_Rep (Days) * Secs_In_Day + Time_Rep (Index - 1)) * Nano;
-         end loop;
-      end;
-   end if;
 end Ada.Calendar;
index fdd6783901726f8461176a15bdaf2be112a0ccf8..bf15ffb3ca3310d90ff06685fd6e5519e2ff58e1 100644 (file)
@@ -124,6 +124,7 @@ package body Bindgen is
    --     Zero_Cost_Exceptions          : Integer;
    --     Detect_Blocking               : Integer;
    --     Default_Stack_Size            : Integer;
+   --     Leap_Seconds_Support          : Integer;
 
    --  Main_Priority is the priority value set by pragma Priority in the
    --  main program. If no such pragma is present, the value is -1.
@@ -207,6 +208,10 @@ package body Bindgen is
    --  Default_Stack_Size is the default stack size used when creating an
    --  Ada task with no explicit Storize_Size clause.
 
+   --  Leap_Seconds_Support denotes whether leap seconds have been enabled or
+   --  disabled. A value of zero indicates that leap seconds are turned "off",
+   --  while a value of one signifies "on" status.
+
    -----------------------
    -- Local Subprograms --
    -----------------------
@@ -575,6 +580,9 @@ package body Bindgen is
          WBI ("      Default_Stack_Size : Integer;");
          WBI ("      pragma Import (C, Default_Stack_Size, " &
               """__gl_default_stack_size"");");
+         WBI ("      Leap_Seconds_Support : Integer;");
+         WBI ("      pragma Import (C, Leap_Seconds_Support, " &
+              """__gl_leap_seconds_support"");");
 
          --  Import entry point for elaboration time signal handler
          --  installation, and indication of if it's been called previously.
@@ -686,6 +694,17 @@ package body Bindgen is
          Set_String (";");
          Write_Statement_Buffer;
 
+         Set_String ("      Leap_Seconds_Support := ");
+
+         if Leap_Seconds_Support then
+            Set_Int (1);
+         else
+            Set_Int (0);
+         end if;
+
+         Set_String (";");
+         Write_Statement_Buffer;
+
          --  Generate call to Install_Handler
 
          WBI ("");
@@ -925,6 +944,18 @@ package body Bindgen is
          Set_String (";");
          Write_Statement_Buffer;
 
+         WBI ("   extern int __gl_leap_seconds_support;");
+         Set_String ("   __gl_leap_seconds_support = ");
+
+         if Leap_Seconds_Support then
+            Set_Int (1);
+         else
+            Set_Int (0);
+         end if;
+
+         Set_String (";");
+         Write_Statement_Buffer;
+
          WBI ("");
 
          --  Install elaboration time signal handler
index 068fca547cf5aeaf8836d235fe747d6e4f540eda..ba36d38458d8bf38ffa7f51e534f714eb3d24261 100644 (file)
@@ -101,6 +101,7 @@ int   __gl_exception_tracebacks          = 0;
 int   __gl_zero_cost_exceptions          = 0;
 int   __gl_detect_blocking               = 0;
 int   __gl_default_stack_size            = -1;
+int   __gl_leap_seconds_support          = 0;
 
 /* Indication of whether synchronous signal handler has already been
    installed by a previous call to adainit */
@@ -444,7 +445,6 @@ __gnat_set_code_loc (struct sigcontext *context, char *pc)
   context->sc_pc = (long) pc;
 }
 
-
 size_t
 __gnat_machine_state_length (void)
 {