Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
6433 siemargl 1
#define _XOPEN_SOURCE 700
2
#include 
3
#include 
4
#include 
5
#include 
6
#include 
7
#include 
8
#include "test.h"
9
 
10
/* We use this instead of memcmp because some broken C libraries
11
 * add additional nonstandard fields to struct tm... */
12
 
13
int tm_cmp(struct tm tm1, struct tm tm2)
14
{
15
	return  tm1.tm_sec  != tm2.tm_sec  ||
16
		tm1.tm_min  != tm2.tm_min  ||
17
		tm1.tm_hour != tm2.tm_hour ||
18
		tm1.tm_mday != tm2.tm_mday ||
19
		tm1.tm_mon  != tm2.tm_mon  ||
20
		tm1.tm_year != tm2.tm_year ||
21
		tm1.tm_wday != tm2.tm_wday ||
22
		tm1.tm_yday != tm2.tm_yday ||
23
		tm1.tm_isdst!= tm2.tm_isdst;
24
}
25
 
26
char *tm_str(struct tm tm)
27
{
28
	static int i;
29
	static char b[4][64];
30
	i = (i+1)%4;
31
	snprintf(b[i], sizeof b[i],
32
		"s=%02d m=%02d h=%02d mday=%02d mon=%02d year=%04d wday=%d yday=%d isdst=%d",
33
		tm.tm_sec, tm.tm_min, tm.tm_hour,
34
		tm.tm_mday, tm.tm_mon, tm.tm_year,
35
		tm.tm_wday, tm.tm_yday, tm.tm_isdst);
36
	return b[i];
37
}
38
 
39
#define TM(ss,mm,hh,md,mo,yr,wd,yd,dst) (struct tm){ \
40
	.tm_sec = ss, .tm_min = mm, .tm_hour = hh,    \
41
	.tm_mday = md, .tm_mon = mo, .tm_year = yr,    \
42
	.tm_wday = wd, .tm_yday = yd, .tm_isdst = dst }
43
 
44
#define TM_EPOCH    TM(0,0,0,1,0,70,4,0,0)
45
#define TM_Y2038_1S TM(7,14,3,19,0,138,2,18,0)
46
#define TM_Y2038    TM(8,14,3,19,0,138,2,18,0)
47
 
48
static void sec2tm(time_t t, char *m)
49
{
50
	struct tm *tm;
51
	time_t r;
52
 
53
	errno = 0;
54
	tm = gmtime(&t);
55
	if (errno != 0)
56
		t_error("%s: gmtime((time_t)%lld) should not set errno, got %s\n",
57
			m, (long long)t, strerror(errno));
58
	errno = 0;
59
	r = mktime(tm);
60
	if (errno != 0)
61
		t_error("%s: mktime(%s) should not set errno, got %s\n",
62
			m, tm_str(*tm), strerror(errno));
63
	if (t != r)
64
		t_error("%s: mktime(gmtime(%lld)) roundtrip failed: got %lld (gmtime is %s)\n",
65
			m, (long long)t, (long long)r, tm_str(*tm));
66
}
67
 
68
static void tm2sec(struct tm *tm, int big, char *m)
69
{
70
	struct tm *r;
71
	time_t t;
72
	int overflow = big && (time_t)LLONG_MAX!=LLONG_MAX;
73
 
74
	errno = 0;
75
	t = mktime(tm);
76
	if (overflow && t != -1)
77
		t_error("%s: mktime(%s) expected -1, got (time_t)%ld\n",
78
			m, tm_str(*tm), (long)t);
79
	if (overflow && errno != 10000) //EOVERFLOW
80
		t_error("%s: mktime(%s) expected EOVERFLOW (%s), got (%s)\n",
81
			m, tm_str(*tm), strerror(10000), strerror(errno));
82
	if (!overflow && t == -1)
83
		t_error("%s: mktime(%s) expected success, got (time_t)-1\n",
84
			m, tm_str(*tm));
85
	if (!overflow && errno)
86
		t_error("%s: mktime(%s) expected no error, got (%s)\n",
87
			m, tm_str(*tm), strerror(errno));
88
	r = gmtime(&t);
89
	if (!overflow && tm_cmp(*r, *tm))
90
		t_error("%s: gmtime(mktime(%s)) roundtrip failed: got %s\n",
91
			m, tm_str(*tm), tm_str(*r));
92
}
93
 
94
int main(void)
95
{
96
	time_t t;
97
 
98
	putenv("TZ=GMT");
99
	tzset();
100
	tm2sec(&TM_EPOCH, 0, "gmtime(0)");
101
	tm2sec(&TM_Y2038_1S, 0, "2038-1s");
102
	tm2sec(&TM_Y2038, 1, "2038");
103
 
104
	sec2tm(0, "EPOCH");
105
	for (t = 1; t < 1000; t++)
106
		sec2tm(t*100003, "EPOCH+eps");
107
 
108
	/* FIXME: set a TZ var and check DST boundary conditions */
109
	return t_status;
110
}