PennMUSH Community

root/1.8.3/trunk/utils/mkcmds.pl

Revision 1117, 6.8 kB (checked in by shawnw, 1 year ago)

Merge with devel

Line 
1 #!/usr/bin/perl -w
2 # perl version of the old mkcmds.sh script. Runs faster by simply not running
3 # a bazillion child processes. Also uses SelfLoader to avoid compiling functions
4 # that are never used, since it's usually invoked with at most 1 argument.
5 #
6
7 use SelfLoader;
8 use File::Compare;
9 use File::Copy;
10 use strict; # Please ma'am may I have another?
11
12 # SelfLoaded functions
13 use subs qw/make_patches make_switches make_cmds make_funs/;
14 # Always present functions
15 use subs qw/maybemove temp_header temp_source scan_files_for_pattern/;
16
17 # Main loop, dispatch for each command line argument.
18 foreach my $command (@ARGV) {
19     if ($command eq "patches") {
20         make_patches;
21     } elsif ($command eq "switches") {
22         make_switches;
23     } elsif ($command eq "commands") {
24         make_cmds;
25     } elsif ($command eq "functions") {
26         make_funs;
27     } elsif ($command eq "all") {
28         make_patches;
29         make_switches;
30         make_cmds;
31         make_funs;
32     } else {
33         warn "Unknown option '${command}'\n";
34     }
35 }
36
37 # Return name of a temp file in hdrs/
38 sub temp_header {
39     return "hdrs/temp.$$.h";
40 }
41
42 # Return name of a temp file in src/
43 sub temp_source {
44     return "src/temp.$$.c";
45 }
46
47 # maybemove(file1, file2) copies file1 to file 2 if they are different,
48 # otherwise just deletes file1 and leaves file2 unchanged.
49 sub maybemove {
50     my $from = shift;
51     my $to = shift;
52
53     if (compare $from, $to) {
54         if (move $from, $to) {
55             print "File ${to} updated.\n";
56         } else {
57             warn "Couldn't rename ${from} to ${to}: $!\n";
58         }
59     } else {
60         print "File ${to} unchanged.\n";
61         unlink $from;
62     }
63 }
64
65 # scan_files_for_pattern(glob-pattern, re) searches all files matching
66 # glob-pattern for lines matching re, and returns a sorted list of
67 # $1's for each matching line.
68 sub scan_files_for_pattern {
69     my $filepattern = shift;
70     my $re = shift;
71     my @idents;
72
73     foreach my $file (glob $filepattern) {
74         open FILE, "<", $file
75             or die "Cannot open ${file} for reading: $!\n";
76         while (<FILE>) {
77             chomp;
78             push @idents, $1 if m/$re/;
79         }
80         close FILE;
81     }
82     return sort @idents;
83 }
84
85
86 END {
87     # Make sure temp files get deleted.
88     my @files = (temp_header(), temp_source());
89     foreach my $file (@files) {
90         unlink $file if -f $file;
91     }
92 }
93
94 __DATA__
95
96 sub make_patches {
97     print "Rebuilding list of installed patches\n";
98     my $tempfile = temp_header;
99     my $patchfile = "hdrs/patches.h";
100     my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
101     open PATCHES, ">", $tempfile
102         or die "Couldn't open $tempfile for writing: $!\n";
103     print PATCHES $auto_msg;
104     print PATCHES "#ifndef PATCHES_H\n";
105     print PATCHES "#define PATCHES_H\n";
106     my %patches;
107     if (-d "patches") {
108         foreach $file (<patches/*>) {
109             next if $file =~ /(?:\.bak|\.orig|\.rej|~)$/o;
110             open FILE, "<", $file
111                 or die "Couldn't open file '$file' for reading: $!\n";
112             my $name = undef;
113             my $version = undef;
114             LINE: while (<FILE>) {
115                 chomp;
116                 $name = $1 if m/^# Patch name: (.*)/o;
117                 $version = $1 if m/^# Patch version: (.*)/o;
118                 if (defined $name && defined $version) {
119                     $patches{$name} = $version;
120                     last LINE;
121                 }
122             }
123             close FILE;
124         }
125         if (scalar keys %patches > 0) {
126             print PATCHES '#define PATCHES "';
127             while (my ($name, $version) = each %patches) {
128                 print PATCHES "$name($version) ";               
129             }
130             print PATCHES '"', "\n";
131         } else {
132             print PATCHES "#undef PATCHES\n";
133         }
134     } else {
135         print PATCHES "#undef PATCHES\n";
136     }
137     print PATCHES "#endif /* PATCHES_H */\n";
138     close PATCHES;
139     
140     maybemove $tempfile, $patchfile;
141 }
142
143 sub make_switches {
144     print "Rebuilding command switch file and header.\n";
145     my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
146     
147     my $temphdr = temp_header;
148     my $tempsrc = temp_source;
149
150     open CMDHDR, "<", "hdrs/command.h" or
151         die "Unable to open hdrs/command.h for reading: $!\n";
152     my $numbytes = 20;
153     while (<CMDHDR>) {
154         if (m/^#define\s+NUM_BYTES\s+(\d+)/o) {
155             $numbytes = $1;
156             last;
157         }
158     }
159     close CMDHDR;
160
161     my $MAXSWITCHES = $numbytes * 8;
162     
163     my @switches = scan_files_for_pattern "src/SWITCHES", qr/^(.+)/;
164     
165     warn "Too many switches defined!\n" if length @switches > $MAXSWITCHES;
166
167     open HDR, ">", $temphdr or
168         die "Unable to open $temphdr for writing: $!\n";
169     open SRC, ">", $tempsrc or
170         die "Unable to open $tempsrc for writing: $1\n";
171
172     print HDR $auto_msg;
173     print HDR "#ifndef SWITCHES_H\n";
174     print HDR "#define SWITCHES_H\n";
175
176     print SRC $auto_msg;
177     print SRC "SWITCH_VALUE switch_list[] = {\n";
178     
179     my $n = 1;
180     foreach my $switch (@switches) {
181         print HDR "#define SWITCH_${switch} ${n}\n";
182         print SRC "  {\"${switch}\", SWITCH_${switch}},\n";
183         $n++;
184     }
185     
186     print SRC "  {NULL, 0}\n";
187     print SRC "};\n";
188     close SRC;
189
190     print HDR "#endif                          /* SWITCHES_H */\n";
191     close HDR;
192
193     maybemove $temphdr, "hdrs/switches.h";
194     maybemove $tempsrc, "src/switchinc.c";
195 }
196
197 # I really should combine this and make_funs into one function that does
198 # the work with specific files/regexps/defines passed as arguments
199
200 sub make_cmds {
201     my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
202
203     print "Rebuilding command prototype header.\n";
204     
205     my $tempfile = temp_header;
206     
207     my @commands =
208         scan_files_for_pattern "src/*.c", qr/^\s*COMMAND\(([^\)]+)\)/;
209
210     open HDR, ">", $tempfile
211         or die "Can't open ${tempfile} for writing: $!\n";
212     
213     print HDR $auto_msg;
214     print HDR "#ifndef CMDS_H\n";
215     print HDR "#define CMDS_H\n";
216
217     foreach my $command (@commands) {
218         print HDR "COMMAND_PROTO(${command});\n";
219     }
220
221     print HDR "#endif /* CMDS_H */\n";
222     close HDR;
223
224     maybemove $tempfile, "hdrs/cmds.h";
225
226 }
227
228 sub make_funs {
229     my $auto_msg = "/* AUTOGENERATED FILE. DO NOT EDIT! */\n";
230
231     print "Rebuilding function prototype header.\n";
232     
233     my $tempfile = temp_header;
234     
235     my @functions =
236         scan_files_for_pattern "src/*.c", qr/^\s*FUNCTION\(([^\)]+)\)/;
237
238     open HDR, ">", $tempfile
239         or die "Can't open ${tempfile} for writing: $!\n";
240     
241     print HDR $auto_msg;
242     print HDR "#ifndef FUNS_H\n";
243     print HDR "#define FUNS_H\n";
244
245     foreach my $function (@functions) {
246         print HDR "FUNCTION_PROTO(${function});\n";
247     }
248
249     print HDR "#endif /* FUNS_H */\n";
250     close HDR;
251
252     maybemove $tempfile, "hdrs/funs.h";
253 }
254
255
Note: See TracBrowser for help on using the browser.