checktab.awk revision 1.7 1 1.7 christos # $NetBSD: checktab.awk,v 1.7 2014/05/13 16:33:56 christos Exp $
2 1.2 perry
3 1.1 jtc # Check tz tables for consistency.
4 1.1 jtc
5 1.4 mlelstv # Contributed by Paul Eggert.
6 1.1 jtc
7 1.1 jtc BEGIN {
8 1.1 jtc FS = "\t"
9 1.1 jtc
10 1.1 jtc if (!iso_table) iso_table = "iso3166.tab"
11 1.1 jtc if (!zone_table) zone_table = "zone.tab"
12 1.1 jtc if (!want_warnings) want_warnings = -1
13 1.1 jtc
14 1.6 christos # A special (and we hope temporary) case.
15 1.6 christos tztab["America/Montreal"] = 1
16 1.6 christos
17 1.1 jtc while (getline <iso_table) {
18 1.1 jtc iso_NR++
19 1.1 jtc if ($0 ~ /^#/) continue
20 1.1 jtc if (NF != 2) {
21 1.3 kleink printf "%s:%d: wrong number of columns\n", \
22 1.1 jtc iso_table, iso_NR >>"/dev/stderr"
23 1.1 jtc status = 1
24 1.1 jtc }
25 1.1 jtc cc = $1
26 1.1 jtc name = $2
27 1.1 jtc if (cc !~ /^[A-Z][A-Z]$/) {
28 1.1 jtc printf "%s:%d: invalid country code `%s'\n", \
29 1.1 jtc iso_table, iso_NR, cc >>"/dev/stderr"
30 1.1 jtc status = 1
31 1.1 jtc }
32 1.1 jtc if (cc <= cc0) {
33 1.3 kleink if (cc == cc0) {
34 1.3 kleink s = "duplicate";
35 1.3 kleink } else {
36 1.3 kleink s = "out of order";
37 1.3 kleink }
38 1.3 kleink
39 1.1 jtc printf "%s:%d: country code `%s' is %s\n", \
40 1.3 kleink iso_table, iso_NR, cc, s \
41 1.1 jtc >>"/dev/stderr"
42 1.1 jtc status = 1
43 1.1 jtc }
44 1.1 jtc cc0 = cc
45 1.1 jtc if (name2cc[name]) {
46 1.1 jtc printf "%s:%d: `%s' and `%s' have the sname name\n", \
47 1.1 jtc iso_table, iso_NR, name2cc[name], cc \
48 1.1 jtc >>"/dev/stderr"
49 1.1 jtc status = 1
50 1.1 jtc }
51 1.1 jtc name2cc[name] = cc
52 1.1 jtc cc2name[cc] = name
53 1.1 jtc cc2NR[cc] = iso_NR
54 1.1 jtc }
55 1.1 jtc
56 1.1 jtc zone_table = "zone.tab"
57 1.1 jtc cc0 = ""
58 1.1 jtc
59 1.1 jtc while (getline <zone_table) {
60 1.1 jtc zone_NR++
61 1.1 jtc if ($0 ~ /^#/) continue
62 1.1 jtc if (NF != 3 && NF != 4) {
63 1.3 kleink printf "%s:%d: wrong number of columns\n", \
64 1.1 jtc zone_table, zone_NR >>"/dev/stderr"
65 1.1 jtc status = 1
66 1.1 jtc }
67 1.1 jtc cc = $1
68 1.1 jtc coordinates = $2
69 1.1 jtc tz = $3
70 1.1 jtc comments = $4
71 1.1 jtc if (cc < cc0) {
72 1.1 jtc printf "%s:%d: country code `%s' is out of order\n", \
73 1.1 jtc zone_table, zone_NR, cc >>"/dev/stderr"
74 1.1 jtc status = 1
75 1.1 jtc }
76 1.1 jtc cc0 = cc
77 1.6 christos cctz = cc tz
78 1.6 christos cctztab[cctz] = 1
79 1.6 christos tztab[tz] = 1
80 1.6 christos tz2comments[cctz] = comments
81 1.1 jtc tz2NR[tz] = zone_NR
82 1.1 jtc if (cc2name[cc]) {
83 1.1 jtc cc_used[cc]++
84 1.1 jtc } else {
85 1.1 jtc printf "%s:%d: %s: unknown country code\n", \
86 1.1 jtc zone_table, zone_NR, cc >>"/dev/stderr"
87 1.1 jtc status = 1
88 1.1 jtc }
89 1.1 jtc if (coordinates !~ /^[-+][0-9][0-9][0-5][0-9][-+][01][0-9][0-9][0-5][0-9]$/ \
90 1.1 jtc && 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]$/) {
91 1.1 jtc printf "%s:%d: %s: invalid coordinates\n", \
92 1.1 jtc zone_table, zone_NR, coordinates >>"/dev/stderr"
93 1.1 jtc status = 1
94 1.1 jtc }
95 1.1 jtc }
96 1.1 jtc
97 1.6 christos for (cctz in cctztab) {
98 1.6 christos cc = substr (cctz, 1, 2)
99 1.6 christos tz = substr (cctz, 3)
100 1.6 christos if (cc_used[cc] == 1) {
101 1.6 christos if (tz2comments[cctz]) {
102 1.1 jtc printf "%s:%d: unnecessary comment `%s'\n", \
103 1.6 christos zone_table, tz2NR[tz], \
104 1.6 christos tz2comments[cctz] \
105 1.1 jtc >>"/dev/stderr"
106 1.1 jtc status = 1
107 1.1 jtc }
108 1.1 jtc } else {
109 1.6 christos if (!tz2comments[cctz]) {
110 1.1 jtc printf "%s:%d: missing comment\n", \
111 1.1 jtc zone_table, tz2NR[tz] >>"/dev/stderr"
112 1.1 jtc status = 1
113 1.1 jtc }
114 1.1 jtc }
115 1.1 jtc }
116 1.1 jtc
117 1.1 jtc FS = " "
118 1.1 jtc }
119 1.1 jtc
120 1.7 christos $1 ~ /^#/ { next }
121 1.7 christos
122 1.1 jtc {
123 1.7 christos tz = rules = ""
124 1.7 christos if ($1 == "Zone") {
125 1.7 christos tz = $2
126 1.7 christos ruleUsed[$4] = 1
127 1.7 christos } else if ($1 == "Link") {
128 1.1 jtc # Ignore Link commands if source and destination basenames
129 1.1 jtc # are identical, e.g. Europe/Istanbul versus Asia/Istanbul.
130 1.1 jtc src = $2
131 1.1 jtc dst = $3
132 1.1 jtc while ((i = index(src, "/"))) src = substr(src, i+1)
133 1.1 jtc while ((i = index(dst, "/"))) dst = substr(dst, i+1)
134 1.1 jtc if (src != dst) tz = $3
135 1.7 christos } else if ($1 == "Rule") {
136 1.7 christos ruleDefined[$2] = 1
137 1.7 christos } else {
138 1.7 christos ruleUsed[$2] = 1
139 1.1 jtc }
140 1.1 jtc if (tz && tz ~ /\//) {
141 1.6 christos if (!tztab[tz]) {
142 1.1 jtc printf "%s: no data for `%s'\n", zone_table, tz \
143 1.1 jtc >>"/dev/stderr"
144 1.1 jtc status = 1
145 1.1 jtc }
146 1.1 jtc zoneSeen[tz] = 1
147 1.1 jtc }
148 1.1 jtc }
149 1.1 jtc
150 1.1 jtc END {
151 1.7 christos for (tz in ruleDefined) {
152 1.7 christos if (!ruleUsed[tz]) {
153 1.7 christos printf "%s: Rule never used\n", tz
154 1.7 christos status = 1
155 1.7 christos }
156 1.7 christos }
157 1.1 jtc for (tz in tz2cc) {
158 1.1 jtc if (!zoneSeen[tz]) {
159 1.1 jtc printf "%s:%d: no Zone table for `%s'\n", \
160 1.1 jtc zone_table, tz2NR[tz], tz >>"/dev/stderr"
161 1.1 jtc status = 1
162 1.1 jtc }
163 1.1 jtc }
164 1.1 jtc
165 1.1 jtc if (0 < want_warnings) {
166 1.1 jtc for (cc in cc2name) {
167 1.1 jtc if (!cc_used[cc]) {
168 1.3 kleink printf "%s:%d: warning: " \
169 1.3 kleink "no Zone entries for %s (%s)\n", \
170 1.1 jtc iso_table, cc2NR[cc], cc, cc2name[cc]
171 1.1 jtc }
172 1.1 jtc }
173 1.1 jtc }
174 1.1 jtc
175 1.1 jtc exit status
176 1.1 jtc }
177