xref: /freebsd/contrib/bmake/unit-tests/varmod-gmtime.mk (revision 6a7405f5a6b639682cacf01e35d561411ff556aa)
1*6a7405f5SSimon J. Gerraty# $NetBSD: varmod-gmtime.mk,v 1.27 2025/01/11 20:54:45 rillig Exp $
22c3632d1SSimon J. Gerraty#
32c3632d1SSimon J. Gerraty# Tests for the :gmtime variable modifier, which formats a timestamp
4956e45f6SSimon J. Gerraty# using strftime(3) in UTC.
5c1d01b5fSSimon J. Gerraty#
6c1d01b5fSSimon J. Gerraty# See also:
7c1d01b5fSSimon J. Gerraty#	varmod-localtime.mk
82c3632d1SSimon J. Gerraty
906b9b3e0SSimon J. Gerraty.if ${TZ:Uundefined} != "undefined"	# see unit-tests/Makefile
1006b9b3e0SSimon J. Gerraty.  error
1106b9b3e0SSimon J. Gerraty.endif
12956e45f6SSimon J. Gerraty
13956e45f6SSimon J. Gerraty# Test for the default time format, %c.  Since the time always varies, it's
14956e45f6SSimon J. Gerraty# only possible to check for the general format here.  The names of the
15956e45f6SSimon J. Gerraty# month and weekday are always in English, independent from the locale.
16956e45f6SSimon J. Gerraty# Example: Thu Oct 29 18:56:41 2020
17956e45f6SSimon J. Gerraty.if ${:U:gmtime:tW:M??? ??? ?? ??\:??\:?? ????} == ""
18956e45f6SSimon J. Gerraty.  error
19956e45f6SSimon J. Gerraty.endif
202c3632d1SSimon J. Gerraty
21956e45f6SSimon J. Gerraty
2206b9b3e0SSimon J. Gerraty# modifier name too short, falling back to the SysV modifier.
2306b9b3e0SSimon J. Gerraty.if ${%Y:L:gmtim=1593536400} != "%Y"
2406b9b3e0SSimon J. Gerraty.  error
2506b9b3e0SSimon J. Gerraty.endif
2606b9b3e0SSimon J. Gerraty
27956e45f6SSimon J. Gerraty
28956e45f6SSimon J. Gerraty# 2020-07-01T00:00:00Z
2906b9b3e0SSimon J. Gerraty.if ${%Y:L:gmtime=1593536400} != "2020"
3006b9b3e0SSimon J. Gerraty.  error
3106b9b3e0SSimon J. Gerraty.endif
32956e45f6SSimon J. Gerraty
3306b9b3e0SSimon J. Gerraty
3406b9b3e0SSimon J. Gerraty# modifier name too long, falling back to the SysV modifier.
3506b9b3e0SSimon J. Gerraty.if ${%Y:L:gmtimer=1593536400} != "%Y"
3606b9b3e0SSimon J. Gerraty.  error
3706b9b3e0SSimon J. Gerraty.endif
3806b9b3e0SSimon J. Gerraty
39956e45f6SSimon J. Gerraty
40956e45f6SSimon J. Gerraty# If the modifier name is not matched exactly, fall back to the
41956e45f6SSimon J. Gerraty# :from=to modifier.
4206b9b3e0SSimon J. Gerraty.if ${gmtime:L:gm%=local%} != "localtime"
4306b9b3e0SSimon J. Gerraty.  error
4406b9b3e0SSimon J. Gerraty.endif
452c3632d1SSimon J. Gerraty
462c3632d1SSimon J. Gerraty
47c1d01b5fSSimon J. Gerraty# Before var.c 1.1050 from 2023-05-09, it was not possible to pass the
48d5e0a182SSimon J. Gerraty# seconds via an expression.
49c1d01b5fSSimon J. Gerraty.if ${%Y:L:gmtime=${:U1593536400}} != "2020"
5006b9b3e0SSimon J. Gerraty.  error
5106b9b3e0SSimon J. Gerraty.endif
522c3632d1SSimon J. Gerraty
53956e45f6SSimon J. Gerraty
5406b9b3e0SSimon J. Gerraty# Before var.c 1.631 from 2020-10-31 21:40:20, it was possible to pass
5506b9b3e0SSimon J. Gerraty# negative time stamps to the :gmtime modifier, resulting in dates before
5606b9b3e0SSimon J. Gerraty# 1970.  Going back 50 years in the past is not a practical use case for
5706b9b3e0SSimon J. Gerraty# make.  Therefore, since var.c 1.631, negative time stamps produce a
5806b9b3e0SSimon J. Gerraty# parse error.
59*6a7405f5SSimon J. Gerraty# expect+1: Invalid time value "-1"
6006b9b3e0SSimon J. Gerraty.if ${:L:gmtime=-1} != ""
6106b9b3e0SSimon J. Gerraty.  error
6206b9b3e0SSimon J. Gerraty.else
6306b9b3e0SSimon J. Gerraty.  error
6406b9b3e0SSimon J. Gerraty.endif
65956e45f6SSimon J. Gerraty
66956e45f6SSimon J. Gerraty
67dba7b0efSSimon J. Gerraty# Spaces were allowed before var.c 1.631 from 2020-10-31 21:40:20, not
68dba7b0efSSimon J. Gerraty# because it would make sense but just as a side-effect from using strtoul.
69*6a7405f5SSimon J. Gerraty# expect+1: Invalid time value " 1"
7006b9b3e0SSimon J. Gerraty.if ${:L:gmtime= 1} != ""
7106b9b3e0SSimon J. Gerraty.  error
72c1d01b5fSSimon J. Gerraty.else
73c1d01b5fSSimon J. Gerraty.  error
7406b9b3e0SSimon J. Gerraty.endif
75956e45f6SSimon J. Gerraty
76956e45f6SSimon J. Gerraty
7706b9b3e0SSimon J. Gerraty# 0 means now; this differs from GNode.mtime, where a 0 means nonexistent.
7806b9b3e0SSimon J. Gerraty# Since "now" constantly changes, the strongest possible test is to match the
7906b9b3e0SSimon J. Gerraty# resulting pattern.
8006b9b3e0SSimon J. Gerraty.if !${:L:gmtime=0:tW:M??? ??? ?? ??\:??\:?? 20??}
8106b9b3e0SSimon J. Gerraty.  error
8206b9b3e0SSimon J. Gerraty.endif
83956e45f6SSimon J. Gerraty
84956e45f6SSimon J. Gerraty
8506b9b3e0SSimon J. Gerraty.if ${:L:gmtime=1} != "Thu Jan  1 00:00:01 1970"
8606b9b3e0SSimon J. Gerraty.  error
8706b9b3e0SSimon J. Gerraty.endif
88956e45f6SSimon J. Gerraty
8906b9b3e0SSimon J. Gerraty
9006b9b3e0SSimon J. Gerraty# INT32_MAX
9106b9b3e0SSimon J. Gerraty.if ${:L:gmtime=2147483647} != "Tue Jan 19 03:14:07 2038"
9206b9b3e0SSimon J. Gerraty.  error
9306b9b3e0SSimon J. Gerraty.endif
9406b9b3e0SSimon J. Gerraty
9506b9b3e0SSimon J. Gerraty
9606b9b3e0SSimon J. Gerraty.if ${:L:gmtime=2147483648} == "Tue Jan 19 03:14:08 2038"
9706b9b3e0SSimon J. Gerraty# All systems that have unsigned time_t or 64-bit time_t.
98dba7b0efSSimon J. Gerraty.elif ${:L:gmtime=2147483648} == "Fri Dec 13 20:45:52 1901"
99dba7b0efSSimon J. Gerraty# FreeBSD-12.0-i386 still has 32-bit signed time_t, see
100dba7b0efSSimon J. Gerraty# sys/x86/include/_types.h, __LP64__.
101dba7b0efSSimon J. Gerraty#
102dba7b0efSSimon J. Gerraty# Linux on 32-bit systems may still have 32-bit signed time_t, see
103dba7b0efSSimon J. Gerraty# sysdeps/unix/sysv/linux/generic/bits/typesizes.h, __TIMESIZE.
10406b9b3e0SSimon J. Gerraty.else
10506b9b3e0SSimon J. Gerraty.  error
10606b9b3e0SSimon J. Gerraty.endif
10706b9b3e0SSimon J. Gerraty
10806b9b3e0SSimon J. Gerraty
10906b9b3e0SSimon J. Gerraty# Integer overflow, at least before var.c 1.631 from 2020-10-31.
11006b9b3e0SSimon J. Gerraty# Because this modifier is implemented using strtoul, the parsed time was
11106b9b3e0SSimon J. Gerraty# ULONG_MAX, which got converted to -1.  This resulted in a time stamp of
11206b9b3e0SSimon J. Gerraty# the second before 1970.
11306b9b3e0SSimon J. Gerraty#
114c1d01b5fSSimon J. Gerraty# Since var.c 1.631 from 2020-10-31, the overflow is detected and produces a
115c1d01b5fSSimon J. Gerraty# parse error.
116*6a7405f5SSimon J. Gerraty# expect+1: Invalid time value "10000000000000000000000000000000"
11706b9b3e0SSimon J. Gerraty.if ${:L:gmtime=10000000000000000000000000000000} != ""
11806b9b3e0SSimon J. Gerraty.  error
11906b9b3e0SSimon J. Gerraty.else
12006b9b3e0SSimon J. Gerraty.  error
12106b9b3e0SSimon J. Gerraty.endif
12206b9b3e0SSimon J. Gerraty
12306b9b3e0SSimon J. Gerraty# Before var.c 1.631 from 2020-10-31, there was no error handling while
124dba7b0efSSimon J. Gerraty# parsing the :gmtime modifier, thus no error message was printed.  Parsing
12506b9b3e0SSimon J. Gerraty# stopped after the '=', and the remaining string was parsed for more variable
12606b9b3e0SSimon J. Gerraty# modifiers.  Because of the unknown modifier 'e' from the 'error', the whole
12706b9b3e0SSimon J. Gerraty# variable value was discarded and thus not printed.
128*6a7405f5SSimon J. Gerraty# expect+1: Invalid time value "error"
12906b9b3e0SSimon J. Gerraty.if ${:L:gmtime=error} != ""
13006b9b3e0SSimon J. Gerraty.  error
13106b9b3e0SSimon J. Gerraty.else
13206b9b3e0SSimon J. Gerraty.  error
13306b9b3e0SSimon J. Gerraty.endif
13406b9b3e0SSimon J. Gerraty
135c1d01b5fSSimon J. Gerraty# Before var.c 1.1050 from 2023-05-09, the timestamp could be directly
136c1d01b5fSSimon J. Gerraty# followed by the next modifier, without a ':' separator.  This was the same
137c1d01b5fSSimon J. Gerraty# bug as for the ':L' and ':P' modifiers.
138*6a7405f5SSimon J. Gerraty# expect+1: Invalid time value "100000S,1970,bad,"
139c1d01b5fSSimon J. Gerraty.if ${%Y:L:gmtime=100000S,1970,bad,} != "bad"
140c1d01b5fSSimon J. Gerraty.  error
141c1d01b5fSSimon J. Gerraty.endif
14206b9b3e0SSimon J. Gerraty
14398875883SSimon J. Gerraty
14498875883SSimon J. Gerraty# Before var.c 1.1062 from 2023-08-19, ':gmtime' but not ':localtime' reported
14598875883SSimon J. Gerraty# wrong values for '%s', depending on the operating system and the timezone.
14698875883SSimon J. Gerratyexport TZ=UTC
14798875883SSimon J. Gerraty.for t in ${%s:L:gmtime} ${%s:L:localtime}
14898875883SSimon J. GerratyTIMESTAMPS+= $t
14998875883SSimon J. Gerraty.endfor
15098875883SSimon J. Gerratyexport TZ=Europe/Berlin
15198875883SSimon J. Gerraty.for t in ${%s:L:gmtime} ${%s:L:localtime}
15298875883SSimon J. GerratyTIMESTAMPS+= $t
15398875883SSimon J. Gerraty.endfor
15498875883SSimon J. Gerratyexport TZ=UTC
15598875883SSimon J. Gerraty.for t in ${%s:L:gmtime} ${%s:L:localtime}
15698875883SSimon J. GerratyTIMESTAMPS+= $t
15798875883SSimon J. Gerraty.endfor
15898875883SSimon J. Gerratyexport TZ=America/Los_Angeles
15998875883SSimon J. Gerraty.for t in ${%s:L:gmtime} ${%s:L:localtime}
16098875883SSimon J. GerratyTIMESTAMPS+= $t
16198875883SSimon J. Gerraty.endfor
16298875883SSimon J. Gerratyexport TZ=UTC
16398875883SSimon J. Gerraty.for t in ${%s:L:gmtime} ${%s:L:localtime}
16498875883SSimon J. GerratyTIMESTAMPS+= $t
16598875883SSimon J. Gerraty.endfor
16698875883SSimon J. Gerraty.for a b in ${TIMESTAMPS:[1]} ${TIMESTAMPS:@t@$t $t@} ${TIMESTAMPS:[-1]}
16798875883SSimon J. Gerraty.  if $a > $b
16898875883SSimon J. Gerraty.    warning timestamp $a > $b
16998875883SSimon J. Gerraty.  endif
17098875883SSimon J. Gerraty.endfor
17198875883SSimon J. Gerraty
172d5e0a182SSimon J. Gerraty
173d5e0a182SSimon J. Gerraty.if ${year=%Y month=%m day=%d:L:gmtime=1459494000} != "year=2016 month=04 day=01"
174d5e0a182SSimon J. Gerraty.  error
175d5e0a182SSimon J. Gerraty.endif
176d5e0a182SSimon J. Gerraty# Slightly contorted syntax to convert a UTC timestamp from an expression to a
177d5e0a182SSimon J. Gerraty# formatted timestamp.
178d5e0a182SSimon J. Gerraty.if ${%Y%m%d:L:${gmtime=${:U1459494000}:L}} != "20160401"
179d5e0a182SSimon J. Gerraty.  error
180d5e0a182SSimon J. Gerraty.endif
181d5e0a182SSimon J. Gerraty
182d5e0a182SSimon J. Gerraty
18306b9b3e0SSimon J. Gerratyall:
184