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