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