/usr/bin/grep-changelog.emacs24 is in emacs24-bin-common 24.5+1-6ubuntu1.
This file is owned by root:root, with mode 0o755.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 | #! /usr/bin/perl
# Copyright (C) 1999-2015 Free Software Foundation, Inc.
#
# This file is part of GNU Emacs.
# GNU Emacs 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 of the License, or
# (at your option) any later version.
# GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
# Extract entries from ChangeLogs matching specified criteria.
# Optionally format the resulting output to a form suitable for RCS
# logs, like they are used in Emacs, for example. In this format,
# author lines, leading spaces, and file names are removed.
require 5;
use strict;
# Parse command line options.
use vars qw($author $regexp $exclude $from_date $to_date
$rcs_log $with_date $version $help $reverse
@entries);
use Getopt::Long;
my $result;
if (@ARGV == 0) {
# No arguments cannot possibly mean "show everything"!!
$result = 0;
} else {
$result = GetOptions ("author=s" => \$author,
"text=s" => \$regexp,
"exclude=s" => \$exclude,
"from-date=s" => \$from_date,
"to-date=s" => \$to_date,
"rcs-log" => \$rcs_log,
"with-date" => \$with_date,
"reverse!" => \$reverse,
"version" => \$version,
"help" => \$help);
# If date options are specified, check that they have the format
# YYYY-MM-DD.
$result = 0 if $from_date && $from_date !~ /^\d\d\d\d-\d\d-\d\d$/;
$result = 0 if $to_date && $to_date !~ /^\d\d\d\d-\d\d-\d\d$/;
}
# Print usage information and exit when necessary.
if ($result == 0 || $help) {
print <<USAGE;
Usage: $0 [options] [CHANGELOG...]
Print entries in ChangeLogs matching various criteria.
Valid options are:
--author=AUTHOR Match entries whose author line matches
regular expression AUTHOR
--text=TEXT Match entries whose text matches regular
expression TEXT
--exclude=TEXT Exclude entries matching TEXT
--from-date=YYYY-MM-DD Match entries not older than given date
--to-date=YYYY-MM-DD Match entries not younger than given date
--rcs-log Format output suitable for RCS log entries
--with-date Print short date line in RCS log
--reverse Show entries in reverse (chronological) order
--version Print version info
--help Print this help
If no CHANGELOG is specified scan the files "ChangeLog" and
"ChangeLog.N+" in the current directory. Old-style dates in ChangeLogs
are not recognized.
USAGE
exit !$help;
}
# Print version info and exit if `--version' was specified.
if ($version) {
print "0.3\n";
exit 0;
}
# Value is non-zero if HEADER matches according to command line
# options specified, i.e. it matches $author, and its date is in
# the range $from_date <= date <= $to_date.
sub header_match_p {
my $header = shift;
return 0 unless $header;
# No match if AUTHOR-regexp specified and doesn't match.
return 0 if $author && $header !~ /$author/;
# Check that the date of the entry matches if date options
# `--from-date' and/or `--to-date' were specified . Old-style
# dates in ChangeLogs are not recognized, and never match.
if ($from_date || $to_date) {
if ($header =~ /^(\d\d\d\d-\d\d-\d\d)/) {
my $date = $1;
return 0 if $from_date && $date lt $from_date;
return 0 if $to_date && $date gt $to_date;
} else {
# Don't bother recognizing old-style dates.
return 0;
}
}
return 1;
}
# Value is non-zero if ENTRY matches the criteria specified on the
# command line, i.e. it matches $regexp, and it doesn't match
# $exclude.
sub entry_match_p {
my $entry = shift;
return 0 unless $entry;
if ($regexp) {
return 1 if ($entry =~ /$regexp/
&& (!$exclude || $entry !~ $exclude));
} else {
return 1 if !$exclude || $entry !~ $exclude;
}
return 0;
}
# Print HEADER and/or ENTRY in a format suitable for what was
# specified on the command line. If $rcs_log is specified, author
# lines are not printed, and leading spaces and file names are removed
# from ChangeLog entries.
sub print_log {
my ($header, $entry) = @_;
my $output = '';
if ($rcs_log) {
# Remove leading whitespace from entry.
$entry =~ s/^\s+//mg;
# Remove file name parts.
$entry =~ s/^\*.*\(/(/mg;
# Remove file name parts, 2.
$entry =~ s/^\*.*://mg;
if ($with_date) {
$header =~ /(\d\d\d\d-\d\d-\d\d)/;
$output = "!changelog-date $1\n";
}
$output .= $entry;
} else {
$output .= $header . $entry;
}
if ($reverse) {
push @entries, $output;
} else {
print $output;
}
}
# Scan LOG for matching entries, and print them to standard output.
sub parse_changelog {
my $log = shift;
my $entry = undef;
my $header = undef;
@entries = () if $reverse;
# Open the ChangeLog.
open (IN, "< $log") || die "Cannot open $log: $!";
while (defined(my $line = <IN>)) {
if ($line =~ /^\S/) {
# Line is an author-line. Print previous entry if
# it matches.
print_log ($header, $entry)
if header_match_p ($header) && entry_match_p ($entry);
$entry = "";
$header = $line;
# Add empty lines below the header.
while (defined($line = <IN>) && $line =~ /^\s*$/) {
$header = "$header$line";
}
}
last unless defined $line;
if ($line =~ /^\s*\*/) {
# LINE is the first line of a ChangeLog entry. Print
# previous entry if it matches.
print_log ($header, $entry)
if header_match_p ($header) && entry_match_p ($entry);
$entry = $line;
} else {
# Add LINE to the current entry.
$entry = "$entry$line";
}
}
# Print last entry if it matches.
print_log ($header, $entry)
if header_match_p ($header) && entry_match_p ($entry);
close IN;
if ($reverse) {
for (my $entry = @entries; $entry; $entry--) {
print $entries[$entry-1];
}
}
}
# Main program. Process ChangeLogs.
# If files were specified on the command line, parse those files in the
# order supplied by the user; otherwise parse default files ChangeLog and
# ChangeLog.NNN according to $reverse.
unless (@ARGV > 0) {
@ARGV = ("ChangeLog");
push @ARGV,
map {"ChangeLog.$_"}
sort {$b <=> $a}
map {/\.(\d+)$/; $1}
do {
opendir D, '.';
grep /^ChangeLog\.\d+$/, readdir D;
};
@ARGV = reverse @ARGV if $reverse;
}
while (defined (my $log = shift @ARGV)) {
parse_changelog ($log) if -f $log;
}
# grep-changelog ends here.
|