1309568Sglebius# Check tz tables for consistency.
2309568Sglebius
3309568Sglebius# Contributed by Paul Eggert.  This file is in the public domain.
4309568Sglebius
5309568SglebiusBEGIN {
6309568Sglebius	FS = "\t"
7309568Sglebius
8309568Sglebius	if (!iso_table) iso_table = "iso3166.tab"
9309568Sglebius	if (!zone_table) zone_table = "zone1970.tab"
10309568Sglebius	if (!want_warnings) want_warnings = -1
11309568Sglebius
12309568Sglebius	while (getline <iso_table) {
13309568Sglebius		iso_NR++
14309568Sglebius		if ($0 ~ /^#/) continue
15309568Sglebius		if (NF != 2) {
16309568Sglebius			printf "%s:%d: wrong number of columns\n", \
17309568Sglebius				iso_table, iso_NR >>"/dev/stderr"
18309568Sglebius			status = 1
19309568Sglebius		}
20309568Sglebius		cc = $1
21309568Sglebius		name = $2
22309568Sglebius		if (cc !~ /^[A-Z][A-Z]$/) {
23309568Sglebius			printf "%s:%d: invalid country code '%s'\n", \
24309568Sglebius				iso_table, iso_NR, cc >>"/dev/stderr"
25309568Sglebius			status = 1
26309568Sglebius		}
27309568Sglebius		if (cc <= cc0) {
28309568Sglebius			if (cc == cc0) {
29309568Sglebius				s = "duplicate";
30309568Sglebius			} else {
31309568Sglebius				s = "out of order";
32309568Sglebius			}
33309568Sglebius
34309568Sglebius			printf "%s:%d: country code '%s' is %s\n", \
35309568Sglebius				iso_table, iso_NR, cc, s \
36309568Sglebius				>>"/dev/stderr"
37309568Sglebius			status = 1
38309568Sglebius		}
39309568Sglebius		cc0 = cc
40309568Sglebius		if (name2cc[name]) {
41309568Sglebius			printf "%s:%d: '%s' and '%s' have the same name\n", \
42309568Sglebius				iso_table, iso_NR, name2cc[name], cc \
43309568Sglebius				>>"/dev/stderr"
44309568Sglebius			status = 1
45309568Sglebius		}
46309568Sglebius		name2cc[name] = cc
47309568Sglebius		cc2name[cc] = name
48309568Sglebius		cc2NR[cc] = iso_NR
49309568Sglebius	}
50309568Sglebius
51309568Sglebius	cc0 = ""
52309568Sglebius
53309568Sglebius	while (getline <zone_table) {
54309568Sglebius		zone_NR++
55309568Sglebius		if ($0 ~ /^#/) continue
56309568Sglebius		if (NF != 3 && NF != 4) {
57309568Sglebius			printf "%s:%d: wrong number of columns\n", \
58309568Sglebius				zone_table, zone_NR >>"/dev/stderr"
59309568Sglebius			status = 1
60309568Sglebius		}
61309568Sglebius		split($1, cca, /,/)
62309568Sglebius		cc = cca[1]
63309568Sglebius		coordinates = $2
64309568Sglebius		tz = $3
65309568Sglebius		comments = $4
66309568Sglebius		if (cc < cc0) {
67309568Sglebius			printf "%s:%d: country code '%s' is out of order\n", \
68309568Sglebius				zone_table, zone_NR, cc >>"/dev/stderr"
69309568Sglebius			status = 1
70309568Sglebius		}
71309568Sglebius		cc0 = cc
72309568Sglebius		tztab[tz] = 1
73309568Sglebius		tz2comments[tz] = comments
74309568Sglebius		tz2NR[tz] = zone_NR
75309568Sglebius		for (i in cca) {
76309568Sglebius		    cc = cca[i]
77309568Sglebius		    cctz = cc tz
78309568Sglebius		    cctztab[cctz] = 1
79309568Sglebius		    if (cc2name[cc]) {
80309568Sglebius			cc_used[cc]++
81309568Sglebius		    } else {
82309568Sglebius			printf "%s:%d: %s: unknown country code\n", \
83309568Sglebius				zone_table, zone_NR, cc >>"/dev/stderr"
84309568Sglebius			status = 1
85309568Sglebius		    }
86309568Sglebius		}
87309568Sglebius		if (coordinates !~ /^[-+][0-9][0-9][0-5][0-9][-+][01][0-9][0-9][0-5][0-9]$/ \
88309568Sglebius		    && coordinates !~ /^[-+][0-9][0-9][0-5][0-9][0-5][0-9][-+][01][0-9][0-9][0-5][0-9][0-5][0-9]$/) {
89309568Sglebius			printf "%s:%d: %s: invalid coordinates\n", \
90309568Sglebius				zone_table, zone_NR, coordinates >>"/dev/stderr"
91309568Sglebius			status = 1
92309568Sglebius		}
93309568Sglebius	}
94309568Sglebius
95309568Sglebius	for (cctz in cctztab) {
96309568Sglebius		cc = substr (cctz, 1, 2)
97309568Sglebius		tz = substr (cctz, 3)
98309568Sglebius		if (1 < cc_used[cc]) {
99309568Sglebius			comments_needed[tz] = cc
100309568Sglebius		}
101309568Sglebius	}
102309568Sglebius	for (cctz in cctztab) {
103309568Sglebius	  cc = substr (cctz, 1, 2)
104309568Sglebius	  tz = substr (cctz, 3)
105309568Sglebius	  if (!comments_needed[tz] && tz2comments[tz]) {
106309568Sglebius	    printf "%s:%d: unnecessary comment '%s'\n", \
107309568Sglebius		zone_table, tz2NR[tz], tz2comments[tz] \
108309568Sglebius		>>"/dev/stderr"
109309568Sglebius	    tz2comments[tz] = 0
110309568Sglebius	    status = 1
111309568Sglebius	  } else if (comments_needed[tz] && !tz2comments[tz]) {
112309568Sglebius	    printf "%s:%d: missing comment for %s\n", \
113309568Sglebius	      zone_table, tz2NR[tz], comments_needed[tz] \
114309568Sglebius	      >>"/dev/stderr"
115309568Sglebius	    tz2comments[tz] = 1
116309568Sglebius	    status = 1
117309568Sglebius	  }
118309568Sglebius	}
119309568Sglebius	FS = " "
120309568Sglebius}
121309568Sglebius
122309568Sglebius$1 ~ /^#/ { next }
123309568Sglebius
124309568Sglebius{
125309568Sglebius	tz = rules = ""
126309568Sglebius	if ($1 == "Zone") {
127309568Sglebius		tz = $2
128309568Sglebius		ruleUsed[$4] = 1
129309568Sglebius	} else if ($1 == "Link" && zone_table == "zone.tab") {
130309568Sglebius		# Ignore Link commands if source and destination basenames
131309568Sglebius		# are identical, e.g. Europe/Istanbul versus Asia/Istanbul.
132309568Sglebius		src = $2
133309568Sglebius		dst = $3
134309568Sglebius		while ((i = index(src, "/"))) src = substr(src, i+1)
135309568Sglebius		while ((i = index(dst, "/"))) dst = substr(dst, i+1)
136309568Sglebius		if (src != dst) tz = $3
137309568Sglebius	} else if ($1 == "Rule") {
138309568Sglebius		ruleDefined[$2] = 1
139309568Sglebius	} else {
140309568Sglebius		ruleUsed[$2] = 1
141309568Sglebius	}
142309568Sglebius	if (tz && tz ~ /\//) {
143309568Sglebius		if (!tztab[tz]) {
144309568Sglebius			printf "%s: no data for '%s'\n", zone_table, tz \
145309568Sglebius				>>"/dev/stderr"
146309568Sglebius			status = 1
147309568Sglebius		}
148309568Sglebius		zoneSeen[tz] = 1
149309568Sglebius	}
150309568Sglebius}
151309568Sglebius
152309568SglebiusEND {
153309568Sglebius	for (tz in ruleDefined) {
154309568Sglebius		if (!ruleUsed[tz]) {
155309568Sglebius			printf "%s: Rule never used\n", tz
156309568Sglebius			status = 1
157309568Sglebius		}
158309568Sglebius	}
159309568Sglebius	for (tz in tztab) {
160309568Sglebius		if (!zoneSeen[tz]) {
161309568Sglebius			printf "%s:%d: no Zone table for '%s'\n", \
162309568Sglebius				zone_table, tz2NR[tz], tz >>"/dev/stderr"
163309568Sglebius			status = 1
164309568Sglebius		}
165309568Sglebius	}
166309568Sglebius	if (0 < want_warnings) {
167309568Sglebius		for (cc in cc2name) {
168309568Sglebius			if (!cc_used[cc]) {
169309568Sglebius				printf "%s:%d: warning: " \
170309568Sglebius					"no Zone entries for %s (%s)\n", \
171309568Sglebius					iso_table, cc2NR[cc], cc, cc2name[cc]
172309568Sglebius			}
173309568Sglebius		}
174309568Sglebius	}
175309568Sglebius
176309568Sglebius	exit status
177309568Sglebius}
178