First version
authorMichael Brown <mcb30@etherboot.org>
Sun, 17 Apr 2005 15:25:09 +0000 (15:25 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sun, 17 Apr 2005 15:25:09 +0000 (15:25 +0000)
src/util/mkconfig.pl [new file with mode: 0755]

diff --git a/src/util/mkconfig.pl b/src/util/mkconfig.pl
new file mode 100755 (executable)
index 0000000..2f2d6a4
--- /dev/null
@@ -0,0 +1,163 @@
+#!/usr/bin/perl -w
+
+use File::Spec::Functions qw ( :ALL );
+use strict;
+use warnings;
+
+my $cfgdir = "config";
+my $config_h = "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";
+}
+
+# Read a directory listing (excluding the . and .. entries)
+#
+sub read_dir {
+  my $dir = shift;
+
+  opendir my $dh, $dir or die "Could not open directory $dir: $!\n";
+  my @entries = grep { ! /^(\.)+$/ } 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
+#
+foreach my $file ( keys %$new ) {
+  write_file ( catfile ( $cfgdir, $file ), $new->{$file} )
+      unless $current->{$file} && $new->{$file} eq $current->{$file};
+}