tech-toolchain archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
make: control utc value used for :{gm,local}time
The :gmtime and :localtime modifiers in make would be more useful if the
value of utc used could be controlled.
For example, using the mtime of a file obtained via 'stat -s'
The patch below allows for this - as the unit-test shows:
April1= 1459494000
# slightly contorted syntax to use utc via variable
strftime:
@echo ${year=%Y month=%m day=%d:L:gmtime=1459494000}
@echo date=${%Y%m%d:L:${gmtime=${April1}:L}}
outputs
year=2016 month=04 day=01
date=20160401
:gtime=0 or just :gtime uses the current time as before.
As noted above, using a utc value from a variable is not (yet)
as simple as one might want, I didn't want to add all the extra code for
that until the general idea is OK'd.
In the example above ${gmtime=${April1}:L} takes advantage of the
recursive nature of modifier application, thus ${April1} is expanded
before seen by gmtime logic.
--sjg
diff -r 2411e3332160 bmake/make.1
--- a/bmake/make.1 Tue Dec 13 12:45:14 2016 -0800
+++ b/bmake/make.1 Sat Jan 14 13:30:37 2017 -0800
@@ -1212,18 +1212,24 @@
.Nm .
.It Cm \&:R
Replaces each word in the variable with everything but its suffix.
-.It Cm \&:gmtime
+.It Cm \&:gmtime[=utc]
The value is a format string for
.Xr strftime 3 ,
-using the current
+using
.Xr gmtime 3 .
+If a
+.Va utc
+value is not provided or is 0, the current time is used.
.It Cm \&:hash
Compute a 32-bit hash of the value and encode it as hex digits.
-.It Cm \&:localtime
+.It Cm \&:localtime[=utc]
The value is a format string for
.Xr strftime 3 ,
-using the current
+using
.Xr localtime 3 .
+If a
+.Va utc
+value is not provided or is 0, the current time is used.
.It Cm \&:tA
Attempt to convert variable to an absolute path using
.Xr realpath 3 ,
diff -r 2411e3332160 bmake/unit-tests/varmisc.exp
--- a/bmake/unit-tests/varmisc.exp Tue Dec 13 12:45:14 2016 -0800
+++ b/bmake/unit-tests/varmisc.exp Sat Jan 14 13:30:37 2017 -0800
@@ -17,4 +17,6 @@
FALSE
do not evaluate or expand :? if discarding
is set
+year=2016 month=04 day=01
+date=20160401
exit status 0
diff -r 2411e3332160 bmake/unit-tests/varmisc.mk
--- a/bmake/unit-tests/varmisc.mk Tue Dec 13 12:45:14 2016 -0800
+++ b/bmake/unit-tests/varmisc.mk Sat Jan 14 13:30:37 2017 -0800
@@ -2,7 +2,8 @@
#
# Miscellaneous variable tests.
-all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none
+all: unmatched_var_paren D_true U_true D_false U_false Q_lhs Q_rhs NQ_none \
+ strftime
unmatched_var_paren:
@echo ${foo::=foo-text}
@@ -40,3 +41,11 @@
NQ_none:
@echo do not evaluate or expand :? if discarding
@echo ${VSET:U${1:L:?${True}:${False}}}
+
+April1= 1459494000
+
+# slightly contorted syntax to use utc via variable
+strftime:
+ @echo ${year=%Y month=%m day=%d:L:gmtime=1459494000}
+ @echo date=${%Y%m%d:L:${gmtime=${April1}:L}}
+
diff -r 2411e3332160 bmake/var.c
--- a/bmake/var.c Tue Dec 13 12:45:14 2016 -0800
+++ b/bmake/var.c Sat Jan 14 13:30:37 2017 -0800
@@ -2379,12 +2379,12 @@
}
static char *
-VarStrftime(const char *fmt, int zulu)
+VarStrftime(const char *fmt, int zulu, time_t utc)
{
char buf[BUFSIZ];
- time_t utc;
-
- time(&utc);
+
+ if (!utc)
+ time(&utc);
if (!*fmt)
fmt = "%c";
strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc));
@@ -2481,6 +2481,8 @@
/* we now have some modifiers with long names */
#define STRMOD_MATCH(s, want, n) \
(strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':'))
+#define STRMOD_MATCHX(s, want, n) \
+ (strncmp(s, want, n) == 0 && (s[n] == endc || s[n] == ':' || s[n] == '='))
static char *
ApplyModifiers(char *nstr, const char *tstr,
@@ -2492,12 +2494,14 @@
const char *cp; /* Secondary pointer into str (place marker
* for tstr) */
char *newStr; /* New value to return */
+ char *ep;
char termc; /* Character which terminated scan */
int cnt; /* Used to count brace pairs when variable in
* in parens or braces */
char delim;
int modifier; /* that we are processing */
Var_Parse_State parsestate; /* Flags passed to helper functions */
+ time_t utc; /* for VarStrftime */
delim = '\0';
parsestate.oneBigWord = FALSE;
@@ -2954,9 +2958,15 @@
}
case 'g':
cp = tstr + 1; /* make sure it is set */
- if (STRMOD_MATCH(tstr, "gmtime", 6)) {
- newStr = VarStrftime(nstr, 1);
- cp = tstr + 6;
+ if (STRMOD_MATCHX(tstr, "gmtime", 6)) {
+ if (tstr[6] == '=') {
+ utc = strtoul(&tstr[7], &ep, 10);
+ cp = ep;
+ } else {
+ utc = 0;
+ cp = tstr + 6;
+ }
+ newStr = VarStrftime(nstr, 1, utc);
termc = *cp;
} else {
goto default_case;
@@ -2974,9 +2984,15 @@
break;
case 'l':
cp = tstr + 1; /* make sure it is set */
- if (STRMOD_MATCH(tstr, "localtime", 9)) {
- newStr = VarStrftime(nstr, 0);
- cp = tstr + 9;
+ if (STRMOD_MATCHX(tstr, "localtime", 9)) {
+ if (tstr[9] == '=') {
+ utc = strtoul(&tstr[10], &ep, 10);
+ cp = ep;
+ } else {
+ utc = 0;
+ cp = tstr + 9;
+ }
+ newStr = VarStrftime(nstr, 0, utc);
termc = *cp;
} else {
goto default_case;
Home |
Main Index |
Thread Index |
Old Index