Fine-grained sGMTIME_min/max detection
H.Merijn Brand [Tue, 8 Jul 2008 20:03:50 +0000 (20:03 +0000)]
p4raw-id: //depot/perl@34114

Configure

index 939bcfc..e038975 100755 (executable)
--- a/Configure
+++ b/Configure
@@ -25,7 +25,7 @@
 
 # $Id: Head.U 6 2006-08-25 22:21:46Z rmanfredi $
 #
-# Generated on Tue Jul  8 13:24:59 CEST 2008 [metaconfig 3.5 PL0]
+# Generated on Tue Jul  8 22:01:30 CEST 2008 [metaconfig 3.5 PL0]
 # (with additional metaconfig patches by perlbug@perl.org)
 
 cat >c1$$ <<EOF
@@ -20008,74 +20008,87 @@ else
 fi
 $rm -f foo* bar*
 
+: see if this is a values.h system
+set values.h i_values
+eval $inhdr
+
 : Check the max offset that gmtime accepts
-echo "Checking max offset that gmtime () accepts"
+echo "Checking max offsets that gmtime () accepts"
 
-$cat >try.c <<'EOCP'
+case $i_values in
+    define) yyy="#include <values.h>" ;;
+    *)      yyy="" ;;
+    esac
+
+$cat >try.c <<EOCP
 #include <sys/types.h>
 #include <stdio.h>
 #include <time.h>
-int main () {
-  struct tm *tmp;
-  int i, y = 0;
-  time_t pt = 0;
+$yyy
 
-  for (i = 0; i < 78; i++) {
-    time_t t = ((time_t)1 << i) - 1;
+int i;
+struct tm *tmp;
+time_t pt;
+
+void gm_check (time_t t)
+{
     tmp = gmtime (&t);
-    if (tmp == NULL || tmp->tm_year < y) {
-      i--;
-      printf ("%ld\n", pt);
-      return (i);
-      }
+    if (tmp == NULL || tmp->tm_year < -1900)
+       tmp = NULL;
+    else
+       pt = t;
+    } /* gm_check */
 
-    y = tmp->tm_year;
-    pt = t;
+int check_max ()
+{
+  tmp = NULL;
+  pt  = 0;
+#ifdef MAXLONG
+  gm_check (MAXLONG);
+#endif
+  if (tmp == NULL || tmp->tm_year < 0) {
+    for (i = 63; i >= 0; i--) {
+      time_t x = pt | ((time_t)1 << i);
+      if (x < 0) continue;
+      gm_check (x);
+      }
     }
-  printf ("%ld\n", pt);
+  printf ("sGMTIME_max=%ld\n", pt);
   return (0);
   }
-EOCP
-set try
-if eval $compile; then
-    sGMTIME_max=`$run ./try`
-else
-    echo "Cannot determine sGMTIME_max"
-    fi
-$rm_try
-
-echo "Checking min offset that gmtime () accepts"
-
-$cat >try.c <<'EOCP'
-#include <sys/types.h>
-#include <stdio.h>
-#include <time.h>
-int main () {
-  struct tm *tmp;
-  int i, y = 70;
-  time_t pt = 0;
 
-  for (i = 0; i < 78; i++) {
-    time_t t = - ((time_t)1 << i);
-    tmp = gmtime (&t);
-    if (tmp == NULL || tmp->tm_year > y) {
-      i--;
-      printf ("%ld\n", pt);
-      return (i);
+int check_min ()
+{
+  tmp = NULL;
+  pt  = 0;
+#ifdef MINLONG
+  gm_check (MINLONG);
+#endif
+  if (tmp == NULL) {
+    for (i = 36; i >= 0; i--) {
+      time_t x = pt - ((time_t)1 << i);
+      if (x > 0) continue;
+      gm_check (x);
       }
-
-    y = tmp->tm_year;
-    pt = t;
     }
-  printf ("%ld\n", pt);
+  printf ("sGMTIME_min=%ld\n", pt);
   return (0);
   }
+
+int main (int argc, char *argv[])
+{
+  fprintf (stderr, "Sizeof time_t = %ld\n", sizeof (time_t));
+  check_max ();
+  check_min ();
+  return (0);
+  } /* main */
 EOCP
 set try
 if eval $compile; then
-    sGMTIME_min=`$run ./try`
+    yyy=`$run ./try`
+    eval $yyy
 else
-    echo "Cannot determine sGMTIME_min"
+    echo "Cannot determine sGMTIME_max and sGMTIME_min." >&4
     fi
 $rm_try
 
@@ -21341,10 +21354,6 @@ eval $inhdr
 set utime.h i_utime
 eval $inhdr
 
-: see if this is a values.h system
-set values.h i_values
-eval $inhdr
-
 : see if this is a vfork system
 case "$d_vfork" in
 "$define")