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