This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
MakeMaker is first-come in Maintainers.pl.
[perl5.git] / Porting / timecheck.c
1 #include <sys/types.h>
2 #include <stdio.h>
3 #include <time.h>
4 #include <errno.h>
5 #include <values.h>
6
7 int opt_v = 0;
8 int i;
9 struct tm *tmp;
10 time_t pt, pt_max, pt_min;
11
12 static char hexbuf[80];
13 char *hex (time_t t)
14 {
15     if ((long long)t < 0)
16         sprintf (hexbuf, " -0x%016lx", -t);
17     else
18         sprintf (hexbuf, "  0x%016lx",  t);
19     return (hexbuf);
20     } /* hex */
21
22 void gm_check (time_t t, int min_year, int max_year)
23 {
24     tmp = gmtime (&t);
25     if ( tmp == NULL ||
26         /* Check tm_year overflow */
27          tmp->tm_year < min_year || tmp->tm_year > max_year) {
28         if (opt_v)
29             fprintf (stderr, "gmtime (%ld) failed with errno %d\n", t, errno);
30         }
31     else {
32         if (opt_v)
33             fprintf (stderr, "%3d:%s: %12ld-%02d-%02d %02d:%02d:%02d\n",
34                 i, hex (t),
35                 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
36                 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
37         pt = t;
38         }
39     } /* gm_check */
40
41 int check_gm_max ()
42 {
43     tmp = NULL;
44     pt  = 0;
45     if (tmp == NULL || tmp->tm_year < 0) {
46         for (i = 63; i >= 0; i--) {
47             time_t x = pt | ((time_t)1 << i);
48             if (x < 0 || x < pt) continue;
49             gm_check (x, 69, 0x7fffffff);
50             }
51         }
52     pt_max = pt;
53     return (0);
54     } /* check_gm_max */
55
56 int check_gm_min ()
57 {
58     tmp = NULL;
59     pt  = 0;
60     if (tmp == NULL) {
61         for (i = 36; i >= 0; i--) {
62             time_t x = pt - ((time_t)1 << i);
63             if (x > 0) continue;
64             gm_check (x, -1900, 70);
65             }
66         }
67     pt_min = pt;
68     return (0);
69     } /* check_gm_min */
70
71 void lt_check (time_t t, int min_year, int max_year)
72 {
73     if (sizeof (time_t) > 4 && t > 0x7ffffffffffff000LL)
74         tmp = NULL;
75     else
76         tmp = localtime (&t);
77     if ( tmp == NULL ||
78         /* Check tm_year overflow */
79          tmp->tm_year < min_year || tmp->tm_year > max_year) {
80         if (opt_v)
81             fprintf (stderr, "localtime (%ld) failed with errno %d\n", t, errno);
82         }
83     else {
84         if (opt_v)
85             fprintf (stderr, "%3d:%s: %12ld-%02d-%02d %02d:%02d:%02d\n",
86                 i, hex (t),
87                 tmp->tm_year + 1900, tmp->tm_mon + 1, tmp->tm_mday,
88                 tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
89         pt = t;
90         }
91     } /* lt_check */
92
93 int check_lt_max ()
94 {
95     tmp = NULL;
96     pt  = 0;
97     if (tmp == NULL || tmp->tm_year < 0) {
98         for (i = 63; i >= 0; i--) {
99             time_t x = pt | ((time_t)1 << i);
100             if (x < 0 || x < pt) continue;
101             lt_check (x, 69, 0x7fffffff);
102             }
103         }
104     pt_max = pt;
105     return (0);
106     } /* check_lt_max */
107
108 int check_lt_min ()
109 {
110     tmp = NULL;
111     pt  = 0;
112     if (tmp == NULL) {
113         for (i = 36; i >= 0; i--) {
114             time_t x = pt - ((time_t)1 << i);
115             if (x > 0) continue;
116             lt_check (x, -1900, 70);
117             }
118         }
119     pt_min = pt;
120     return (0);
121     } /* check_lt_min */
122
123 int main (int argc, char *argv[])
124 {
125     time_t gm_max, gm_min, lt_max, lt_min;
126     if (argc > 1 && strcmp (argv[1], "-v") == 0) opt_v++;
127
128     check_gm_max (); gm_max = pt_max;
129     check_gm_min (); gm_min = pt_min;
130     check_lt_max (); lt_max = pt_max;
131     check_lt_min (); lt_min = pt_min;
132
133     opt_v++;
134     printf ("======================\n");
135     printf ("Sizeof time_t = %ld\n", (i = sizeof (time_t)));
136     printf ("gmtime () boundaries:\n");
137     gm_check (gm_max,    69, 0x7fffffff);
138     gm_check (gm_min, -1900,         70);
139     printf ("localtime () boundaries:\n");
140     lt_check (lt_max,    69, 0x7fffffff);
141     lt_check (lt_min, -1900,         70);
142     printf ("Configure variables:\n");
143     printf ("sGMTIME_max='%ld'\n",    gm_max);
144     printf ("sGMTIME_min='%ld'\n",    gm_min);
145     printf ("sLOCALTIME_max='%ld'\n", lt_max);
146     printf ("sLOCALTIME_min='%ld'\n", lt_min);
147     return (0);
148     } /* main */