diff options
Diffstat (limited to 'source4/script')
-rwxr-xr-x | source4/script/update-proto.pl | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/source4/script/update-proto.pl b/source4/script/update-proto.pl new file mode 100755 index 00000000000..d351e2dcfea --- /dev/null +++ b/source4/script/update-proto.pl @@ -0,0 +1,189 @@ +#!/usr/bin/perl +# Simple script for updating the prototypes in a C header file +# +# Copyright (C) 2006 Jelmer Vernooij <jelmer@samba.org> +# Published under the GNU GPL +# +# TODO: +# - update for prototypes that span lines + +use strict; +use warnings; +use Getopt::Long; + +=head1 NAME + +update-proto - automatically update prototypes in header files + +=head1 SYNOPSIS + +update-proto [OPTIONS] <HEADER> <C-FILE>... + +update-proto [OPTIONS] <HEADER> + +=head1 DESCRIPTION + +Update-proto makes sure the prototypes in a C header file are current +by comparing the existing prototypes in a header with the function definition +in the source file. It aims to keep the diff between the original header +and generated one as small as possible. + +New prototypes are inserted before any line that contains the following comment: + +/* New prototypes are inserted above this line */ + +It will automatically parse C files after it encounters a line that contains: + +/* The following definitions come from FILE */ + +=head1 OPTIONS + +=over 4 + +=item I<--verbose|-v> + +Increase verbosity. Currently only two levels of verbosity are used. + +=item I<--help> + +Show list of options + +=back + +=head1 BUGS + +Prototypes must appear on one line - they can't be split across multiple lines. +Some things are erroneously recognized as functions + +=head1 LICENSE + +update-proto is licensed under the GNU General Public License L<http://www.gnu.org/licenses/gpl.html>. + +=head1 AUTHOR + +update-proto was written by Jelmer Vernooij L<jelmer@samba.org>. + +=cut + +sub Usage() +{ + print "Usage: update-proto.pl [OPTIONS] <HEADER> <C-FILE>...\n"; + exit 1; +} + +sub Help() +{ + print "Usage: update-proto.pl [OPTIONS] <HEADER> <C-FILE>...\n"; + print "Options:\n"; + print " --help Show this help message\n"; + print " --verbose Write changes made to standard error\n\n"; + exit 0; +} + +my %new_protos = (); + +my $verbose = 0; + +GetOptions( + 'help|h' => \&Help, + 'v|verbose' => sub { $verbose += 1; } +) or Usage(); + +my $header = shift @ARGV; + +sub process_file($) +{ + my $file = shift; + open (IN, "<$file"); + while (my $line = <IN>) { + next if ($line =~ /^\s/); + next unless ($line =~ /\(/); + next if ($line =~ /^\/|[;]|^#|}|^\s*static/); + next unless ($line =~ /^([^(]+)(\s+)(\w+)\s*\((.*)\)\s*{*\s*$/); + + my $name = $3; + + next if ($name eq "main"); + next unless ($1 =~ /^[\*\w\s]+$/); + + $line =~ s/}\s*$//g; + $line =~ s/\n//g; + + $new_protos{$name} = "$line;"; + } + close(IN); +} + +process_file($_) foreach (@ARGV); + +my $added = 0; +my $modified = 0; +my $deleted = 0; +my $kept = 0; + +sub insert_new_protos() +{ + foreach (keys %new_protos) { + print "$new_protos{$_}\n"; + print STDERR "Inserted prototype for `$_'\n" if ($verbose); + $added+=1; + } + %new_protos = (); +} + +open (HDR, "<$header"); +while (my $line = <HDR>) { + # Insert prototypes that weren't in the header before + if ($line =~ /^\/\* New prototypes are inserted above this line.*\*\/\s*$/) { + insert_new_protos(); + print "$line\n"; + next; + } + + # Recognize C files that prototypes came from + if ($line =~ /^\/\* The following definitions come from (.*) \*\//) { + insert_new_protos(); + process_file($1); + print "$line"; + next; + } + + if ($line =~ /^\s*typedef |^\#|^\s*static/) { + print "$line"; + next; + } + + unless ($line =~ /^([^(]+)(\s+)(\w+)\s*\((.*)\)\s*;\s*$/) { + print "$line"; + next; + } + + my $name = $3; + + # This prototype is for a function that was removed + unless (defined($new_protos{$name})) { + $deleted+=1; + print STDERR "Removed prototype for `$name'\n" if ($verbose); + next; + } + + my $nline = $line; + chop($nline); + + if ($new_protos{$name} ne $nline) { + $modified+=1; + print STDERR "Updated prototype for `$name'\n" if ($verbose); + print "$new_protos{$name}\n"; + } else { + $kept+=1; + print STDERR "Prototype for `$name' didn't change\n" if ($verbose > 1); + print "$line"; + } + + delete $new_protos{$name}; +} +close(HDR); + +print STDERR "$added added, $modified modified, $deleted deleted, $kept unchanged.\n"; + +1; |