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