mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-14 15:21:32 +00:00
189 lines
4.0 KiB
Perl
Executable File
189 lines
4.0 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
|
|
|
use File::Spec::Functions qw ( :ALL );
|
|
use File::stat;
|
|
use strict;
|
|
use warnings;
|
|
|
|
my $cfgdir = "config";
|
|
my $config_h = shift || "config.h";
|
|
|
|
# Read in a whole file
|
|
#
|
|
sub read_file {
|
|
my $file = shift;
|
|
|
|
open my $fh, "<$file" or die "Could not open file $file: $!\n";
|
|
local $/;
|
|
my $data = <$fh>;
|
|
close $fh;
|
|
return $data;
|
|
}
|
|
|
|
# Write out a whole file
|
|
#
|
|
sub write_file {
|
|
my $file = shift;
|
|
my $data = shift;
|
|
|
|
open my $fh, ">$file" or die "Could not write $file: $!\n";
|
|
print $fh $data;
|
|
close $fh;
|
|
}
|
|
|
|
# Delete a file
|
|
#
|
|
sub delete_file {
|
|
my $file = shift;
|
|
|
|
unlink $file or die "Could not delete $file: $!\n";
|
|
}
|
|
|
|
# Get a file modification time
|
|
#
|
|
sub file_mtime {
|
|
my $file = shift;
|
|
|
|
my $stat = stat ( $file ) or die "Could not stat $file: $!\n";
|
|
return $stat->mtime;
|
|
}
|
|
|
|
# Read all the .h files in a directory
|
|
#
|
|
sub read_dir {
|
|
my $dir = shift;
|
|
|
|
opendir my $dh, $dir or die "Could not open directory $dir: $!\n";
|
|
my @entries = grep { /\.h$/ } readdir $dh;
|
|
closedir $dh;
|
|
return @entries;
|
|
}
|
|
|
|
# Get the current configuration by reading the configuration file
|
|
# fragments
|
|
#
|
|
sub current_config {
|
|
my $dir = shift;
|
|
|
|
my $cfg = {};
|
|
foreach my $file ( read_dir ( $dir ) ) {
|
|
$cfg->{$file} = read_file ( catfile ( $dir, $file ) );
|
|
}
|
|
return $cfg;
|
|
}
|
|
|
|
# Calculate guard name for a header file
|
|
#
|
|
sub guard {
|
|
my $name = shift;
|
|
|
|
$name =~ s/\W/_/g;
|
|
return "CONFIG_".( uc $name );
|
|
}
|
|
|
|
# Calculate preamble for a header file
|
|
#
|
|
sub preamble {
|
|
my $name = shift;
|
|
my $master = shift;
|
|
|
|
my $guard = guard ( $name );
|
|
my $preamble = <<"EOF";
|
|
/*
|
|
* This file is automatically generated from $master. Do not edit this
|
|
* file; edit $master instead.
|
|
*
|
|
*/
|
|
|
|
#ifndef $guard
|
|
#define $guard
|
|
EOF
|
|
return $preamble;
|
|
}
|
|
|
|
# Calculate postamble for a header file
|
|
#
|
|
sub postamble {
|
|
my $name = shift;
|
|
|
|
my $guard = guard ( $name );
|
|
return "\n#endif /* $guard */\n";
|
|
}
|
|
|
|
# Get the new configuration by splitting config.h file using the
|
|
# @BEGIN/@END tags
|
|
#
|
|
sub new_config {
|
|
my $file = shift;
|
|
|
|
my $cfg = {};
|
|
my $cursor = "";
|
|
|
|
open my $fh, "<$file" or die "Could not open $file: $!\n";
|
|
while ( <$fh> ) {
|
|
if ( ( my $newcursor, my $suffix ) = /\@BEGIN\s+(\w+\.h)(.*)$/ ) {
|
|
die "Missing \"\@END $cursor\" before \"\@BEGIN $1\""
|
|
." at $file line $.\n" if $cursor;
|
|
$cursor = $newcursor;
|
|
$cfg->{$cursor} = preamble ( $cursor, $file )
|
|
unless exists $cfg->{$cursor};
|
|
$cfg->{$cursor} .= "\n/*".$suffix."\n";
|
|
} elsif ( ( my $prefix, my $oldcursor ) = /^(.*)\@END\s+(\w+\.h)/ ) {
|
|
die "Missing \"\@BEGIN $oldcursor\" before \"\@END $oldcursor\""
|
|
." at $file line $.\n" unless $cursor eq $oldcursor;
|
|
$cfg->{$cursor} .= $prefix."*/\n";
|
|
$cursor = "";
|
|
} else {
|
|
$cfg->{$cursor} .= $_ if $cursor;
|
|
}
|
|
}
|
|
close $fh;
|
|
die "Missing \"\@END $cursor\" in $file\n" if $cursor;
|
|
|
|
foreach $cursor ( keys %$cfg ) {
|
|
$cfg->{$cursor} .= postamble ( $cursor );
|
|
}
|
|
|
|
return $cfg;
|
|
}
|
|
|
|
#############################################################################
|
|
#
|
|
# Main program
|
|
|
|
# Read in current config file fragments
|
|
#
|
|
my $current = current_config ( $cfgdir );
|
|
|
|
# Read in config.h and split it into fragments
|
|
#
|
|
my $new = new_config ( $config_h );
|
|
|
|
# Delete any no-longer-wanted config file fragments
|
|
#
|
|
foreach my $file ( keys %$current ) {
|
|
unlink catfile ( $cfgdir, $file ) unless exists $new->{$file};
|
|
}
|
|
|
|
# Write out any modified fragments, and find the oldest timestamp of
|
|
# any unmodified fragments.
|
|
#
|
|
my $oldest = time ();
|
|
foreach my $file ( keys %$new ) {
|
|
if ( $current->{$file} && $new->{$file} eq $current->{$file} ) {
|
|
# Unmodified
|
|
my $time = file_mtime ( catfile ( $cfgdir, $file ) );
|
|
$oldest = $time if $time < $oldest;
|
|
} else {
|
|
write_file ( catfile ( $cfgdir, $file ), $new->{$file} );
|
|
}
|
|
}
|
|
|
|
# If we now have fragments that are older than config.h, set the
|
|
# timestamp on config.h to match the oldest fragment, to prevent make
|
|
# from always attempting to rebuild the fragments.
|
|
#
|
|
if ( $oldest < file_mtime ( $config_h ) ) {
|
|
utime time(), $oldest, $config_h or die "Could not touch $config_h: $!\n";
|
|
}
|