#!/usr/bin/perl -w # NAME: cmpphonebook.pl # AIM: QUITE specific - compare phone books used by fgcom use strict; use warnings; use File::Basename; # split path ($name,$dir,$ext) = fileparse($file [, qr/\.[^.]*/] ) use Cwd; my $os = $^O; my $perl_dir = '/home/geoff/bin'; my $PATH_SEP = '/'; my $temp_dir = '/tmp'; if ($os =~ /win/i) { $perl_dir = 'C:\GTools\perl'; $temp_dir = $perl_dir; $PATH_SEP = "\\"; } unshift(@INC, $perl_dir); require 'lib_utils.pl' or die "Unable to load 'lib_utils.pl' Check paths in \@INC...\n"; # log file stuff our ($LF); my $pgmname = $0; if ($pgmname =~ /(\\|\/)/) { my @tmpsp = split(/(\\|\/)/,$pgmname); $pgmname = $tmpsp[-1]; } my $outfile = $temp_dir.$PATH_SEP."temp.$pgmname.txt"; open_log($outfile); # user variables my $VERS = "0.0.1 2013-03-17"; my $load_log = 0; my $in_file1 = 'C:\FG\18\build-fgcom\server\phonebook.txt'; my $in_file2 = 'C:\FG\18\build-fgcom\server\or\phonebook.txt'; #my $in_file1 = 'C:\FG\18\fgcom\server\fgcom-data\phonebook.txt'; #my $in_file1 = 'C:\FG\18\fgcom\data\phonebook.txt'; #my $in_file2 = 'C:\FG\18\fgcom-bxns\data\phonebook.txt'; my $verbosity = 0; my $out_file = ''; my $ignore_case = 1; my $ignore_25kmz = 1; # ### DEBUG ### my $debug_on = 0; my $def_file = 'def_file'; ### program variables my @warnings = (); my $cwd = cwd(); my $max_icao_len = 4; my $max_type_len = 0; my $max_freq_len = 0; my $max_numb_len = 0; my $max_name_len = 0; sub VERB1() { return $verbosity >= 1; } sub VERB2() { return $verbosity >= 2; } sub VERB5() { return $verbosity >= 5; } sub VERB9() { return $verbosity >= 9; } sub show_warnings($) { my ($val) = @_; if (@warnings) { prt( "\nGot ".scalar @warnings." WARNINGS...\n" ); foreach my $itm (@warnings) { prt("$itm\n"); } prt("\n"); } else { prt( "\nNo warnings issued.\n\n" ) if (VERB9()); } } sub pgm_exit($$) { my ($val,$msg) = @_; if (length($msg)) { $msg .= "\n" if (!($msg =~ /\n$/)); prt($msg); } show_warnings($val); close_log($outfile,$load_log); exit($val); } sub prtw($) { my ($tx) = shift; $tx =~ s/\n$//; prt("$tx\n"); push(@warnings,$tx); } sub process_in_file($) { my ($inf) = @_; if (! open INF, "<$inf") { pgm_exit(1,"ERROR: Unable to open file [$inf]\n"); } my @lines = ; close INF; my $lncnt = scalar @lines; prt("Processing $lncnt lines, from [$inf]...\n"); my ($line,$inc,$lnn); $lnn = 0; foreach $line (@lines) { chomp $line; $lnn++; if ($line =~ /\s*#\s*include\s+(.+)$/) { $inc = $1; prt("$lnn: $inc\n"); } } } sub is_freq($) { my $txt = shift; return 0 if (!($txt =~ /^\d/)); return 0 if (!($txt =~ /\d$/)); return 0 if (!($txt =~ /\./)); return 1 if ($txt =~ /[\d\.]+/); return 0; } # expect fixed column files #File generated by gen_phonebook.pl - 2013-08-19 16:16:45 UTC #8995 airports and 3137 navaids are present in this file (6619 freq skipped) # #ICAO Description FRQ Phone no. Name #------------------------------------------------------------------------------- #0123456789 12345678 2 2345678 3 2345678 4 2345678 5 2345678 6 23456789 #0 5+ 27+ 37+ 54+ # 00C CTAF/UNICOM 122.800 0132484867122800 Animas Air Park #00CA CTAF 122.900 0148486765122900 GOLDSTONE GTS # 00F CTAF 122.900 0132484870122900 BROADUS AIRPORT #... #ZZZZ 723.340 0190909090723340 French Air Patrol sub load_phonebooks($$) { my ($fil1,$fil2) = @_; if (!open INF, "<$fil1") { pgm_exit(1,"ERROR: Can NOT open $fil1\n"); } my @lines1 = ; close INF; if (!open INF, "<$fil2") { pgm_exit(1,"ERROR: Can NOT open $fil2\n"); } my @lines2 = ; close INF; my $lncnt1 = scalar @lines1; my $lncnt2 = scalar @lines2; prt("Comparing $lncnt1 line in $fil1,\nwith $lncnt2 lines in $fil2\n"); my ($i,$line,$tline,$len,$lnn,$msg); my ($icao,$type,$freq,$numb,$name,@arr,$acnt,$j); my @pb1 = (); my @pb2 = (); for ($i = 0; $i < $lncnt1; $i++) { $line = $lines1[$i]; chomp $line; if ($line =~ /^--------------------------/) { $i++; last; } } if ($i >= $lncnt1) { prt("Divider line 1 '---------' not found!\n"); return; } for (; $i < $lncnt1; $i++) { $lnn = $i + 1; $line = $lines1[$i]; chomp $line; $line = trim_all($line); $len = length($line); next if ($len == 0); if ($len < 25) { prt("$lnn: Line too short [$line]\n"); next; } @arr = split(/\s+/,$line); $acnt = scalar @arr; $icao = $arr[0]; $type = ''; # can be BLANK for ($j = 1; $j < $acnt; $j++) { $freq = $arr[$j]; if (is_freq($freq)) { $j++; last; } $type .= ' ' if (length($type)); $type .= $freq; } if ($j < $acnt) { # special case where frequency is part of the 'type' string $numb = $arr[$j]; if (is_freq($numb)) { $type .= ' ' if (length($type)); $type .= $numb; $j++; } } if ($j < $acnt) { # special case where frequency is part of the 'type' string $numb = $arr[$j]; if ($numb =~ /^\d+$/) { $j++; $name = ''; for (; $j < $acnt; $j++) { $name .= ' ' if (length($name)); $name .= $arr[$j]; } } else { prt("$lnn: Failed to find number [$line]\n"); next; } } else { prt("$lnn: Failed to find frequency [$line]\n"); next; } push(@pb1, [$icao,$type,$freq,$numb,$name,0]); # get maximum length for displays $len = length($type); $max_type_len = $len if ($len > $max_type_len); $len = length($freq); $max_freq_len = $len if ($len > $max_freq_len); $len = length($numb); $max_numb_len = $len if ($len > $max_numb_len); $len = length($name); $max_name_len = $len if ($len > $max_name_len); } # stored file1 in @pb1 array # process line from file 2 for ($i = 0; $i < $lncnt2; $i++) { $line = $lines2[$i]; chomp $line; if ($line =~ /^--------------------------/) { $i++; last; } } if ($i >= $lncnt2) { prt("Divider line 2 '---------' not found!\n"); return; } for (; $i < $lncnt2; $i++) { $lnn = $i + 1; $line = $lines2[$i]; chomp $line; $line = trim_all($line); $len = length($line); next if ($len == 0); if ($len < 25) { prt("$lnn: Line too short [$line]\n"); next; } @arr = split(/\s+/,$line); $acnt = scalar @arr; $icao = $arr[0]; $type = ''; # can be BLANK for ($j = 1; $j < $acnt; $j++) { $freq = $arr[$j]; if (is_freq($freq)) { $j++; last; } $type .= ' ' if (length($type)); $type .= $freq; } if ($j < $acnt) { # special case where frequency is part of the 'type' string $numb = $arr[$j]; if (is_freq($numb)) { $type .= ' ' if (length($type)); $type .= $numb; $j++; } } if ($j < $acnt) { # special case where frequency is part of the 'type' string $numb = $arr[$j]; if ($numb =~ /^\d+$/) { $j++; $name = ''; for (; $j < $acnt; $j++) { $name .= ' ' if (length($name)); $name .= $arr[$j]; } } else { prt("$lnn: Failed to find number [$line]\n"); next; } } else { prt("$lnn: Failed to find frequency [$line]\n"); next; } push(@pb2, [$icao,$type,$freq,$numb,$name,0]); # get maximum length for displays $len = length($type); $max_type_len = $len if ($len > $max_type_len); $len = length($freq); $max_freq_len = $len if ($len > $max_freq_len); $len = length($numb); $max_numb_len = $len if ($len > $max_numb_len); $len = length($name); $max_name_len = $len if ($len > $max_name_len); } # stored file2 in @pb2 array $lncnt1 = scalar @pb1; $lncnt2 = scalar @pb2; prt("Got $lncnt1 entries file 1, an $lncnt2 entries file 2\n"); my %h = (); $h{file1} = \@pb1; $h{file2} = \@pb2; return \%h; } my %done_icao = (); # Per apt.dat # RKSG A 511 # 50 10820 ATIS # 53 11950 DESIDERIO GND # 54 12250 DESIDERIO TWR # 55 12790 OSAN APP/DEP # KOCH A L MANGHAM JR RGNL # 50 13562 AWOS 3 # 51 12300 CTAF/UNICOM # EKYT Aalborg # 50 12047 ATIS # 54 11830 TWR # 55 12397 APP # 55 12070 ARR # Some phonebook generations pre-convert the frequency with - # if ($line =~ /^5[0-6]\s+(\d{5})\d*\s+(.+)/) { # $freq = $1; # if ( substr($freq, -1) == 2 || substr($freq, -1) == 7 ) { # $com = sprintf("%3.2f5", $freq / 100); # } else { # $com = sprintf("%3.3f", $freq / 100); # } # but further than that some have the 25 kHz added and some not # KSGJ UNICOM 122.950 0175837174122950 St Augustine # KSGJ TWR 127.620 0175837174127620 St Augustine # KSGJ ATIS 119.620 0175837174119620 St Augustine # KSGJ GND 121.170 0175837174121170 St Augustine # KSGJ JACKSONVILLE APP/DEP 120.750 0175837174120750 St Augustine # versus # KSGJ ATIS 119.625 0175837174119625 St Augustine # KSGJ TWR 127.625 0175837174127625 St Augustine # KSGJ UNICOM 122.950 0175837174122950 St Augustine # KSGJ GND 121.175 0175837174121175 St Augustine # KSGJ JACKSONVILLE APP/DEP 120.750 0175837174120750 St Augustine # so int this compare '121.170' == '121.175' sub same_base_freq($$) { my ($f1,$f2) = @_; my $i1 = int( $f1 * 100 ); my $i2 = int( $f2 * 100 ); return 1 if ($i1 == $i2); return 0; } my %freq_types = ( 'GRD' => 'GROUND', 'GND' => 'GROUND', 'TWR' => 'TOWER', 'APP' => 'APPROCH', 'DEP' => 'DEPARTURE', 'ATIS' => 'ATIS', 'ZONE' => 'ZONE', 'INFO' => 'INFORMATION', 'DEL' => 'DELIVERY', 'VORTAC' => 'VOR-DME', 'VOR-DME' => 'VORTAC', 'RDR' => 'APPROACH' ); my %full_types = ( 'INFORMATION' => 'ATIS', 'TOWER' => 'TWR', 'RADAR' => 'APP', 'GROUND' => 'GND', 'DELIVERY' => 'GND', 'VORTAC' => 'VOR-DME', 'VOR-DME' => 'VORTAC', 'DIRECTOR' => 'APP', 'INFORMATION' => 'ATIS', 'APPROACH' => 'APP' ); sub same_base_type($$); sub same_base_type($$) { my ($t1,$t2) = @_; return 1 if ($t1 eq $t2); my @a1 = split(/\s+/,$t1); my @a2 = split(/\s+/,$t2); my $l1 = scalar @a1; my $l2 = scalar @a2; my %h = (); my $same = 0; my ($tmp,$tmp2); if ($l1 > $l2) { foreach $tmp (@a1) { $h{$tmp} = 1; if (defined $full_types{$tmp}) { $tmp = $full_types{$tmp}; $h{$tmp} = 1; # add short name to list } } foreach $tmp (@a2) { if (defined $h{$tmp}) { $same++; $same++ if (defined $freq_types{$tmp}); } elsif (defined $full_types{$tmp}) { $tmp2 = $full_types{$tmp}; $same++ if (defined $freq_types{$tmp2}); } } } else { foreach $tmp (@a2) { $h{$tmp} = 1; if (defined $full_types{$tmp}) { $tmp = $full_types{$tmp}; $h{$tmp} = 1; # add short name to list } } foreach $tmp (@a1) { if (defined $h{$tmp}) { $same++; $same++ if (defined $freq_types{$tmp}); } elsif (defined $full_types{$tmp}) { $tmp2 = $full_types{$tmp}; $same++ if (defined $freq_types{$tmp2}); } } } return 1 if ($same > 1); if ((($l1 + $l2) <= 4) && $same) { return $same; } my $chg = 0; if ($t1 =~ /\//) { $t1 =~ s/\// /; $chg++; } if ($t2 =~ /\//) { $t2 =~ s/\// /; $chg++; } if ($chg) { return same_base_type($t1,$t2); } return 0; # not same } sub same_base_name($$); # AGGL N [SANTA CRUZ/GRACIOSA BAY/LUOVA] vs [SANTA CRUZ] # AU14 N [LAIDER'S STRIP] vs [LAIDERS STRIP] # EDDF N [FRANKFURT AM MAIN] vs [FRANKFURT-MAIN] sub same_base_name($$) { my ($t1,$t2) = @_; return 1 if ($t1 eq $t2); my @a1 = split(/\s+/,$t1); my @a2 = split(/\s+/,$t2); my $l1 = scalar @a1; my $l2 = scalar @a2; my %h = (); my $same = 0; my ($tmp); if ($l1 > $l2) { foreach $tmp (@a1) { $h{$tmp} = 1; } foreach $tmp (@a2) { if (defined $h{$tmp}) { $same++; $same++ if (defined $freq_types{$tmp}); } } } else { foreach $tmp (@a2) { $h{$tmp} = 1; } foreach $tmp (@a1) { if (defined $h{$tmp}) { $same++; $same++ if (defined $freq_types{$tmp}); } } } return 1 if ($same > 1); my $mod = 0; if ($t1 =~ /\//) { $t1 =~ s/\// /g; $mod++; } if ($t2 =~ /\//) { $t2 =~ s/\// /g; $mod++; } if ($t1 =~ /\'/) { $t1 =~ s/\'//g; $mod++; } if ($t2 =~ /\'/) { $t2 =~ s/\'//g; $mod++; } if ($t1 =~ /-/) { $t1 =~ s/-/ /g; $mod++; } if ($t2 =~ /-/) { $t2 =~ s/-/ /g; $mod++; } if ($mod) { return same_base_name($t1,$t2); } if (($l1 + $l2) <= 4) { return $same; } return 0; # not same } # KPOB P [0175807966135025] vs [0175807966135020] sub same_base_num($$) { my ($n1,$n2) = @_; return 1 if ($n1 eq $n2); my $ln1 = substr($n1,0,length($n1)-1); my $ln2 = substr($n2,0,length($n2)-1); return 1 if ($ln1 == $ln2); return 0; } sub compare_phonebooks($$) { my ($rpb1,$rpb2) = @_; my $cnt1 = scalar @{$rpb1}; my $cnt2 = scalar @{$rpb2}; prt("Comparing $cnt1 with $cnt2 entries...\n"); my ($i,$icao,$type,$freq,$numb,$name,$ra,$len); my ($j,$icao2,$type2,$freq2,$numb2,$name2,$ra2,$mat2); my ($fnd,$tmp); my $added_ctaf = 0; my $missed_cnt = 0; my $same_cnt = 0; my $diff_cnt = 0; my $missed_cnt2; my @diff_items = (); my @notin2 = (); my @notin1 = (); prt("\n") if (VERB5()); prt("Processing file 1, seeking same ICAO in 2...\n"); for ($i = 0; $i < $cnt1; $i++) { $ra = ${$rpb1}[$i]; $len = scalar @{$ra}; if ($len < 6) { prt("BAD reference array!\n"); pgm_exit(1,""); } # 0 1 2 3 4 5 #push(@pb1, [$icao,$type,$freq,$numb,$name,0]); $icao = ${$ra}[0]; $type = ${$ra}[1]; $freq = ${$ra}[2]; $numb = ${$ra}[3]; $name = ${$ra}[4]; $fnd = 0; for ($j = 0; $j < $cnt2; $j++) { $ra2 = ${$rpb2}[$j]; $len = scalar @{$ra2}; if ($len < 6) { prt("BAD reference array!\n"); pgm_exit(1,""); } $mat2 = ${$ra2}[5]; next if ($mat2 > 0); $icao2 = ${$ra2}[0]; $freq2 = ${$ra2}[2]; # hmmm, this is NOT ENOUGH here - an ICAO can be repeated for multiple frequencies, like # KSFO AWOS 1 118.050 0175837079118050 San Francisco Intl # KSFO TWR 120.500 0175837079120500 San Francisco Intl # KSFO CLNC DEL 118.200 0175837079118200 San Francisco Intl # KSFO GND 128.650 0175837079128650 San Francisco Intl # KSFO UNICOM 122.950 0175837079122950 San Francisco Intl # KSFO NORCAL APP 133.950 0175837079133950 San Francisco Intl # KSFO NORCAL DEP 135.100 0175837079135100 San Francisco Intl # but further than that some have the 25 kHz added and some not # KSGJ UNICOM 122.950 0175837174122950 St Augustine # KSGJ TWR 127.620 0175837174127620 St Augustine # KSGJ ATIS 119.620 0175837174119620 St Augustine # KSGJ GND 121.170 0175837174121170 St Augustine # KSGJ JACKSONVILLE APP/DEP 120.750 0175837174120750 St Augustine # versus # KSGJ ATIS 119.625 0175837174119625 St Augustine # KSGJ TWR 127.625 0175837174127625 St Augustine # KSGJ UNICOM 122.950 0175837174122950 St Augustine # KSGJ GND 121.175 0175837174121175 St Augustine # KSGJ JACKSONVILLE APP/DEP 120.750 0175837174120750 St Augustine if ($icao eq $icao2) { if (same_base_freq($freq,$freq2)) { # here GND 121.170 == 121.175 $fnd = 1; $type2 = ${$ra2}[1]; $freq2 = ${$ra2}[2]; $numb2 = ${$ra2}[3]; $name2 = ${$ra2}[4]; ${$ra}[5] = $j + 1; ${$ra2}[5] = $i + 1; last; } } } if ($fnd) { if ($ignore_case) { $name = uc($name); $name2 = uc($name2); $type = uc($type); $type2 = uc($type2); } if ( same_base_type($type,$type2) && same_base_num($numb,$numb2) && same_base_freq($freq,$freq2) && same_base_name($name,$name2) ) { $same_cnt++; } else { $diff_cnt++; push(@diff_items,$i); } } else { if ($type eq 'CTAF') { $added_ctaf++; } else { push(@notin2,[$icao,$type,$freq,$numb,$name]); if (VERB5()) { $icao .= ' ' while (length($icao) < 4); $type .= ' ' while (length($type) < $max_type_len); $freq .= ' ' while (length($freq) < $max_freq_len); $name .= ' ' while (length($name) < $max_name_len); prt("$icao $type $freq $numb $name 1NFin2\n"); } $missed_cnt++; } } } $tmp = scalar @notin2; prt("Found $tmp not in file 2\n"); prt("\n") if (VERB5()); prt("Process file 2, showing ICAO not found in 1\n"); for ($j = 0; $j < $cnt2; $j++) { $ra2 = ${$rpb2}[$j]; $mat2 = ${$ra2}[5]; next if ($mat2 > 0); $icao = ${$ra2}[0]; $type = ${$ra2}[1]; $freq = ${$ra2}[2]; $numb = ${$ra2}[3]; $name = ${$ra2}[4]; push(@notin1,[$icao,$type,$freq,$numb,$name]); if (VERB5()) { $icao .= ' ' while (length($icao) < 4); $type .= ' ' while (length($type) < $max_type_len); $freq .= ' ' while (length($freq) < $max_freq_len); $name .= ' ' while (length($name) < $max_name_len); prt("$icao $type $freq $numb $name 2NFin1\n"); } $missed_cnt2++; } $tmp = scalar @notin1; prt("Found $tmp not in file 1\n"); prt("\nNow an enumeration of the $diff_cnt DIFFERENT entries...\n"); my %shown = (); my ($msg); foreach $i (@diff_items) { $ra = ${$rpb1}[$i]; # 0 1 2 3 4 5 #push(@pb1, [$icao,$type,$freq,$numb,$name,0]); $icao = ${$ra}[0]; $type = ${$ra}[1]; $freq = ${$ra}[2]; $numb = ${$ra}[3]; $name = ${$ra}[4]; $j = ${$ra}[5] - 1; if (($j < 0)||($j >= $cnt2)) { prt("Bad cross refrence to 2 [$j]!\n"); next; } $ra2 = ${$rpb2}[$j]; $icao2 = ${$ra2}[0]; $type2 = ${$ra2}[1]; $freq2 = ${$ra2}[2]; $numb2 = ${$ra2}[3]; $name2 = ${$ra2}[4]; $msg = "$icao "; if ($ignore_case) { $name = uc($name); $name2 = uc($name2); $type = uc($type); $type2 = uc($type2); } if (!same_base_type($type,$type2)) { $msg .= "T [$type] vs [$type2] "; } if (!same_base_freq($freq,$freq2)) { $msg .= "F [$freq] vs [$freq2] "; } if (!same_base_num($numb,$numb2)) { $msg .= "P [$numb] vs [$numb2] "; } if (!same_base_name($name,$name2)) { $msg .= "N [$name] vs [$name2] "; } if (!defined $shown{$msg}) { prt("$msg\n"); $shown{$msg} = 1; } } prt("Discounting the $added_ctaf only entries added\n"); prt("Compared $cnt1 with $cnt2. Same $same_cnt, diff $diff_cnt, missed1 $missed_cnt, missed2 $missed_cnt2\n"); $load_log = 1; } sub process_in_files() { my $rh = load_phonebooks($in_file1,$in_file2); if (!defined ${$rh}{file1} || !defined ${$rh}{file2}) { prt("Bad phonebook load!\n"); return; } compare_phonebooks(${$rh}{file1}, ${$rh}{file2}); } ######################################### ### MAIN ### parse_args(@ARGV); #process_in_file($in_file); process_in_files(); pgm_exit(0,""); ######################################## sub need_arg { my ($arg,@av) = @_; pgm_exit(1,"ERROR: [$arg] must have a following argument!\n") if (!@av); } sub parse_args { my (@av) = @_; my ($arg,$sarg); while (@av) { $arg = $av[0]; if ($arg =~ /^-/) { $sarg = substr($arg,1); $sarg = substr($sarg,1) while ($sarg =~ /^-/); if (($sarg =~ /^h/i)||($sarg eq '?')) { give_help(); pgm_exit(0,"Help exit(0)"); } elsif ($sarg =~ /^v/) { if ($sarg =~ /^v.*(\d+)$/) { $verbosity = $1; } else { while ($sarg =~ /^v/) { $verbosity++; $sarg = substr($sarg,1); } } prt("Verbosity = $verbosity\n") if (VERB1()); } elsif ($sarg =~ /^l/) { if ($sarg =~ /^ll/) { $load_log = 2; } else { $load_log = 1; } prt("Set to load log at end. ($load_log)\n") if (VERB1()); } elsif ($sarg =~ /^o/) { need_arg(@av); shift @av; $sarg = $av[0]; $out_file = $sarg; prt("Set out file to [$out_file].\n") if (VERB1()); } else { pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n"); } } else { pgm_exit(1,"ERROR: Invalid argument [$arg]! Try -?\n"); #$in_file = $arg; #prt("Set input to [$in_file]\n") if (VERB1()); } shift @av; } if ($debug_on) { prtw("WARNING: DEBUG is ON!\n"); #if ((length($in_file) == 0) && $debug_on) { # $in_file = $def_file; # prt("Set DEFAULT input to [$in_file]\n"); #} } #if (length($in_file) == 0) { # pgm_exit(1,"ERROR: No input files found in command!\n"); #} if (! -f $in_file1) { pgm_exit(1,"ERROR: Unable to find in file [$in_file1]! Check name, location...\n"); } if (! -f $in_file2) { pgm_exit(1,"ERROR: Unable to find in file [$in_file2]! Check name, location...\n"); } } sub give_help { prt("$pgmname: version $VERS\n"); prt("Usage: $pgmname [options] in-file\n"); prt("Options:\n"); prt(" --help (-h or -?) = This help, and exit 0.\n"); prt(" --verb[n] (-v) = Bump [or set] verbosity. def=$verbosity\n"); prt(" --load (-l) = Load LOG at end. ($outfile)\n"); prt(" --out (-o) = Write output to this file.\n"); } # eof - template.pl