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