3 use File::Spec::Functions qw ( :ALL );
9 my $config_h = shift || "config.h";
12 # Read in a whole file
17 open my $fh, "<$file" or die "Could not open file $file: $!\n";
24 # Write out a whole file
30 open my $fh, ">$file" or die "Could not write $file: $!\n";
40 unlink $file or die "Could not delete $file: $!\n";
43 # Get a file modification time
48 my $stat = stat ( $file ) or die "Could not stat $file: $!\n";
52 # Read all the .h files in a directory
57 opendir my $dh, $dir or die "Could not open directory $dir: $!\n";
58 my @entries = grep { /\.h$/ } readdir $dh;
63 # Get the current configuration by reading the configuration file
70 foreach my $file ( read_dir ( $dir ) ) {
71 $cfg->{$file} = read_file ( catfile ( $dir, $file ) );
76 # Calculate guard name for a header file
82 return "CONFIG_".( uc $name );
85 # Calculate preamble for a header file
91 my $guard = guard ( $name );
92 my $preamble = <<"EOF";
94 * This file is automatically generated from $master. Do not edit this
95 * file; edit $master instead.
105 # Calculate postamble for a header file
110 my $guard = guard ( $name );
111 return "\n#endif /* $guard */\n";
114 # Parse one config.h file into an existing configuration
121 push ( @input_files, $file );
123 open my $fh, "<$file" or die "Could not open $file: $!\n";
125 if ( ( my $newcursor, my $suffix ) = /\@BEGIN\s+(\w+\.h)(.*)$/ ) {
126 die "Missing \"\@END $cursor\" before \"\@BEGIN $1\""
127 ." at $file line $.\n" if $cursor;
128 $cursor = $newcursor;
129 $cfg->{$cursor} = preamble ( $cursor, $file )
130 unless exists $cfg->{$cursor};
131 $cfg->{$cursor} .= "\n/*".$suffix."\n";
132 } elsif ( ( my $prefix, my $oldcursor ) = /^(.*)\@END\s+(\w+\.h)/ ) {
133 die "Missing \"\@BEGIN $oldcursor\" before \"\@END $oldcursor\""
134 ." at $file line $.\n" unless $cursor eq $oldcursor;
135 $cfg->{$cursor} .= $prefix."*/\n";
137 } elsif ( ( my $newfile ) = /\@TRYSOURCE\s+([\w\-]+\.h)/ ) {
138 die "Missing \"\@END $cursor\" before \"\@TRYSOURCE $newfile\""
139 ." at $file line $.\n" if $cursor;
140 parse_config ( $newfile, $cfg ) if -e $newfile;
142 $cfg->{$cursor} .= $_ if $cursor;
146 die "Missing \"\@END $cursor\" in $file\n" if $cursor;
149 # Get the new configuration by splitting config.h file using the
156 parse_config ( $file, $cfg );
158 foreach my $cursor ( keys %$cfg ) {
159 $cfg->{$cursor} .= postamble ( $cursor );
165 #############################################################################
169 # Read in current config file fragments
171 my $current = current_config ( $cfgdir );
173 # Read in config.h and split it into fragments
175 my $new = new_config ( $config_h );
177 # Delete any no-longer-wanted config file fragments
179 foreach my $file ( keys %$current ) {
180 unlink catfile ( $cfgdir, $file ) unless exists $new->{$file};
183 # Write out any modified fragments, and find the oldest timestamp of
184 # any unmodified fragments.
186 my $oldest = time ();
187 foreach my $file ( keys %$new ) {
188 if ( $current->{$file} && $new->{$file} eq $current->{$file} ) {
190 my $time = file_mtime ( catfile ( $cfgdir, $file ) );
191 $oldest = $time if $time < $oldest;
193 write_file ( catfile ( $cfgdir, $file ), $new->{$file} );
197 # If we now have fragments that are older than config.h, set the
198 # timestamp on each input file to match the oldest fragment, to
199 # prevent make from always attempting to rebuild the fragments.
201 foreach my $file ( @input_files ) {
202 if ( $oldest < file_mtime ( $file ) ) {
203 utime time(), $oldest, $file or die "Could not touch $file: $!\n";