#!/usr/bin/perl # Copyright (C) 2012 Free Software Foundation, Inc. # # This file is part of GCC. # # GCC is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # GCC is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GCC; see the file COPYING. If not, write to # the Free Software Foundation, 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. # This script parses a .diff file generated with 'diff -up' or 'diff -cp' # and writes a skeleton ChangeLog file to stdout. It does not try to be # very smart when parsing function names, but it produces a reasonable # approximation. # # Author: Diego Novillo and # Cary Coutant # Change these settings to reflect your profile. $username = $ENV{'USER'}; $name = `finger $username | grep -o 'Name: .*'`; @n = split(/: /, $name); $name = @n[1]; chop($name); $addr = $username . "\@my.domain.org"; $date = `date +%Y-%m-%d`; chop ($date); #----------------------------------------------------------------------------- # Program starts here. You should not need to edit anything below this # line. #----------------------------------------------------------------------------- if ( $#ARGV != 0 ) { $prog = `basename $0`; chop ($prog); print "usage: $prog file.diff\n\n"; print "Adds a ChangeLog template to the start of file.diff\n"; print "It assumes that file.diff has been created with -up or -cp.\n"; exit 1; } $diff = $ARGV[0]; $dir = `dirname $diff`; chop ($dir); $basename = `basename $diff`; chop ($basename); $cl = `mktemp /tmp/$basename.XXXXXX` || exit 1; chop ($cl); $hdrline = "$date $name <$addr>"; open (CLFILE, ">$cl") or die "Could not open file $cl for writing"; print CLFILE "$hdrline\n\n"; # For every file in the .diff print all the function names in ChangeLog # format. $bof = 0; open (DFILE, $diff) or die "Could not open file $diff for reading"; while () { # Check if we found a new file. if (/^\+\+\+ (b\/)?(\S+)/) { # If we have not seen any function names in the previous file (ie, # $bof == 1), we just write out a ':' before starting the next # file. if ($bof == 1) { print CLFILE ":\n"; } $filename = $2; print CLFILE "\t* $filename"; $bof = 1; } # Remember the last line in a unified diff block that might start # a new function. if (/^[-+ ]([a-zA-Z0-9_].*)/) { $save_fn = $1; } # If we find a new function, print it in brackets. Special case if # this is the first function in a file. # # Note that we don't try too hard to find good matches. This should # return a superset of the actual set of functions in the .diff file. # # The first two patterns work with context diff files (diff -c). The # third pattern works with unified diff files (diff -u). # # The fourth pattern looks for the starts of functions or classes # within a unified diff block. if (/^\*\*\*\*\*\** ([a-zA-Z0-9_].*)/ || /^[\-\+\!] ([a-zA-Z0-9_]+)[ \t]*\(.*/ || /^@@ .* @@ ([a-zA-Z0-9_].*)/ || /^[-+ ](\{)/) { $_ = $1; my $fn; if (/^\{/) { # Beginning of a new function. $_ = $save_fn; } else { $save_fn = ""; } if (/;$/) { # No usable function name found. } elsif (/^((class|struct|union|enum) [a-zA-Z0-9_]+)/) { # Discard stuff after the class/struct/etc. tag. $fn = $1; } elsif (/([a-zA-Z0-9_][^(]*)\(/) { # Discard template and function parameters. $fn = $1; 1 while ($fn =~ s/<[^<>]*>//); $fn =~ s/[ \t]*$//; } if ($fn && $seen_names{$fn} == 0) { # If this is the first function in the file, we display it next # to the filename, so we need an extra space before the opening # brace. if ($bof) { print CLFILE " "; $bof = 0; } else { print CLFILE "\t"; } print CLFILE "($fn):\n"; $seen_names{$fn} = 1; } } } # If we have not seen any function names (ie, $bof == 1), we just # write out a ':'. This happens when there is only one file with no # functions. if ($bof == 1) { print CLFILE ":\n"; } print CLFILE "\n"; close (DFILE); # Concatenate the ChangeLog template and the original .diff file. system ("cat $diff >>$cl && mv $cl $diff") == 0 or die "Could not add the ChangeLog entry to $diff"; exit 0;