2 # Copyright: 2008-2010, Nick Treleaven
3 # License: GNU GPL V2 or later, as published by the Free Software Foundation, USA.
6 # Searches a ChangeLog file for a line matching 'matchstring', then matches
7 # all lines until two consecutive empty lines are found. The process then
8 # repeats until all matching blocks of text are found.
9 # Results are printed in reverse, hence in chronological order (as ChangeLogs
10 # are usually written in reverse date order).
12 # The resulting lines are then formatted to be easier to read and edit into a
15 # Example ChangeLog format:
16 #2009-04-03 Joe Author <joe@example.net>
18 # * src/file.c, src/file.h,
20 # Some change description,
21 # spanning several lines.
22 # * foo.c: Combined line.
27 my $argc = $#ARGV + 1;
29 ($argc == 2) or die <<END;
31 $0 matchstring changelogfile >outfile
33 matchstring is not case sensitive.
36 my ($matchstr, $infile) = @ARGV;
39 or die "Couldn't open $infile for reading: $!\n";
41 my $entry; # the current matching block of text
42 my @entries; # changelog entries, one per date
44 # first parse each ChangeLog entry into an array
46 my $found = 0; # if we're in a matching block of text
47 my $blank = 0; # whether the last line was empty
50 my $line = $_; # read a line, including \n char
53 ($line =~ m/$matchstr/) and $found = 1;
55 if (length($line) <= 1) { # current line is empty
56 if ($blank > 0) { # previous line was also empty
57 push(@entries, $entry); # append entry
59 $found = 0; # now look for next match
74 foreach $entry (reverse @entries) {
75 my @lines = split(/\n/, $entry);
76 my $fl = 0; # in file list lines
77 my $cm = 0; # in commit message lines
79 foreach my $line (@lines){
82 # strip trailing space
86 # check if in filelist
87 ($line =~ m/ \* /) and $fl = 1;
88 # join filelist together on one line
89 $fl and ($line =~ s/^ / /);
90 if ($fl and ($line =~ m/:/)){
92 # separate ' * foo.c: Some edit.' messages:
93 if (!($line =~ m/:$/)) {
97 $fl and ($line =~ m/,$/) or $fl = 0;
100 # Asterisk commit messages
101 if (!$cm and ($line =~ m/^ /)){
103 $line =~ s/^( )/$1* /;
105 $cm and ($line =~ s/^( )/$1 /); # indent continuing lines
107 $cm and ($line =~ m/\.$/) and $cm = 0;
109 #~ print $fl.','.$cm.','.$line."\n"; next; # debug
111 # change file list start char to easily distinguish between file list and commit messages
112 $line =~ s/^ \* /@ /g;
113 # strip <email> from date line
114 $line =~ s/^([0-9-]+.*?)\s+<.+>$/$1/g;
120 (!$fl) and print "\n";