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