add CTY-2615 prefixes
[spider.git] / perl / create_prefix.pl
1 #!/usr/bin/perl
2 # a program to create a prefix file from a wpxloc.raw file
3 #
4 # Copyright (c) - Dirk Koopman G1TLH
5 #
6 #
7 #
8
9 require 5.004;
10
11 # search local then perl directories
12 BEGIN {
13         # root of directory tree for this system
14         $root = "/spider"; 
15         $root = $ENV{'DXSPIDER_ROOT'} if $ENV{'DXSPIDER_ROOT'};
16         
17         unshift @INC, "$root/perl";     # this IS the right way round!
18         unshift @INC, "$root/local";
19         $data = "$root/data";
20 }
21
22 use DXVars;
23 use Data::Dumper;
24 use strict;
25
26 my %loc = ();                                           # the location unique hash
27 my $nextloc = 1;                                        # the next location number
28 my %locn = ();                                          # the inverse of the above
29 my %pre = ();                                           # the prefix hash
30 my %pren = ();                                          # the inverse
31
32 # open the input file
33 my $ifn = $ARGV[0] if $ARGV[0];
34 $ifn = "$main::data/wpxloc.raw" if !$ifn;
35 open (IN, $ifn) or die "can't open $ifn ($!)";
36
37 # first pass, find all the 'master' location records
38 while (<IN>) {
39         next if /^\!/;                          # ignore comment lines
40         chomp;
41         my @f  = split;                         # get each 'word'
42         next if @f == 0;                        # ignore blank lines
43
44         if (($f[14] && $f[14] eq '@') || ($f[15] && $f[15] eq '@')) {
45                 my $locstr = join ' ', @f[1..13];
46                 my $loc = $loc{$locstr};
47                 $loc = addloc($locstr) if !$loc;
48         }
49 }
50
51 #foreach $loc (sort {$a <=> $b;} keys %locn) {
52 #  print "loc: $loc data: $locn{$loc}\n";
53 #}
54
55 # go back to the beginning and this time add prefixes (adding new location entries, if required)
56 seek(IN, 0, 0);
57
58 my $line;
59 while (<IN>) {
60         $line++;
61         chomp;
62         next if /^\s*\!/;                               # ignore comment lines
63         next if /^\s*$/;
64         
65         my @f  = split;                         # get each 'word'
66         next if @f == 0;                        # ignore blank lines
67   
68         # location record
69         my $locstr = join ' ', @f[1..13];
70         my $loc = $loc{$locstr};
71         $loc = addloc($locstr) if !$loc;
72   
73         my @prefixes = split /,/, $f[0];
74         foreach my $p (@prefixes) {
75                 my $ref;
76         
77                 if ($p =~ /#/) {
78                         my $i;
79                         for ($i = 0; $i < 9; ++$i) {
80                                 my $t = $p;
81                                 $t =~ s/#/$i/;
82                                 addpre($t, $loc);
83                         }
84                 } else {
85                         addpre($p, $loc);
86                 }       
87         }
88 }
89
90 close(IN);
91
92 #print Data::Dumper->Dump([\%pre, \%locn], [qw(pre locn)]);
93
94 # now open the cty.dat file if it is there
95 my @f;
96 my @a;
97 $line = 0;
98 if (open(IN, "$main::data/cty.dat")) {
99         my $state = 0;
100         while (<IN>) {
101                 $line++;
102                 s/\r$//;
103                 next if /^\s*\#/;
104                 next if /^\s*$/;
105                 chomp;
106                 if ($state == 0) {
107                         s/:$//;
108                         @f = split /:\s+/;
109                         @a = ();
110                         $state = 1;
111                 } elsif ($state == 1) {
112                         s/^\s+//;
113                         if (/;$/) {
114                                 $state = 0;
115                                 s/[,;]$//;
116                                 push @a, split /\s*,/;
117                                 $f[7] =~ s/^\*\s*//;   # remove any preceeding '*' before a callsign
118                                 ct($_, uc $f[7], @a) if @a;
119                         } else {
120                                 s/,$//;
121                                 push @a, split /\s*,/;
122                         }
123                 }
124         }
125 }
126 close IN;
127
128
129 open(OUT, ">$main::data/prefix_data.pl") or die "Can't open $main::data/prefix_data.pl ($!)";
130
131 print OUT "\%pre = (\n";
132 foreach my $k (sort keys %pre) {
133         my $ans = printpre($k);
134         print OUT "  '$k' => '$ans',\n";
135 }
136 print OUT ");\n\n";
137
138 print OUT "\n\%prefix_loc = (\n";
139 foreach my $l (sort {$a <=> $b} keys %locn) {
140         print OUT "   $l => bless( {";
141         my ($name, $dxcc, $itu, $cq, $utcoff, $latd, $latm, $lats, $latl, $longd, $longm, $longs, $longl) = split /\s+/, $locn{$l};
142   
143         $longd += ($longm/60);
144         $longd = 0-$longd if (uc $longl) eq 'W'; 
145         $latd += ($latm/60);
146         $latd = 0-$latd if (uc $latl) eq 'S';
147         print OUT " name => '$name',";
148         print OUT " dxcc => $dxcc,";
149         print OUT " itu => $itu,";
150         print OUT " cq => $cq,";
151         print OUT " utcoff => $utcoff,";
152         print OUT " lat => $latd,";
153         print OUT " long => $longd";
154         print OUT " }, 'Prefix'),\n";
155 }
156 print OUT ");\n\n";
157
158 close(OUT);
159
160 sub addpre
161 {
162         my ($p, $ent) = @_;
163         my $ref = $pre{$p};
164         $ref = $pre{$p} = [] if !$ref;
165         push @{$ref}, $ent;;
166 }
167
168 sub printpre
169 {
170         my $p = shift;
171         my $ref = $pre{$p};
172         my $out;
173         my $r;
174   
175         foreach $r (@{$ref}) {
176                 $out .= "$r,";
177         }
178         chop $out;
179         return $out;
180 }
181
182 sub ct
183 {
184         my $l = shift;
185         my $p = shift; 
186         my @a = @_;
187         my $ref = $pre{$p};
188         if ($ref) {
189                 my $a;
190                 foreach $a (@a) {
191                         # for now remove (nn) [nn]
192                         my ($itu) = $a =~ /(\(\d+\))/; $a =~ s/(\(\d+\))//g;
193                         my ($cq) = $a =~ /(\[\d+\])/; $a =~ s/(\[\d+\])//g;
194                         my ($lat, $long) = $a =~ m{(<[-+\d.]+/[-+\d.]+>)}; $a =~ s{(<[-+\d.]+/[-+\d.]+>)}{}g;
195                         my ($cont) = $a =~ /(\{[A-Z]{2}\})/; $a =~ s/(\{[A-Z]{2}\})//g;
196
197                         unless ($a) {
198                                 print "line $line: blank prefix on $l in cty.dat\n";
199                                 next;
200                         }
201                         next if $a eq $p;       # ignore if we have it already
202                         my $nref = $pre{$a};
203                         $pre{$a} = $ref if !$nref; # copy the original ref if new 
204                 }
205         } else {
206                 print "line $line: unknown prefix '$p' on $l in cty.dat\n";
207         }
208 }
209
210 sub addloc
211 {
212         my $locstr = shift;
213         $locstr =~ s/\'/\\'/g;
214         my $loc = $loc{$locstr} = $nextloc++;
215         $locn{$loc} = $locstr;
216         return $loc;
217 }
218