3 use File
::Spec
::Functions qw
( :ALL
);
9 my $config_h = shift || "config.h";
11 # Read in a whole file
16 open my $fh, "<$file" or die "Could not open file $file: $!\n";
23 # Write out a whole file
29 open my $fh, ">$file" or die "Could not write $file: $!\n";
39 unlink $file or die "Could not delete $file: $!\n";
42 # Get a file modification time
47 my $stat = stat ( $file ) or die "Could not stat $file: $!\n";
51 # Read all the .h files in a directory
56 opendir my $dh, $dir or die "Could not open directory $dir: $!\n";
57 my @entries = grep { /\.h$/ } readdir $dh;
62 # Get the current configuration by reading the configuration file
69 foreach my $file ( read_dir
( $dir ) ) {
70 $cfg->{$file} = read_file
( catfile
( $dir, $file ) );
75 # Calculate guard name for a header file
81 return "CONFIG_".( uc $name );
84 # Calculate preamble for a header file
90 my $guard = guard
( $name );
91 my $preamble = <<"EOF";
93 * This file is automatically generated from $master. Do not edit this
94 * file; edit $master instead.
104 # Calculate postamble for a header file
109 my $guard = guard
( $name );
110 return "\n#endif /* $guard */\n";
113 # Get the new configuration by splitting config.h file using the
122 open my $fh, "<$file" or die "Could not open $file: $!\n";
124 if ( ( my $newcursor, my $suffix ) = /\@BEGIN\s+(\w+\.h)(.*)$/ ) {
125 die "Missing \"\@END $cursor\" before \"\@BEGIN $1\""
126 ." at $file line $.\n" if $cursor;
127 $cursor = $newcursor;
128 $cfg->{$cursor} = preamble
( $cursor, $file )
129 unless exists $cfg->{$cursor};
130 $cfg->{$cursor} .= "\n/*".$suffix."\n";
131 } elsif ( ( my $prefix, my $oldcursor ) = /^(.*)\@END\s+(\w+\.h)/ ) {
132 die "Missing \"\@BEGIN $oldcursor\" before \"\@END $oldcursor\""
133 ." at $file line $.\n" unless $cursor eq $oldcursor;
134 $cfg->{$cursor} .= $prefix."*/\n";
137 $cfg->{$cursor} .= $_ if $cursor;
141 die "Missing \"\@END $cursor\" in $file\n" if $cursor;
143 foreach $cursor ( keys %$cfg ) {
144 $cfg->{$cursor} .= postamble
( $cursor );
150 #############################################################################
154 # Read in current config file fragments
156 my $current = current_config
( $cfgdir );
158 # Read in config.h and split it into fragments
160 my $new = new_config
( $config_h );
162 # Delete any no-longer-wanted config file fragments
164 foreach my $file ( keys %$current ) {
165 unlink catfile
( $cfgdir, $file ) unless exists $new->{$file};
168 # Write out any modified fragments, and find the oldest timestamp of
169 # any unmodified fragments.
171 my $oldest = time ();
172 foreach my $file ( keys %$new ) {
173 if ( $current->{$file} && $new->{$file} eq $current->{$file} ) {
175 my $time = file_mtime
( catfile
( $cfgdir, $file ) );
176 $oldest = $time if $time < $oldest;
178 write_file
( catfile
( $cfgdir, $file ), $new->{$file} );
182 # If we now have fragments that are older than config.h, set the
183 # timestamp on config.h to match the oldest fragment, to prevent make
184 # from always attempting to rebuild the fragments.
186 if ( $oldest < file_mtime
( $config_h ) ) {
187 utime time(), $oldest, $config_h or die "Could not touch $config_h: $!\n";