[util] config-local.h to avoid accidental commits
[people/dverkamp/gpxe.git] / src / util / mkconfig.pl
index 2f2d6a4..e55c2ca 100755 (executable)
@@ -1,11 +1,13 @@
 #!/usr/bin/perl -w
 
 use File::Spec::Functions qw ( :ALL );
+use File::stat;
 use strict;
 use warnings;
 
 my $cfgdir = "config";
-my $config_h = "config.h";
+my $config_h = shift || "config.h";
+my @input_files;
 
 # Read in a whole file
 #
@@ -38,13 +40,22 @@ sub delete_file {
   unlink $file or die "Could not delete $file: $!\n";
 }
 
-# Read a directory listing (excluding the . and .. entries)
+# 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 { ! /^(\.)+$/ } readdir $dh;
+  my @entries = grep { /\.h$/ } readdir $dh;
   closedir $dh;
   return @entries;
 }
@@ -100,15 +111,15 @@ sub postamble {
   return "\n#endif /* $guard */\n";
 } 
 
-# Get the new configuration by splitting config.h file using the
-# @BEGIN/@END tags
+# Parse one config.h file into an existing configuration
 #
-sub new_config {
+sub parse_config {
   my $file = shift;
-
-  my $cfg = {};
+  my $cfg = shift;
   my $cursor = "";
 
+  push ( @input_files, $file );
+
   open my $fh, "<$file" or die "Could not open $file: $!\n";
   while ( <$fh> ) {
     if ( ( my $newcursor, my $suffix ) = /\@BEGIN\s+(\w+\.h)(.*)$/ ) {
@@ -123,14 +134,28 @@ sub new_config {
          ." at $file line $.\n" unless $cursor eq $oldcursor;
       $cfg->{$cursor} .= $prefix."*/\n";
       $cursor = "";
+    } elsif ( ( my $newfile ) = /\@TRYSOURCE\s+([\w\-]+\.h)/ ) {
+      die "Missing \"\@END $cursor\" before \"\@TRYSOURCE $newfile\""
+         ." at $file line $.\n" if $cursor;
+      parse_config ( $newfile, $cfg ) if -e $newfile;
     } else {
       $cfg->{$cursor} .= $_ if $cursor;
     }
   }
   close $fh;
   die "Missing \"\@END $cursor\" in $file\n" if $cursor;
+}
 
-  foreach $cursor ( keys %$cfg ) {
+# Get the new configuration by splitting config.h file using the
+# @BEGIN/@END tags
+#
+sub new_config {
+  my $file = shift;
+  my $cfg = {};
+
+  parse_config ( $file, $cfg );
+
+  foreach my $cursor ( keys %$cfg ) {
     $cfg->{$cursor} .= postamble ( $cursor );
   }
 
@@ -155,9 +180,26 @@ foreach my $file ( keys %$current ) {
   unlink catfile ( $cfgdir, $file ) unless exists $new->{$file};
 }
 
-# Write out any modified fragments
+# Write out any modified fragments, and find the oldest timestamp of
+# any unmodified fragments.
 #
+my $oldest = time ();
 foreach my $file ( keys %$new ) {
-  write_file ( catfile ( $cfgdir, $file ), $new->{$file} )
-      unless $current->{$file} && $new->{$file} eq $current->{$file};
+  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 each input file to match the oldest fragment, to
+# prevent make from always attempting to rebuild the fragments.
+#
+foreach my $file ( @input_files ) {
+  if ( $oldest < file_mtime ( $file ) ) {
+    utime time(), $oldest, $file or die "Could not touch $file: $!\n";
+  }
 }