aboutsummaryrefslogtreecommitdiff
path: root/contrib/bmake/unit-tests/varmod-gmtime.mk
blob: db24b1680c4610fdd9fac075c53aa435f178d1be (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# $NetBSD: varmod-gmtime.mk,v 1.22 2024/04/20 10:18:55 rillig Exp $
#
# Tests for the :gmtime variable modifier, which formats a timestamp
# using strftime(3) in UTC.
#
# See also:
#	varmod-localtime.mk

.if ${TZ:Uundefined} != "undefined"	# see unit-tests/Makefile
.  error
.endif

# Test for the default time format, %c.  Since the time always varies, it's
# only possible to check for the general format here.  The names of the
# month and weekday are always in English, independent from the locale.
# Example: Thu Oct 29 18:56:41 2020
.if ${:U:gmtime:tW:M??? ??? ?? ??\:??\:?? ????} == ""
.  error
.endif


# modifier name too short, falling back to the SysV modifier.
.if ${%Y:L:gmtim=1593536400} != "%Y"
.  error
.endif


# 2020-07-01T00:00:00Z
.if ${%Y:L:gmtime=1593536400} != "2020"
.  error
.endif


# modifier name too long, falling back to the SysV modifier.
.if ${%Y:L:gmtimer=1593536400} != "%Y"
.  error
.endif


# If the modifier name is not matched exactly, fall back to the
# :from=to modifier.
.if ${gmtime:L:gm%=local%} != "localtime"
.  error
.endif


# Before var.c 1.1050 from 2023-05-09, it was not possible to pass the
# seconds via an expression.
.if ${%Y:L:gmtime=${:U1593536400}} != "2020"
.  error
.endif


# Before var.c 1.631 from 2020-10-31 21:40:20, it was possible to pass
# negative time stamps to the :gmtime modifier, resulting in dates before
# 1970.  Going back 50 years in the past is not a practical use case for
# make.  Therefore, since var.c 1.631, negative time stamps produce a
# parse error.
# expect+2: while evaluating "${:L:gmtime=-1} != """: Invalid time value "-1"
# expect+1: Malformed conditional (${:L:gmtime=-1} != "")
.if ${:L:gmtime=-1} != ""
.  error
.else
.  error
.endif


# Spaces were allowed before var.c 1.631 from 2020-10-31 21:40:20, not
# because it would make sense but just as a side-effect from using strtoul.
# expect+2: while evaluating "${:L:gmtime= 1} != """: Invalid time value " 1"
# expect+1: Malformed conditional (${:L:gmtime= 1} != "")
.if ${:L:gmtime= 1} != ""
.  error
.else
.  error
.endif


# 0 means now; this differs from GNode.mtime, where a 0 means nonexistent.
# Since "now" constantly changes, the strongest possible test is to match the
# resulting pattern.
.if !${:L:gmtime=0:tW:M??? ??? ?? ??\:??\:?? 20??}
.  error
.endif


.if ${:L:gmtime=1} != "Thu Jan  1 00:00:01 1970"
.  error
.endif


# INT32_MAX
.if ${:L:gmtime=2147483647} != "Tue Jan 19 03:14:07 2038"
.  error
.endif


.if ${:L:gmtime=2147483648} == "Tue Jan 19 03:14:08 2038"
# All systems that have unsigned time_t or 64-bit time_t.
.elif ${:L:gmtime=2147483648} == "Fri Dec 13 20:45:52 1901"
# FreeBSD-12.0-i386 still has 32-bit signed time_t, see
# sys/x86/include/_types.h, __LP64__.
#
# Linux on 32-bit systems may still have 32-bit signed time_t, see
# sysdeps/unix/sysv/linux/generic/bits/typesizes.h, __TIMESIZE.
.else
.  error
.endif


# Integer overflow, at least before var.c 1.631 from 2020-10-31.
# Because this modifier is implemented using strtoul, the parsed time was
# ULONG_MAX, which got converted to -1.  This resulted in a time stamp of
# the second before 1970.
#
# Since var.c 1.631 from 2020-10-31, the overflow is detected and produces a
# parse error.
# expect+2: while evaluating "${:L:gmtime=10000000000000000000000000000000} != """: Invalid time value "10000000000000000000000000000000"
# expect+1: Malformed conditional (${:L:gmtime=10000000000000000000000000000000} != "")
.if ${:L:gmtime=10000000000000000000000000000000} != ""
.  error
.else
.  error
.endif

# Before var.c 1.631 from 2020-10-31, there was no error handling while
# parsing the :gmtime modifier, thus no error message was printed.  Parsing
# stopped after the '=', and the remaining string was parsed for more variable
# modifiers.  Because of the unknown modifier 'e' from the 'error', the whole
# variable value was discarded and thus not printed.
# expect+2: while evaluating "${:L:gmtime=error} != """: Invalid time value "error"
# expect+1: Malformed conditional (${:L:gmtime=error} != "")
.if ${:L:gmtime=error} != ""
.  error
.else
.  error
.endif

# Before var.c 1.1050 from 2023-05-09, the timestamp could be directly
# followed by the next modifier, without a ':' separator.  This was the same
# bug as for the ':L' and ':P' modifiers.
# expect+2: while evaluating variable "%Y": Invalid time value "100000S,1970,bad,"
# expect+1: Malformed conditional (${%Y:L:gmtime=100000S,1970,bad,} != "bad")
.if ${%Y:L:gmtime=100000S,1970,bad,} != "bad"
.  error
.endif


# Before var.c 1.1062 from 2023-08-19, ':gmtime' but not ':localtime' reported
# wrong values for '%s', depending on the operating system and the timezone.
export TZ=UTC
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
export TZ=Europe/Berlin
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
export TZ=UTC
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
export TZ=America/Los_Angeles
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
export TZ=UTC
.for t in ${%s:L:gmtime} ${%s:L:localtime}
TIMESTAMPS+= $t
.endfor
.for a b in ${TIMESTAMPS:[1]} ${TIMESTAMPS:@t@$t $t@} ${TIMESTAMPS:[-1]}
.  if $a > $b
.    warning timestamp $a > $b
.  endif
.endfor


.if ${year=%Y month=%m day=%d:L:gmtime=1459494000} != "year=2016 month=04 day=01"
.  error
.endif
# Slightly contorted syntax to convert a UTC timestamp from an expression to a
# formatted timestamp.
.if ${%Y%m%d:L:${gmtime=${:U1459494000}:L}} != "20160401"
.  error
.endif


all: