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