root/releases/1.6/0p5/update.pl

Revision 36, 8.4 KB (checked in by pennmush, 3 years ago)

PennMUSH 1.50p13 Archival

  • Property svn:executable set to *
Line 
1#!/usr/local/bin/perl5
2#
3# You make have to change the path to perl above, unless you call this
4# script with 'make update'
5#
6# update.pl - integrate previous options.h settings with new options.h.dist
7#             results appear in options.h
8#
9# Usage: update.pl old-file new-file
10#  e.g.: update.pl dune.h dune.h.dist
11#
12# 'make update' calls this twice:
13#   update.pl options.h options.h.dist
14#   update.pl dune.h dune.h.dist
15#
16# Here's how it works.
17# First, we make a backup of your old-file to old-file.bak
18# Then we read all the #def's in the old-file, and their
19#  associated comments. Associated comments means comments
20#  on the same line, after the define, or comments on lines
21#  preceding the define. We store the names of all the defines,
22#  their comments, and whether they're defined or not.
23# Then we do the same for the new-file. If we find a define
24#  that wasn't in the old-file, we show the user the comment
25#  and ask them how they want it set. Every time we write out
26#  a define, we delete it from the list of defines from old-file
27# Finally, if there's anything left from old-file that's not in
28#  new-file, we ask if the user would like to retain each one.
29#  Presumably users want to retain their custom defines, but don't
30#  want to retain obsoleted defines. Retained defines appear at
31#  the end of the file.
32
33die "Usage: update.pl old-file new-file\n" unless $#ARGV == 1;
34
35$old = $ARGV[0];
36$bak = $old . ".bak";
37$new = $ARGV[1];
38
39
40# Part 1 - back up the old file (inefficient but reliable method)
41if (-r $old) {
42    print "*** Backing up $old to $bak...\n";
43    die "update.pl: Unable to open $old\n" unless open(OLD,"$old"); 
44    die "update.pl: Unable to open $bak\n" unless open(BAK,">$bak");
45    print BAK <OLD>;
46    close(BAK);
47    close(OLD);
48}
49
50# Part 2 - read the settings from the old file and store them
51if (-r $old) {
52   print "*** Reading your settings from $old...\n";
53    die "update.pl: Unable to open $old\n" unless open(OLD,"$old"); 
54    while (<OLD>) {
55        # There are a few possibilities for what we could have:
56        # an #ifdef, #ifndef, #else, #endif, #define, #undef,
57        # commented #define, comment text, etc. We only care
58        # about the settings of define/undefs
59        s#/\*\s*\*/##;
60        s#[ \t]+([\r\n]*)$#$1#;
61        if ( /^#define\s+([A-Z0-9_-]+).*\\$/ ) {
62        # A define with a continuation, we need the next line
63        chop($next = <OLD>);
64        $defs{$1} = $next;
65        $comment{$1} = $comment;
66        } elsif ( m!^#define\s+([A-Z0-9_-]+)\s+(.+)\s+(/\*.*\*/)!
67             ) {
68        # A define with a value and a comment
69        $name = $1;
70        $comment{$name} = $3;
71        $defs{$name} = $2;
72        undef $comment;
73        } elsif ( m!^#define\s+([A-Z0-9_-]+)\s+(.+)!
74             ) {
75        # A define with a value
76        $defs{$1} = $2;
77        $comment{$1} = $comment;
78        } elsif ( /^#undef\s+([A-Z0-9_-]+)/ 
79             ) {
80        # an undef
81        $defs{$1} = 'undef';
82        $comment{$1} = $comment;
83        } elsif ( /^(\/\*)*\s*#define\s+([A-Z0-9-][A-Z0-9_-]+)/
84             ) {
85        # a define or commented define
86        $defs{$2} = ($1 eq "/*") ? 'undef' : 'define';
87        $comment{$2} = $comment;
88        } else {
89        if (m#^\s*/\*#) {
90            # Start of a comment
91            $incomment = 1;
92            undef $comment;
93        }
94        if ($incomment) {
95            $comment = $comment . $_;
96            if (m#\*/\s+$#) {
97            # End of a comment
98            $incomment = 0;
99            }
100        }
101        }
102    }
103    close(OLD);
104}
105undef $comment; $incomment = 0;
106
107
108# Part 3 - read in the new file, modifying its definition lines to
109#          match the old file. If we come across a definition that
110#          isn't in the old file, ask the user about it.
111print "*** Updating $old from $new...\n";
112die "update.pl: Unable to open $old\n" unless open(OLD,">$old"); 
113die "update.pl: Unable to open $new\n" unless open(NEW,"$new"); 
114$_ = <NEW>;
115while ($next = <NEW>) {
116    # Just like before, but we need to keep track of
117    # comments in the file so that we can describe options
118    s#[ \t]+([\r\n]*)$#$1#;
119    if ( /^#define\s+([A-Z0-9_-]+).*\\$/
120    ) {
121    # A define with a continuation, we need the next line
122    print OLD "#define $1 \\\n";
123    &ask_value($1,$next) if (!defined($defs{$1}));
124    print OLD $defs{$1};
125    delete $defs{$1};
126    $next = <NEW>;
127    } elsif ( /^#define\s+([A-Z0-9-][A-Z0-9_-]+)\s+\/\*\s*\*\//) {
128    # a define followed by /* */
129    print OLD defined($defs{$1}) ? &def($1) 
130                                 : &def(&ask_simple($1,'define'));
131    } elsif ( m!^#define\s+([A-Z0-9_-]+)\s+(.+)\s+(/\*.*\*/)!) {
132    # A define with a value and a comment
133    $comment = $3; $name = $1;
134    $def = $2;
135    print OLD defined($defs{$name}) 
136        ? &def($name,$comment) : &def(&ask_value($name,$def),$comment);
137    } elsif ( m!^#define\s+([A-Z0-9_-]+)\s+(.+)!) {
138    # A define with a value
139    print OLD defined($defs{$1}) ? &def($1) : &def(&ask_value($1,$2));
140    } elsif ( /^#undef\s+([A-Z0-9_-]+)/ 
141         ) {
142    print OLD defined($defs{$1}) ? &def($1) 
143                                 : &def(&ask_simple($1,'undef'));
144    } elsif ( /^(\/\*)*\s*#define\s+([A-Z0-9-][A-Z0-9_-]+)/
145         ) {
146    # a define or commented define
147    print OLD defined($defs{$2}) ?
148        &def($2)
149        : &def(&ask_simple($2,($1 eq "/*" ? 'undef': 'define')));
150    } else {
151    if (m#^\s*/\*#) {
152        # Start of a comment
153        $incomment = 1;
154        undef $comment;
155    }
156    if ($incomment) {
157        $comment = $comment . $_;
158        if (m#\*/\s+$#) {
159        # End of a comment
160        $incomment = 0;
161        }
162    }
163    print OLD;
164    }
165    $_ = $next;
166}
167# At the end of that loop, $_ contains the last line of the
168# file, which should be the #endif.
169$final = $_;
170close(NEW);
171
172# Part 4 - if there are any definitions left from the old file,
173#          offer to delete them (or not)
174print "\n*** Checking for leftover defines from $old...\n";
175foreach $d (keys %defs) {
176    print "\nI found: $d\n";
177    if ($defs{$d} eq 'undef') {
178    print "Currently undefined\n";
179    } elsif ($defs{$d} eq 'define') {
180    print "Currently defined\n";
181    } else {
182    print "Definition: $defs{$d}\n";
183    }
184    print $comment{$d};
185    print "\n";
186    print "If this is a define that you hacked in, you probably should retain it.\n";
187    print "If not, it's probably an obsolete define from an earlier patchlevel,\n";
188    print "and you need not retain it.\n";
189    print "Do you want to retain this in your $old file? [y] ";
190    $yn = <STDIN>;
191    if ($yn !~ /^[Nn]/) {
192    print "Retaining definition. It will appear at the end of $old.\n";
193        @retained = (@retained, $d);
194    print OLD $comment{$d};
195    print OLD &def($d);
196    print OLD "\n";
197    } else {
198    print "Deleting definition.\n";
199    @deleted = (@deleted, $d);
200    }
201}
202
203print OLD $final;
204
205close(OLD);
206
207print "\nSummary of changes:\n";
208print "New options from $new: ",join(" ",@newoptions),"\n";
209print "Old options retained: ",join(" ",@retained),"\n";
210print "Old options deleted: ",join(" ",@deleted),"\n";
211print "If this is wrong, you can recover $old from $bak.\n";
212print "Done!\n";
213exit 0;
214
215
216#
217# &def - Given a define name, return the appopriate C code
218# to define/undefine it. And delete it.
219# May also be given a comment as a second arg.
220#
221sub def {
222    # We should use my instead of local, but some folks have perl 4
223    local($d) = $_[0];
224    local($c) = $_[1];
225    local($df) = $defs{$d};
226    delete $defs{$d};
227    $d =~ s/^\s+//;
228    $d =~ s/\s+$//;
229    $c =~ s/^\s+//;
230    $c =~ s/\s+$//;
231    $df =~ s/^\s+//;
232    $df =~ s/\s+$//;
233    return "/* #define $d /* */\n" if ($df eq 'undef');
234    return "#define $d /* */\n" if ($df eq 'define');
235    return "#define $d\t$df\t$c\n" if ($c);
236    return "#define $d\t$df\n";
237}
238
239#
240# &ask_simple - Given a define name and default setting,
241# show the comment in $comment,
242# and ask the user if they want to define it or not
243# Set $defs{$d} and return the name given
244#
245sub ask_simple {
246    local($d,$s) = @_;
247    local($yn);
248    print "\nNew option: $d\n";
249    print $comment;
250    $s = ($s eq 'define') ? 'y' : 'n';
251    while (1) {
252    print "Define this option? [$s] ";
253    $yn = <STDIN>;
254    $yn = $s if $yn =~ /^$/;
255    last if $yn =~ /^[YyNn]/;
256    }
257    $defs{$d} = ($yn =~ /^[Yy]/) ? 'define' : 'undef';
258    @newoptions = (@newoptions,$d);
259    return $d;
260}
261   
262
263#
264# &ask_value - Just like ask_simple, but instead of a yes/no,
265# we're going to get a value
266#
267sub ask_value {
268    local($d,$s) = @_;
269    local($val);
270    print "\nNew option: $d\n";
271    print $comment;
272    print "Default value: $s\n";
273    print "Value for this option? [$s] ";
274    $val = <STDIN>;
275    $val = $s if $val =~ /^$/;
276    $defs{$d} = $val;
277    @newoptions = (@newoptions,$d);
278    return $d;
279}
Note: See TracBrowser for help on using the browser.