r14607: Update mkproto.pl to only write out new header files if the contents changed.
authorJelmer Vernooij <jelmer@samba.org>
Tue, 21 Mar 2006 09:25:36 +0000 (09:25 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:59:00 +0000 (13:59 -0500)
(This used to be commit 06403ea2be9ce38dbd099e710ccf17dc4340fa43)

source4/script/mkproto.pl

index 01066885e124e252c76f69ee2c6f16bc29ae42ba..097a5cb18fd0a53053f86ba477d3a73d923099a6 100755 (executable)
@@ -1,19 +1,38 @@
 #!/usr/bin/perl
+# Simple script for generating prototypes for C functions
+# Written by Jelmer Vernooij
+# based on the original mkproto.sh by Andrew Tridgell
 
 use strict;
 
 # don't use warnings module as it is not portable enough
 # use warnings;
 
-
 use Getopt::Long;
 
+#####################################################################
+# read a file into a string
+
 my $public_file = undef;
 my $private_file = undef;
 my $public_define = undef;
 my $private_define = undef;
-my $public_fd = \*STDOUT;
-my $private_fd = \*STDOUT;
+my $_public = "";
+my $_private = "";
+my $public_data = \$_public;
+my $private_data = \$_private;
+
+sub public($)
+{
+       my ($d) = @_;
+       $$public_data .= $d;
+}
+
+sub private($)
+{
+       my ($d) = @_;
+       $$private_data .= $d;
+}
 
 sub usage()
 {
@@ -55,34 +74,40 @@ if (not defined($private_define) and defined($private_file)) {
        $public_define = '_PROTO_H_';
 }
 
-if (defined($public_file)) {
-       open PUBLIC, ">$public_file" or die("Can't open `$public_file': $!"); 
-       $public_fd = \*PUBLIC;
+if ((defined($private_file) and defined($public_file) and ($private_file eq $public_file)) or 
+       (not defined($private_file) and not defined($public_file))) {
+       $private_data = $public_data;
 }
 
-if ($private_file eq $public_file) {
-       $private_fd = $public_fd;
-} elsif (defined($private_file)) {
-       open PRIVATE, ">$private_file" or die("Can't open `$private_file': $!"); ; 
-       $private_fd = \*PRIVATE;
+sub file_load($)
+{
+    my($filename) = shift;
+    local(*INPUTFILE);
+    open(INPUTFILE, $filename) || return undef;
+    my($saved_delim) = $/;
+    undef $/;
+    my($data) = <INPUTFILE>;
+    close(INPUTFILE);
+    $/ = $saved_delim;
+    return $data;
 }
 
 sub print_header($$)
 {
        my ($file, $header_name) = @_;
-       print $file "#ifndef $header_name\n";
-       print $file "#define $header_name\n\n";
-       print $file "#undef _PRINTF_ATTRIBUTE\n";
-       print $file "#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2)\n";
-       print $file "/* This file was automatically generated by mkproto.pl. DO NOT EDIT */\n\n";
+       $file->("#ifndef $header_name\n");
+       $file->("#define $header_name\n\n");
+       $file->("#undef _PRINTF_ATTRIBUTE\n");
+       $file->("#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2)\n");
+       $file->("/* This file was automatically generated by mkproto.pl. DO NOT EDIT */\n\n");
 }
 
 sub print_footer($$) 
 {
        my ($file, $header_name) = @_;
-       print $file "#undef _PRINTF_ATTRIBUTE\n";
-       print $file "#define _PRINTF_ATTRIBUTE(a1, a2)\n";
-       print $file "\n#endif /* $header_name */\n\n";
+       $file->("#undef _PRINTF_ATTRIBUTE\n");
+       $file->("#define _PRINTF_ATTRIBUTE(a1, a2)\n");
+       $file->("\n#endif /* $header_name */\n\n");
 }
 
 sub handle_loadparm($$) 
@@ -108,7 +133,7 @@ sub handle_loadparm($$)
                            "LOCAL" => "int "
                            );
 
-               print $file "$tmap{$type}$name($smap{$scope});\n";
+               $file->("$tmap{$type}$name($smap{$scope});\n");
        }
 }
 
@@ -120,10 +145,10 @@ sub process_file($$$)
 
        open(FH, "< $filename") || die "Failed to open $filename";
 
-       print $private_file "\n/* The following definitions come from $filename  */\n\n";
+       $private_file->("\n/* The following definitions come from $filename  */\n\n");
 
        while (my $line = <FH>) {             
-               my $target = $private_file;
+               my $target = \&private;
                my $is_public = 0;
 
                # these are ordered for maximum speed
@@ -139,7 +164,7 @@ sub process_file($$$)
                }
 
                if ($line =~ /^_PUBLIC_[\t ]/) {
-                       $target = $public_file;
+                       $target = \&public;
                        $is_public = 1;
                }
 
@@ -154,42 +179,68 @@ sub process_file($$$)
 
                if ( $line =~ /\(.*\)\s*$/o ) {
                        chomp $line;
-                       print $target "$line;\n";
+                       $target->("$line;\n");
                        next;
                }
 
-               print $target $line;
+               $target->($line);
 
                while ($line = <FH>) {
                        if ($line =~ /\)\s*$/o) {
                                chomp $line;
-                               print $target "$line;\n";
+                               $target->("$line;\n");
                                last;
                        }
-                       print $target $line;
+                       $target->($line);
                }
        }
 
        close(FH);
 }
 
-print_header($public_fd, $public_define);
+print_header(\&public, $public_define);
 if ($public_file ne $private_file) {
-       print_header($private_fd, $private_define);
+       print_header(\&private, $private_define);
 
-       print $private_fd "/* this file contains prototypes for functions that " .
+       private("/* this file contains prototypes for functions that " .
                        "are private \n * to this subsystem or library. These functions " .
-                       "should not be \n * used outside this particular subsystem! */\n\n";
+                       "should not be \n * used outside this particular subsystem! */\n\n");
 
-       print $public_fd "/* this file contains prototypes for functions that " . 
-                       "are part of \n * the public API of this subsystem or library. */\n\n";
+       public("/* this file contains prototypes for functions that " . 
+                       "are part of \n * the public API of this subsystem or library. */\n\n");
 
 }
 
-print $public_fd "#ifndef _PUBLIC_\n#define _PUBLIC_\n#endif\n\n";
+public("#ifndef _PUBLIC_\n#define _PUBLIC_\n#endif\n\n");
 
-process_file($public_fd, $private_fd, $_) foreach (@ARGV);
-print_footer($public_fd, $public_define);
+process_file(\&public, \&private, $_) foreach (@ARGV);
+print_footer(\&public, $public_define);
 if ($public_file ne $private_file) {
-       print_footer($private_fd, $private_define);
+       print_footer(\&private, $private_define);
+}
+
+if (not defined($public_file)) {
+       print STDOUT $$public_data;
+}
+
+if (not defined($private_file) and defined($public_file)) {
+       print STDOUT $$private_data;
+}
+
+my $old_public_data = file_load($public_file);
+my $old_private_data = file_load($private_file);
+
+if (not defined($old_public_data) or ($old_public_data ne $$public_data))
+{
+       open(PUBLIC, ">$public_file") or die("Can't open `$public_file': $!"); 
+       print PUBLIC "$$public_data";
+       close(PUBLIC);
+} 
+
+if (($public_file ne $private_file) and (
+       not defined($old_private_data) or ($old_private_data ne $$private_data))) {
+
+       open(PRIVATE, ">$private_file") or die("Can't open `$private_file': $!"); 
+       print PRIVATE "$$private_data";
+       close(PRIVATE);
 }