|  | @@ -0,0 +1,163 @@
 | 
		
	
		
			
			|  | 1 | +#!/usr/bin/perl -w
 | 
		
	
		
			
			|  | 2 | +
 | 
		
	
		
			
			|  | 3 | +use File::Spec::Functions qw ( :ALL );
 | 
		
	
		
			
			|  | 4 | +use strict;
 | 
		
	
		
			
			|  | 5 | +use warnings;
 | 
		
	
		
			
			|  | 6 | +
 | 
		
	
		
			
			|  | 7 | +my $cfgdir = "config";
 | 
		
	
		
			
			|  | 8 | +my $config_h = "config.h";
 | 
		
	
		
			
			|  | 9 | +
 | 
		
	
		
			
			|  | 10 | +# Read in a whole file
 | 
		
	
		
			
			|  | 11 | +#
 | 
		
	
		
			
			|  | 12 | +sub read_file {
 | 
		
	
		
			
			|  | 13 | +  my $file = shift;
 | 
		
	
		
			
			|  | 14 | +
 | 
		
	
		
			
			|  | 15 | +  open my $fh, "<$file" or die "Could not open file $file: $!\n";
 | 
		
	
		
			
			|  | 16 | +  local $/;
 | 
		
	
		
			
			|  | 17 | +  my $data = <$fh>;
 | 
		
	
		
			
			|  | 18 | +  close $fh;
 | 
		
	
		
			
			|  | 19 | +  return $data;
 | 
		
	
		
			
			|  | 20 | +}
 | 
		
	
		
			
			|  | 21 | +
 | 
		
	
		
			
			|  | 22 | +# Write out a whole file
 | 
		
	
		
			
			|  | 23 | +#
 | 
		
	
		
			
			|  | 24 | +sub write_file {
 | 
		
	
		
			
			|  | 25 | +  my $file = shift;
 | 
		
	
		
			
			|  | 26 | +  my $data = shift;
 | 
		
	
		
			
			|  | 27 | +
 | 
		
	
		
			
			|  | 28 | +  open my $fh, ">$file" or die "Could not write $file: $!\n";
 | 
		
	
		
			
			|  | 29 | +  print $fh $data;
 | 
		
	
		
			
			|  | 30 | +  close $fh;
 | 
		
	
		
			
			|  | 31 | +}
 | 
		
	
		
			
			|  | 32 | +
 | 
		
	
		
			
			|  | 33 | +# Delete a file
 | 
		
	
		
			
			|  | 34 | +#
 | 
		
	
		
			
			|  | 35 | +sub delete_file {
 | 
		
	
		
			
			|  | 36 | +  my $file = shift;
 | 
		
	
		
			
			|  | 37 | +
 | 
		
	
		
			
			|  | 38 | +  unlink $file or die "Could not delete $file: $!\n";
 | 
		
	
		
			
			|  | 39 | +}
 | 
		
	
		
			
			|  | 40 | +
 | 
		
	
		
			
			|  | 41 | +# Read a directory listing (excluding the . and .. entries)
 | 
		
	
		
			
			|  | 42 | +#
 | 
		
	
		
			
			|  | 43 | +sub read_dir {
 | 
		
	
		
			
			|  | 44 | +  my $dir = shift;
 | 
		
	
		
			
			|  | 45 | +
 | 
		
	
		
			
			|  | 46 | +  opendir my $dh, $dir or die "Could not open directory $dir: $!\n";
 | 
		
	
		
			
			|  | 47 | +  my @entries = grep { ! /^(\.)+$/ } readdir $dh;
 | 
		
	
		
			
			|  | 48 | +  closedir $dh;
 | 
		
	
		
			
			|  | 49 | +  return @entries;
 | 
		
	
		
			
			|  | 50 | +}
 | 
		
	
		
			
			|  | 51 | +
 | 
		
	
		
			
			|  | 52 | +# Get the current configuration by reading the configuration file
 | 
		
	
		
			
			|  | 53 | +# fragments
 | 
		
	
		
			
			|  | 54 | +#
 | 
		
	
		
			
			|  | 55 | +sub current_config {
 | 
		
	
		
			
			|  | 56 | +  my $dir = shift;
 | 
		
	
		
			
			|  | 57 | +
 | 
		
	
		
			
			|  | 58 | +  my $cfg = {};
 | 
		
	
		
			
			|  | 59 | +  foreach my $file ( read_dir ( $dir ) ) {
 | 
		
	
		
			
			|  | 60 | +    $cfg->{$file} = read_file ( catfile ( $dir, $file ) );
 | 
		
	
		
			
			|  | 61 | +  }
 | 
		
	
		
			
			|  | 62 | +  return $cfg;
 | 
		
	
		
			
			|  | 63 | +}
 | 
		
	
		
			
			|  | 64 | +
 | 
		
	
		
			
			|  | 65 | +# Calculate guard name for a header file
 | 
		
	
		
			
			|  | 66 | +#
 | 
		
	
		
			
			|  | 67 | +sub guard {
 | 
		
	
		
			
			|  | 68 | +  my $name = shift;
 | 
		
	
		
			
			|  | 69 | +
 | 
		
	
		
			
			|  | 70 | +  $name =~ s/\W/_/g;
 | 
		
	
		
			
			|  | 71 | +  return "CONFIG_".( uc $name );
 | 
		
	
		
			
			|  | 72 | +}
 | 
		
	
		
			
			|  | 73 | +
 | 
		
	
		
			
			|  | 74 | +# Calculate preamble for a header file
 | 
		
	
		
			
			|  | 75 | +#
 | 
		
	
		
			
			|  | 76 | +sub preamble {
 | 
		
	
		
			
			|  | 77 | +  my $name = shift;
 | 
		
	
		
			
			|  | 78 | +  my $master = shift;
 | 
		
	
		
			
			|  | 79 | +
 | 
		
	
		
			
			|  | 80 | +  my $guard = guard ( $name );
 | 
		
	
		
			
			|  | 81 | +  my $preamble = <<"EOF";
 | 
		
	
		
			
			|  | 82 | +/*
 | 
		
	
		
			
			|  | 83 | + * This file is automatically generated from $master.  Do not edit this
 | 
		
	
		
			
			|  | 84 | + * file; edit $master instead.
 | 
		
	
		
			
			|  | 85 | + *
 | 
		
	
		
			
			|  | 86 | + */
 | 
		
	
		
			
			|  | 87 | +
 | 
		
	
		
			
			|  | 88 | +#ifndef $guard
 | 
		
	
		
			
			|  | 89 | +#define $guard
 | 
		
	
		
			
			|  | 90 | +EOF
 | 
		
	
		
			
			|  | 91 | +  return $preamble;
 | 
		
	
		
			
			|  | 92 | +}
 | 
		
	
		
			
			|  | 93 | +
 | 
		
	
		
			
			|  | 94 | +# Calculate postamble for a header file
 | 
		
	
		
			
			|  | 95 | +#
 | 
		
	
		
			
			|  | 96 | +sub postamble {
 | 
		
	
		
			
			|  | 97 | +  my $name = shift;
 | 
		
	
		
			
			|  | 98 | +
 | 
		
	
		
			
			|  | 99 | +  my $guard = guard ( $name );
 | 
		
	
		
			
			|  | 100 | +  return "\n#endif /* $guard */\n";
 | 
		
	
		
			
			|  | 101 | +} 
 | 
		
	
		
			
			|  | 102 | +
 | 
		
	
		
			
			|  | 103 | +# Get the new configuration by splitting config.h file using the
 | 
		
	
		
			
			|  | 104 | +# @BEGIN/@END tags
 | 
		
	
		
			
			|  | 105 | +#
 | 
		
	
		
			
			|  | 106 | +sub new_config {
 | 
		
	
		
			
			|  | 107 | +  my $file = shift;
 | 
		
	
		
			
			|  | 108 | +
 | 
		
	
		
			
			|  | 109 | +  my $cfg = {};
 | 
		
	
		
			
			|  | 110 | +  my $cursor = "";
 | 
		
	
		
			
			|  | 111 | +
 | 
		
	
		
			
			|  | 112 | +  open my $fh, "<$file" or die "Could not open $file: $!\n";
 | 
		
	
		
			
			|  | 113 | +  while ( <$fh> ) {
 | 
		
	
		
			
			|  | 114 | +    if ( ( my $newcursor, my $suffix ) = /\@BEGIN\s+(\w+\.h)(.*)$/ ) {
 | 
		
	
		
			
			|  | 115 | +      die "Missing \"\@END $cursor\" before \"\@BEGIN $1\""
 | 
		
	
		
			
			|  | 116 | +	  ." at $file line $.\n" if $cursor;
 | 
		
	
		
			
			|  | 117 | +      $cursor = $newcursor;
 | 
		
	
		
			
			|  | 118 | +      $cfg->{$cursor} = preamble ( $cursor, $file )
 | 
		
	
		
			
			|  | 119 | +	  unless exists $cfg->{$cursor};
 | 
		
	
		
			
			|  | 120 | +      $cfg->{$cursor} .= "\n/*".$suffix."\n";
 | 
		
	
		
			
			|  | 121 | +    } elsif ( ( my $prefix, my $oldcursor ) = /^(.*)\@END\s+(\w+\.h)/ ) {
 | 
		
	
		
			
			|  | 122 | +      die "Missing \"\@BEGIN $oldcursor\" before \"\@END $oldcursor\""
 | 
		
	
		
			
			|  | 123 | +	  ." at $file line $.\n" unless $cursor eq $oldcursor;
 | 
		
	
		
			
			|  | 124 | +      $cfg->{$cursor} .= $prefix."*/\n";
 | 
		
	
		
			
			|  | 125 | +      $cursor = "";
 | 
		
	
		
			
			|  | 126 | +    } else {
 | 
		
	
		
			
			|  | 127 | +      $cfg->{$cursor} .= $_ if $cursor;
 | 
		
	
		
			
			|  | 128 | +    }
 | 
		
	
		
			
			|  | 129 | +  }
 | 
		
	
		
			
			|  | 130 | +  close $fh;
 | 
		
	
		
			
			|  | 131 | +  die "Missing \"\@END $cursor\" in $file\n" if $cursor;
 | 
		
	
		
			
			|  | 132 | +
 | 
		
	
		
			
			|  | 133 | +  foreach $cursor ( keys %$cfg ) {
 | 
		
	
		
			
			|  | 134 | +    $cfg->{$cursor} .= postamble ( $cursor );
 | 
		
	
		
			
			|  | 135 | +  }
 | 
		
	
		
			
			|  | 136 | +
 | 
		
	
		
			
			|  | 137 | +  return $cfg;
 | 
		
	
		
			
			|  | 138 | +}  
 | 
		
	
		
			
			|  | 139 | +
 | 
		
	
		
			
			|  | 140 | +#############################################################################
 | 
		
	
		
			
			|  | 141 | +#
 | 
		
	
		
			
			|  | 142 | +# Main program
 | 
		
	
		
			
			|  | 143 | +
 | 
		
	
		
			
			|  | 144 | +# Read in current config file fragments
 | 
		
	
		
			
			|  | 145 | +#
 | 
		
	
		
			
			|  | 146 | +my $current = current_config ( $cfgdir );
 | 
		
	
		
			
			|  | 147 | +
 | 
		
	
		
			
			|  | 148 | +# Read in config.h and split it into fragments
 | 
		
	
		
			
			|  | 149 | +#
 | 
		
	
		
			
			|  | 150 | +my $new = new_config ( $config_h );
 | 
		
	
		
			
			|  | 151 | +
 | 
		
	
		
			
			|  | 152 | +# Delete any no-longer-wanted config file fragments
 | 
		
	
		
			
			|  | 153 | +#
 | 
		
	
		
			
			|  | 154 | +foreach my $file ( keys %$current ) {
 | 
		
	
		
			
			|  | 155 | +  unlink catfile ( $cfgdir, $file ) unless exists $new->{$file};
 | 
		
	
		
			
			|  | 156 | +}
 | 
		
	
		
			
			|  | 157 | +
 | 
		
	
		
			
			|  | 158 | +# Write out any modified fragments
 | 
		
	
		
			
			|  | 159 | +#
 | 
		
	
		
			
			|  | 160 | +foreach my $file ( keys %$new ) {
 | 
		
	
		
			
			|  | 161 | +  write_file ( catfile ( $cfgdir, $file ), $new->{$file} )
 | 
		
	
		
			
			|  | 162 | +      unless $current->{$file} && $new->{$file} eq $current->{$file};
 | 
		
	
		
			
			|  | 163 | +}
 |