| 1 | #!/usr/local/bin/perl |
|---|
| 2 | # |
|---|
| 3 | # You make have to change the path to perl above, unless you call this |
|---|
| 4 | # script with 'make update' |
|---|
| 5 | # |
|---|
| 6 | # update-cnf.pl - integrate previous mush.cnf settings with new |
|---|
| 7 | # mush.cnf.dist. Results appear in mush.cnf |
|---|
| 8 | # |
|---|
| 9 | # Usage: update-cnf.pl old-file new-file |
|---|
| 10 | # e.g.: update-cnf.pl game/mush.cnf game/mush.cnf.dist |
|---|
| 11 | # |
|---|
| 12 | # 'make update' calls this program as in the example above. |
|---|
| 13 | # |
|---|
| 14 | # Here's how it works. |
|---|
| 15 | # First, we make a backup of your old-file to old-file.bak |
|---|
| 16 | # Then we read all the directives in the old-file, and their |
|---|
| 17 | # associated comments. Associated comments are those which |
|---|
| 18 | # appear on lines preceding the directive. |
|---|
| 19 | # We store the names of all the directives, |
|---|
| 20 | # their comments, and how they're defined. |
|---|
| 21 | # Then we do the same for the new-file. If we find a directive |
|---|
| 22 | # that wasn't in the old-file, we show the user the comment |
|---|
| 23 | # and ask them how they want it set. Every time we write out |
|---|
| 24 | # a directive, we delete it from the list of directives from old-file |
|---|
| 25 | # Finally, if there's anything left from old-file that's not in |
|---|
| 26 | # new-file, we ask if the user would like to retain each one. |
|---|
| 27 | # Presumably users want to retain their custom directives, but don't |
|---|
| 28 | # want to retain obsoleted directives. Retained directives appear at |
|---|
| 29 | # the end of the file. |
|---|
| 30 | |
|---|
| 31 | die "Usage: update-cnf.pl old-file new-file\n" unless $#ARGV == 1; |
|---|
| 32 | |
|---|
| 33 | $old = $ARGV[0]; |
|---|
| 34 | $bak = $old . ".bak"; |
|---|
| 35 | $new = $ARGV[1]; |
|---|
| 36 | |
|---|
| 37 | |
|---|
| 38 | # Part 1 - back up the old file (inefficient but reliable method) |
|---|
| 39 | if (-r $old) { |
|---|
| 40 | print "*** Backing up $old to $bak...\n"; |
|---|
| 41 | die "update-cnf.pl: Unable to open $old\n" unless open(OLD,"$old"); |
|---|
| 42 | die "update-cnf.pl: Unable to open $bak\n" unless open(BAK,">$bak"); |
|---|
| 43 | print BAK <OLD>; |
|---|
| 44 | close(BAK); |
|---|
| 45 | close(OLD); |
|---|
| 46 | } else { |
|---|
| 47 | # Heck, let's just copy the new file to the old one and quit! |
|---|
| 48 | print "*** Creating $old from $new...\n"; |
|---|
| 49 | die "update-cnf.pl: Unable to open $old\n" unless open(OLD,">$old"); |
|---|
| 50 | die "update-cnf.pl: Unable to open $new\n" unless open(NEW,"$new"); |
|---|
| 51 | print OLD <NEW>; |
|---|
| 52 | close(OLD); |
|---|
| 53 | close(NEW); |
|---|
| 54 | exit 0; |
|---|
| 55 | } |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | # Part 2 - read the settings from the old file and store them |
|---|
| 59 | if (-r $old) { |
|---|
| 60 | print "*** Reading your settings from $old...\n"; |
|---|
| 61 | die "update-cnf.pl: Unable to open $old\n" unless open(OLD,"$old"); |
|---|
| 62 | while (<OLD>) { |
|---|
| 63 | # We can have comments, which start with #, |
|---|
| 64 | # or directives, which start with anything else. |
|---|
| 65 | if (/^#/) { |
|---|
| 66 | # A comment |
|---|
| 67 | push(@comment,$_); |
|---|
| 68 | } elsif (/^(\S+)\s+(.+)$/) { |
|---|
| 69 | # A directive |
|---|
| 70 | $key = $1; $val = $2; |
|---|
| 71 | chop; |
|---|
| 72 | if (defined($directive{$key})) { |
|---|
| 73 | # This is a repeatable directive! |
|---|
| 74 | $num{$key}++; |
|---|
| 75 | $directive{"$key/$num{$key}"} = $val; |
|---|
| 76 | $comment{"$key/$num{$key}"} = join("",@comment); |
|---|
| 77 | } else { |
|---|
| 78 | $directive{$key} = $val; |
|---|
| 79 | $comment{$key} = join("",@comment); |
|---|
| 80 | } |
|---|
| 81 | undef @comment; |
|---|
| 82 | } elsif (/^(\S+)/) { |
|---|
| 83 | # A directive that's defined as blank |
|---|
| 84 | $key = $1; $val = ""; |
|---|
| 85 | $directive{$key} = $val; |
|---|
| 86 | $comment{$key} = join("",@comment); |
|---|
| 87 | undef @comment; |
|---|
| 88 | } elsif (/^$/) { |
|---|
| 89 | # A blank line. Ignore comments so far |
|---|
| 90 | undef @comment; |
|---|
| 91 | } |
|---|
| 92 | } |
|---|
| 93 | close(OLD); |
|---|
| 94 | } |
|---|
| 95 | |
|---|
| 96 | # Part 3 - read in the new file, modifying its definition lines to |
|---|
| 97 | # match the old file. If we come across a definition that |
|---|
| 98 | # isn't in the old file, ask the user about it. |
|---|
| 99 | print "*** Updating $old from $new...\n"; |
|---|
| 100 | die "update-cnf.pl: Unable to open $old\n" unless open(OLD,">$old"); |
|---|
| 101 | die "update-cnf.pl: Unable to open $new\n" unless open(NEW,"$new"); |
|---|
| 102 | while (<NEW>) { |
|---|
| 103 | # We can have comments, which start with #, |
|---|
| 104 | # or directives, which start with anything else. |
|---|
| 105 | if (/^#/) { |
|---|
| 106 | # A comment |
|---|
| 107 | push(@comment,$_); |
|---|
| 108 | } elsif (/^(\S+)/) { |
|---|
| 109 | # Not a comment |
|---|
| 110 | $key = $1; |
|---|
| 111 | chop; |
|---|
| 112 | if ($num{$key}) { |
|---|
| 113 | if ($num{$key} > 0) { |
|---|
| 114 | # A repeatable directive! |
|---|
| 115 | # Spew them all here. It's probably the best we can do. |
|---|
| 116 | print OLD @comment; |
|---|
| 117 | print OLD "$key\t$directive{$key}\n\n"; |
|---|
| 118 | delete $comment{$key}; |
|---|
| 119 | for ($i = 1; $i <= $num{$key}; $i++) { |
|---|
| 120 | print OLD $comment{"$key/$i"}; |
|---|
| 121 | print OLD "$key\t", $directive{"$key/$i"},"\n\n"; |
|---|
| 122 | delete $comment{"$key/$i"}; |
|---|
| 123 | delete $directive{"$key/$i"}; |
|---|
| 124 | } |
|---|
| 125 | $num{$key} = -1; # Don't spew again |
|---|
| 126 | } |
|---|
| 127 | } else { |
|---|
| 128 | print OLD @comment; |
|---|
| 129 | if (!defined($directive{$key}) || $key eq "include") { |
|---|
| 130 | # It's new, just add it |
|---|
| 131 | print OLD $_,"\n"; |
|---|
| 132 | push(@newoptions,$key); |
|---|
| 133 | delete $comment{$key} if $key eq "include"; |
|---|
| 134 | } else { |
|---|
| 135 | # It's old. Put it in, with a value if one's set. |
|---|
| 136 | print OLD $key; |
|---|
| 137 | print OLD "\t$directive{$key}" if (defined($directive{$key})); |
|---|
| 138 | print OLD "\n"; |
|---|
| 139 | # Remove its comment. |
|---|
| 140 | delete $comment{$key}; |
|---|
| 141 | } |
|---|
| 142 | } |
|---|
| 143 | undef @comment; |
|---|
| 144 | } elsif (/^$/) { |
|---|
| 145 | print OLD @comment; |
|---|
| 146 | undef @comment; |
|---|
| 147 | print OLD; |
|---|
| 148 | } else { |
|---|
| 149 | print OLD; |
|---|
| 150 | } |
|---|
| 151 | } |
|---|
| 152 | close(NEW); |
|---|
| 153 | |
|---|
| 154 | # Part 4 - if there are any definitions left from the old file, |
|---|
| 155 | # offer to delete them (or not) |
|---|
| 156 | print "\n*** Checking for leftover defines from $old...\n"; |
|---|
| 157 | foreach $d (sort { $directive{$a} cmp $directive{$b} } keys %comment) { |
|---|
| 158 | $newd = $d; |
|---|
| 159 | $newd =~ s!/.*!!; |
|---|
| 160 | print "\nI found:\n"; |
|---|
| 161 | print $comment{$d}; |
|---|
| 162 | print "$newd\t$directive{$d}\n"; |
|---|
| 163 | print "\n"; |
|---|
| 164 | print "If this is a directive that you hacked in, you probably should retain it.\n"; |
|---|
| 165 | print "If not, it's probably an obsolete directive from an earlier release,\n"; |
|---|
| 166 | print "and you need not retain it.\n"; |
|---|
| 167 | print "Do you want to retain this in your $old file? [y] "; |
|---|
| 168 | $yn = <STDIN>; |
|---|
| 169 | if ($yn !~ /^[Nn]/) { |
|---|
| 170 | print "Retaining directive. It will appear at the end of $old.\n"; |
|---|
| 171 | @retained = (@retained, $newd); |
|---|
| 172 | print OLD $comment{$d}; |
|---|
| 173 | print OLD "$newd\t$directive{$d}\n"; |
|---|
| 174 | print OLD "\n"; |
|---|
| 175 | } else { |
|---|
| 176 | print "Deleting definition.\n"; |
|---|
| 177 | @deleted = (@deleted, $d); |
|---|
| 178 | } |
|---|
| 179 | } |
|---|
| 180 | close(OLD); |
|---|
| 181 | |
|---|
| 182 | print "\nSummary of changes:\n"; |
|---|
| 183 | print "New options from $new: ",join(" ",@newoptions),"\n"; |
|---|
| 184 | print "Old options retained: ",join(" ",@retained),"\n"; |
|---|
| 185 | print "Old options deleted: ",join(" ",@deleted),"\n"; |
|---|
| 186 | print "If this is wrong, you can recover $old from $bak.\n"; |
|---|
| 187 | print "Done!\n"; |
|---|
| 188 | exit 0; |
|---|