From 432741784ea6e0e7c022a8252944ba60281d3713 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Tue, 21 Sep 2021 10:24:48 -0700
Subject: [PATCH 3/3] New macro BACKPICK to control alike-since-1970
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This patch adds a new BACKPICK macro to select whether
the recent alike-since-1970 patch takes effect.
With a suitable file bias2021a.bp, building with
‘make PACKRATDATA=backzone BACKPICK=bias2021a.bp’
causes the build to act as if the patch had not been installed, by
generating files tzdata.zi etc. that omit the patch’s effect.
* Makefile (BACKPICK): New macro.
(DSTDATA_ZI_DEPS, vanguard.zi main.zi rearguard.zi, tzdata.zi)
(INSTALLARGS): Use it.
* ziguard.awk (BEGIN): Use BACKPICK to initialize backpick, backlink.
Discard backzone lines that BACKPICK does not select.
(END): Redo Link lines according to BACKPICK's directions.
* zishrink.awk (BEGIN): Append backpick info to version number.
---
 Makefile     | 29 ++++++++++++++++++++++-------
 ziguard.awk  | 41 +++++++++++++++++++++++++++++++++++++++++
 zishrink.awk |  3 +++
 3 files changed, 66 insertions(+), 7 deletions(-)

diff --git a/Makefile b/Makefile
index d7fddf3..5d22090 100644
--- a/Makefile
+++ b/Makefile
@@ -176,12 +176,21 @@ TZDATA_TEXT=	leapseconds tzdata.zi
 
 BACKWARD=	backward
 
-# If you want out-of-scope and often-wrong data from the file 'backzone', use
-#	PACKRATDATA=	backzone
-# To omit this data, use
-#	PACKRATDATA=
+# To omit out-of-scope and often-wrong data from the file 'backzone', use
+#	PACKRATDATA=         BACKPICK=
+# To include that data, use
+#	PACKRATDATA=backzone BACKPICK=
+# To include that data only for names given in the backpick file foo.bp, use
+#	PACKRATDATA=backzone BACKPICK=foo.bp
+# where lines in foo.bp are of the form:
+#	Backpick NAME
+#   to select the 'backzone' Zone or Link named NAME, or of the form:
+#	Link TARGET LINKNAME
+#   with the same meaning as in ordinary .zi files.
+# foo.bp lines that are empty or start with '#' are ignored.
 
 PACKRATDATA=
+BACKPICK=
 
 # The name of a locale using the UTF-8 encoding, used during self-tests.
 # The tests are skipped if the name does not appear to work on this system.
@@ -519,7 +528,7 @@ ZONETABLES=	zone1970.tab zone.tab
 TABDATA=	iso3166.tab $(TZDATA_TEXT) $(ZONETABLES)
 LEAP_DEPS=	leapseconds.awk leap-seconds.list
 TZDATA_ZI_DEPS=	ziguard.awk zishrink.awk version $(TDATA) $(PACKRATDATA)
-DSTDATA_ZI_DEPS= ziguard.awk $(TDATA) $(PACKRATDATA)
+DSTDATA_ZI_DEPS= ziguard.awk $(TDATA) $(PACKRATDATA) $(BACKPICK)
 DATA=		$(TDATA_TO_CHECK) backzone iso3166.tab leap-seconds.list \
 			leapseconds $(ZONETABLES)
 AWK_SCRIPTS=	checklinks.awk checktab.awk leapseconds.awk \
@@ -607,14 +616,19 @@ version:	$(VERSION_DEPS)
 
 # These files can be tailored by setting BACKWARD and PACKRATDATA.
 vanguard.zi main.zi rearguard.zi: $(DSTDATA_ZI_DEPS)
-		$(AWK) -v DATAFORM=`expr $@ : '\(.*\).zi'` -f ziguard.awk \
+		$(AWK) \
+		  -v BACKPICK='$(BACKPICK)' \
+		  -v DATAFORM=`expr $@ : '\(.*\).zi'` \
+		  -v PACKRATDATA='$(PACKRATDATA)' \
+		  -f ziguard.awk \
 		  $(TDATA) $(PACKRATDATA) >$@.out
 		mv $@.out $@
 # This file has a version comment that attempts to capture any tailoring
-# via BACKWARD, DATAFORM, PACKRATDATA, and REDO.
+# via BACKPICK, BACKWARD, DATAFORM, PACKRATDATA, and REDO.
 tzdata.zi:	$(DATAFORM).zi version zishrink.awk
 		version=`sed 1q version` && \
 		  LC_ALL=C $(AWK) \
+		    -v backpick='$(BACKPICK)' \
 		    -v dataform='$(DATAFORM)' \
 		    -v deps='$(DSTDATA_ZI_DEPS) zishrink.awk' \
 		    -v redo='$(REDO)' \
@@ -645,6 +659,7 @@ leapseconds:	$(LEAP_DEPS)
 # Arguments to pass to submakes of install_data.
 # They can be overridden by later submake arguments.
 INSTALLARGS = \
+ BACKPICK='$(BACKPICK)' \
  BACKWARD='$(BACKWARD)' \
  DESTDIR='$(DESTDIR)' \
  LEAPSECONDS='$(LEAPSECONDS)' \
diff --git a/ziguard.awk b/ziguard.awk
index 6888c27..4901bcd 100644
--- a/ziguard.awk
+++ b/ziguard.awk
@@ -27,6 +27,32 @@ BEGIN {
   # The command line should set DATAFORM.
   if (!dataform_type[DATAFORM]) exit 1
   vanguard = DATAFORM == "vanguard"
+
+  if (BACKPICK) {
+    while (getline <BACKPICK) {
+      backpick_NR++
+      if ($0 ~ /^#/ || NF == 0) continue
+      if ($1 == "Backpick") {
+	if (NF != 2) {
+	  printf "%s:%d: malformed Backpick line: %s\n", \
+	    BACKPICK, backpick_NR, $0 >>"/dev/stderr"
+	  status = 1
+	}
+	backpick[$2] = 1
+      } else if ($1 == "Link") {
+	if (NF != 3) {
+	  printf "%s:%d: malformed Link line: %s\n", \
+	    BACKPICK, backpick_NR, $0 >>"/dev/stderr"
+	  status = 1
+	}
+	backlink[$3] = $2
+      } else {
+	printf "%s:%d: malformed line: %s\n",
+	  BACKPICK, backpick_NR, $0 >>"/dev/stderr"
+	status = 1
+      }
+    }
+  }
 }
 
 /^Zone/ { zone = $2 }
@@ -114,6 +140,13 @@ DATAFORM != "main" {
   }
 }
 
+# If reading 'backzone' and BACKPICK is specified,
+# discard lines that BACKPICK does not select.
+(FILENAME == PACKRATDATA && BACKPICK && !/^Rule/ \
+ && !backpick[$0 ~ /^Link/ ? $2 : zone]) {
+  next
+}
+
 # If a Link line is followed by a Link or Zone line for the same data, comment
 # out the Link line.  This can happen if backzone overrides a Link
 # with a Zone or a different Link.
@@ -128,6 +161,14 @@ DATAFORM != "main" {
 { line[NR] = $0 }
 
 END {
+  for (name in backlink)
+    sub(/^Link/, "#Link", line[linkline[name]])
+
   for (i = 1; i <= NR; i++)
     print line[i]
+
+  for (name in backlink)
+    printf "Link %s %s\n", backlink[name], name
+
+  exit status
 }
diff --git a/zishrink.awk b/zishrink.awk
index baf85cd..eeedc8a 100644
--- a/zishrink.awk
+++ b/zishrink.awk
@@ -302,6 +302,9 @@ BEGIN {
       ddeps = ddeps " !" d
     }
   }
+  if (backpick) {
+    version = version "-" backpick
+  }
   print "# version", version
   if (dataform != "main") {
     print "# dataform", dataform
-- 
2.30.2

