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