File indexing completed on 2024-04-28 03:42:53

0001 #!/usr/bin/perl -w -i.bak - # -*- perl -*-
0002 
0003 use strict;
0004 my $ME = $0; $ME =~ s{.*/}{};    #-- program name minus leading path if any
0005 
0006 my $USAGE =<<USAGE;
0007 Usage: $ME [options] hip*.dat
0008 Options:
0009  -c --clean     Delete backup files.
0010  -e --edit      Actually change the specified files.
0011  -f --force     Apply changes despite warnings.
0012  -h --help      Show this usage message.
0013  -p --pretend   Just show changes that would be made.
0014  -r --reverse   Convert files in the new format back to the old.
0015  -u --undo      Undoes changes by moving backup files back to originals.
0016  -v --verbose   Show filenames in pretend mode.
0017 
0018 Converts the format of hipXXX.dat files so that the fixed length gname
0019 comes before the variable length name.
0020 
0021 old format: [name[: gname]] | [: gname]
0022 new format: [; gname[; name]]
0023 
0024 DANGER: This program edits files in place.  Always use --pretend first.
0025 USAGE
0026 
0027 @ARGV or die $USAGE;
0028 
0029 my ($REVERSE, $PRETEND, $VERBOSE, $UNDO, $CLEAN, $FORCE, $ABORT, $EDIT);
0030 my $BAK       = ".bak";
0031 my $SEP       = ',';
0032 my $GNAME_LEN = 7;
0033 
0034 while (@ARGV and $ARGV[0] =~ s/^-//) {
0035     my $arg = shift @ARGV;
0036     if    ($arg =~ /^(r|-reverse)$/) { $REVERSE = 1 }
0037     elsif ($arg =~ /^(p|-pretend)$/) { $PRETEND = 1 }
0038     elsif ($arg =~ /^(v|-verbose)$/) { $VERBOSE = 1 }
0039     elsif ($arg =~ /^(u|-undo)$/   ) { $UNDO    = 1 }
0040     elsif ($arg =~ /^(c|-clean)$/  ) { $CLEAN   = 1 }
0041     elsif ($arg =~ /^(f|-force)$/  ) { $FORCE   = 1 }
0042     elsif ($arg =~ /^(e|-edit)$/   ) { $EDIT    = 1 }
0043     elsif ($arg =~ /^(h|-help$)/   ) { die $USAGE   }
0044     elsif ($arg =~ /^$/            ) { last         }
0045     else { die qq(ERROR: Unrecognized argument: "-$arg":\n$USAGE); }
0046 }
0047 
0048 @ARGV or
0049   die "$ME Error: need to specify at least one hipXXX.dat file\n";
0050 
0051 $CLEAN and $UNDO and
0052   die "$ME Error: can't --clean and --undo at the same time.\n";
0053 
0054 $EDIT and $UNDO and
0055   die "$ME Error: can't --edit and --undo at the same time.\n";
0056 
0057 my @files = @ARGV;
0058 
0059 #--- Remove backup files
0060 if ($CLEAN and not $EDIT) {
0061     clean(@files);
0062 }
0063 #--- Copy backups back over 'originals'
0064 elsif ($UNDO) {
0065     for my $file (@files) {
0066         my $backup = $file . $BAK;
0067         -e $backup or do {
0068             warn "$ME Warning: backup file '$backup' for '$file' does not exist\n";
0069             next;
0070         };
0071         if ($PRETEND) {
0072             print "$ME would rename: $backup => $file\n";
0073             next;
0074         }
0075         rename( $backup, $file) or 
0076             warn "$ME Warning: unable to undo changes to '$file': $!\n";
0077     }
0078 }
0079 
0080 #--- Show all lines that would be changed
0081 elsif ($PRETEND) {
0082     for my $file (@files) {
0083         open(FILE, $file) or do {
0084             warn "$ME Warning: could not open($file) $!\n";
0085             next;
0086         };
0087         my $fname = $VERBOSE ? "$file:" : "";
0088         while (<FILE>) {
0089             my $new = swap_names($_, $REVERSE);
0090             $new eq $_ and next;
0091             print "$fname-$_";
0092             print "$fname+$new";
0093         }
0094         close FILE or die "$ME Warning: could not close($file) $!\n";
0095     }
0096 }
0097 
0098 #--- Edit all @ARGV files in-place via Perl -i flag in line 1.
0099 elsif ($EDIT)  {                    
0100     while (<>) {
0101         print swap_names($_, $REVERSE);
0102     }
0103 }
0104 
0105 else {
0106     die "$ME: Must specify a command: --edit --clean --undo --pretend\n";
0107 }
0108 
0109 $EDIT and $CLEAN and clean(@files);
0110 
0111 exit;
0112 
0113 #=== End of Main code ======================================================
0114 
0115 sub clean {
0116     for my $file (@_) {
0117         my $backup = $file . $BAK;
0118         -e $backup or do {
0119             warn "$ME Warning: backup file '$backup' for '$file' does not exist\n";
0120             next;
0121         };
0122         if ($PRETEND) {
0123             print "$ME would remove: $backup\n";
0124             next;
0125         }
0126         unlink($backup) or 
0127             warn "$ME Warning: unable to delete '$backup': $!\n";
0128     }
0129 }
0130 
0131 #---- swap_names($line, $reverse_flag) -------------------------------------
0132 # Change the format of name and gname at the end of the line if it matches
0133 # the format of the hipXXX.dat data files.  Return the line unchanged if
0134 # it starts with "#" or if it is too short.  Aborts if a data line does not
0135 # match the format of hipXXX.dat files.
0136 
0137 sub swap_names {
0138     my ($line, $reverse) = @_;
0139     return $line if $ABORT;
0140     $line =~ m/^#/ and return $line;
0141     my $d1 = substr($line, 0, 72, '');
0142     my $tail =  $/ x chomp($line);            # $tail contains chomped char(s)
0143     length($line) > 0 or return $d1 . $tail;
0144 
0145     #-- extreme check of format of a data line
0146     $FORCE or $d1 =~ m{^(\d{6}\.\d\d)\s  # RA  HHMMSS.SS
0147                     ([+-]\d{6}\.\d)\s    # DEC DDMMSS.SS
0148                     ([+-]\d{6}\.\d)      # dRA/dt
0149                     ([+-]\d{6}\.\d)      # dDec/dt
0150                     (\d{5}\.\d)\s        # Parallax
0151                     ([\d-]\d\.\d\d)      # Magnitude
0152                     ([\d-]\d\.\d\d)      # B-V index
0153                     ([A-Z].)\s           # Spectral Type
0154                     (\d)                 # Multiplicity
0155      }x or do {
0156         warn "$ME Warning: This does not look like a hipXXX.dat file\n";
0157         warn "$ME: Cowardly aborting.  Consider using --force or perhaps --undo.\n";
0158         $ABORT = 1;
0159         return  $d1 . $line . $tail;
0160     };
0161 
0162     my $gname;
0163     my $name;
0164 
0165     #--- Read names in new format
0166     if ($line =~ s/^$SEP\s*//) {
0167         $name  = $line =~ s/\s*$SEP\s*(.*)// ? $1 : "";
0168         $gname = $line || "";
0169     }
0170 
0171     #--- Read names in old format
0172     else {
0173         $gname = $line =~ s/\s?:\s?(.*)// ? $1 : "";
0174         $name  = $line || "";
0175     }
0176     
0177     my $names;
0178     
0179     #--- Write names in old format
0180     if ($reverse) {     
0181         $names = $name;
0182         $name  and $gname and $names .= " ";
0183         $gname and $names .= ": $gname";
0184     }
0185 
0186     #--- Write names in new format
0187     else {
0188         $names = "$SEP ";
0189         $names .= $gname ? $gname : " " x $GNAME_LEN;
0190         $name and $names .= "$SEP $name";
0191     }
0192     return $d1 . $names . $tail;
0193 }
0194 
0195 __END__