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