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