summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/cvs/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/cvs/contrib')
-rw-r--r--gnu/usr.bin/cvs/contrib/README23
-rw-r--r--gnu/usr.bin/cvs/contrib/cln_hist.pl5
-rw-r--r--gnu/usr.bin/cvs/contrib/commit_prep.pl176
-rw-r--r--gnu/usr.bin/cvs/contrib/cvs_acls.pl5
-rw-r--r--gnu/usr.bin/cvs/contrib/cvscheck.man2
-rw-r--r--gnu/usr.bin/cvs/contrib/cvshelp.man2
-rw-r--r--gnu/usr.bin/cvs/contrib/descend.man2
-rw-r--r--gnu/usr.bin/cvs/contrib/log.pl117
-rw-r--r--gnu/usr.bin/cvs/contrib/log_accum.pl489
-rw-r--r--gnu/usr.bin/cvs/contrib/mfpipe.pl5
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog106
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL29
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/README7
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el455
-rw-r--r--gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo2
-rw-r--r--gnu/usr.bin/cvs/contrib/rcslock.pl3
16 files changed, 1033 insertions, 395 deletions
diff --git a/gnu/usr.bin/cvs/contrib/README b/gnu/usr.bin/cvs/contrib/README
index 8d90180..e84b176 100644
--- a/gnu/usr.bin/cvs/contrib/README
+++ b/gnu/usr.bin/cvs/contrib/README
@@ -1,9 +1,9 @@
$CVSid: @(#)README 1.12 94/09/25 $
This "contrib" directory is a place holder for code/scripts sent to
-me by contributors around the world. This READM file will be kept
+me by contributors around the world. This README file will be kept
up-to-date from release to release. BUT, I must point out that these
-contributions are really, REALLY UNSSUPPORTED. In fact, I probably
+contributions are really, REALLY UNSUPPORTED. In fact, I probably
don't even know what they do. Nor do I guarantee to have tried them,
or ported them to work with this CVS distribution. If you have questions,
you might contact the author, but you should not necessarily expect
@@ -12,7 +12,7 @@ a reply. USE AT YOUR OWN RISK -- and all that stuff.
Contents of this directory:
README This file.
- log.pl A perl script suitable for including in your
+ log A perl script suitable for including in your
$CVSROOT/CVSROOT/loginfo file for logging commit
changes. Includes the RCS revision of the change
as part of the log.
@@ -20,15 +20,15 @@ Contents of this directory:
pcl-cvs A directory that contains GNU Emacs lisp code which
implements a CVS-mode for emacs.
Contributed by Per Cederqvist <ceder@lysator.liu.se>.
- commit_prep.pl A perl script, to be combined with log_accum.pl, to
- log_accum.pl provide for a way to combine the individual log
+ commit_prep A perl script, to be combined with log_accum.pl, to
+ log_accum provide for a way to combine the individual log
messages of a multi-directory "commit" into a
single log message, and mail the result somewhere.
- Also does other checks for $Id and that you are
+ Can also do other checks for $Id and that you are
committing the correct revision of the file.
Read the comments carefully.
Contributed by David Hampton <hampton@cisco.com>.
- mfpipe.pl Another perl script for logging. Allows you to
+ mfpipe Another perl script for logging. Allows you to
pipe the log message to a file and/or send mail
to some alias.
Contributed by John Clyne <clyne@niwot.scd.ucar.edu>.
@@ -46,12 +46,15 @@ Contents of this directory:
help your system support opendir/readdir/closedir,
if it does not already.
Copied from the C-News distribution.
- rcslock.pl A perl script that can be added to your commitinfo
+ rcslock A perl script that can be added to your commitinfo
file that tries to determine if your RCS file is
currently locked by someone else, as might be the
case for a binary file.
Contributed by John Rouillard <rouilj@cs.umb.edu>.
- cvs_acls.pl A perl script that implements Access Control Lists
+ ccvs-rsh A Perl script which allows "rsh pipelines" to
+ be built in order to use Cyclic CVS from
+ behind some varieties of firewall.
+ cvs_acls A perl script that implements Access Control Lists
by using the "commitinfo" hook provided with the
"cvs commit" command.
Contributed by David G. Grubbs <dgg@ksr.com>.
@@ -62,7 +65,7 @@ Contents of this directory:
the commands are recursive. However, this may still
come in handy.
Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
- cln_hist.pl A perl script to compress your
+ cln_hist A perl script to compress your
$CVSROOT/CVSROOT/history file, as it can grow quite
large after extended use.
Contributed by David G. Grubbs <dgg@ksr.com>
diff --git a/gnu/usr.bin/cvs/contrib/cln_hist.pl b/gnu/usr.bin/cvs/contrib/cln_hist.pl
index 534863d..ff49d0a 100644
--- a/gnu/usr.bin/cvs/contrib/cln_hist.pl
+++ b/gnu/usr.bin/cvs/contrib/cln_hist.pl
@@ -1,6 +1,7 @@
-#!/usr/bin/perl -- # -*-Perl-*-
+#! xPERL_PATHx
+# -*-Perl-*-
#
-# $Id: cln_hist.pl,v 1.1 1992/04/10 03:04:15 berliner Exp $
+# $Id: cln_hist.pl,v 1.2 1995/07/10 02:01:26 kfogel Exp $
# Contributed by David G. Grubbs <dgg@ksr.com>
#
# Clean up the history file. 10 Record types: MAR OFT WUCG
diff --git a/gnu/usr.bin/cvs/contrib/commit_prep.pl b/gnu/usr.bin/cvs/contrib/commit_prep.pl
index b3f7e9a..5272c04 100644
--- a/gnu/usr.bin/cvs/contrib/commit_prep.pl
+++ b/gnu/usr.bin/cvs/contrib/commit_prep.pl
@@ -1,9 +1,11 @@
-#!/usr/local/bin/perl -w
+#! xPERL_PATHx
+# -*-Perl-*-
#
+#ident "@(#)cvs/contrib:$Name: $:$Id: commit_prep.pl,v 1.2 1995/07/10 02:01:29 kfogel Exp $"
#
# Perl filter to handle pre-commit checking of files. This program
# records the last directory where commits will be taking place for
-# use by the log_accumulate script. For new file, it forcing the
+# use by the log_accum.pl script. For new files, it forces the
# existence of a RCS "Id" keyword in the first ten lines of the file.
# For existing files, it checks version number in the "Id" line to
# prevent losing changes because an old version of a file was copied
@@ -11,63 +13,62 @@
#
# Possible future enhancements:
#
-#
# Check for cruft left by unresolved conflicts. Search for
# "^<<<<<<<$", "^-------$", and "^>>>>>>>$".
#
# Look for a copyright and automagically update it to the
-# current year.
+# current year. [[ bad idea! -- woods ]]
+#
#
# Contributed by David Hampton <hampton@cisco.com>
#
+# Hacked on lots by Greg A. Woods <woods@web.net>
-############################################################
-#
-# Configurable options
#
-############################################################
-#
-# Check each file (except dot files) for an RCS "Id" keyword.
+# Configurable options
#
-$check_id = 1;
+# Constants (remember to protect strings from RCS keyword substitution)
#
-# Record the directory for later use by the log_accumulate stript.
-#
-$record_directory = 1;
+$LAST_FILE = "/tmp/#cvs.lastdir"; # must match name in log_accum.pl
+$ENTRIES = "CVS/Entries";
-############################################################
+# Patterns to find $Log keywords in files
#
-# Constants
-#
-############################################################
-$LAST_FILE = "/tmp/#cvs.lastdir";
-$ENTRIES = "CVS/Entries";
+$LogString1 = "\\\$\\Log: .* \\\$";
+$LogString2 = "\\\$\\Log\\\$";
+$NoLog = "%s - contains an RCS \$Log keyword. It must not!\n";
+# pattern to match an RCS Id keyword line with an existing ID
+#
+$IDstring = "\"@\\(#\\)[^:]*:.*\\\$\Id: .*\\\$\"";
$NoId = "
-%s - Does not contain a line with the keyword \"Id:\".
- Please see the template files for an example.\n";
+%s - Does not contain a properly formatted line with the keyword \"Id:\".
+ I.e. no lines match \"" . $IDstring . "\".
+ Please see the template files for an example.\n";
+
+# pattern to match an RCS Id keyword line for a new file (i.e. un-expanded)
+#
+$NewId = "\"@(#)[^:]*:.*\\$\Id\\$\"";
-# Protect string from substitution by RCS.
$NoName = "
-%s - The ID line should contain only \"\$\I\d\:\ \$\" for a newly created file.\n";
+%s - The ID line should contain only \"@(#)module/path:\$Name\$:\$\Id\$\"
+ for a newly created file.\n";
$BadName = "
%s - The file name '%s' in the ID line does not match
- the actual filename.\n";
+ the actual filename.\n";
$BadVersion = "
-%s - How dare you!! You replaced your copy of the file '%s',
- which was based upon version %s, with an %s version based
- upon %s. Please move your '%s' out of the way, perform an
- update to get the current version, and them merge your changes
- into that file.\n";
+%s - How dare you!!! You replaced your copy of the file '%s',
+ which was based upon version %s, with an %s version based
+ upon %s. Please move your '%s' out of the way, perform an
+ update to get the current version, and them merge your changes
+ into that file, then try the commit again.\n";
-############################################################
#
-# Subroutines
+# Subroutines
#
-############################################################
sub write_line {
local($filename, $line) = @_;
@@ -80,58 +81,107 @@ sub check_version {
local($i, $id, $rname, $version);
local($filename, $cvsversion) = @_;
- open(FILE, $filename) || die("Cannot open $filename, stopped");
- for ($i = 1; $i < 10; $i++) {
- $pos = -1;
- last if eof(FILE);
- $line = <FILE>;
- $pos = index($line, "Id: ");
- last if ($pos >= 0);
+ open(FILE, "<$filename") || return(0);
+
+ @all_lines = ();
+ $idpos = -1;
+ $newidpos = -1;
+ for ($i = 0; <FILE>; $i++) {
+ chop;
+ push(@all_lines, $_);
+ if ($_ =~ /$IDstring/) {
+ $idpos = $i;
+ }
+ if ($_ =~ /$NewId/) {
+ $newidpos = $i;
+ }
}
- if ($pos == -1) {
- printf($NoId, $filename);
+ if (grep(/$LogString1/, @all_lines) || grep(/$LogString2/, @all_lines)) {
+ print STDERR sprintf($NoLog, $filename);
return(1);
}
- ($id, $rname, $version) = split(' ', substr($line, $pos));
+ if ($debug != 0) {
+ print STDERR sprintf("file = %s, version = %d.\n", $filename, $cvsversion{$filename});
+ }
+
if ($cvsversion{$filename} == 0) {
- if ($rname ne "\$") {
- printf($NoName, $filename);
+ if ($newidpos != -1 && $all_lines[$newidpos] !~ /$NewId/) {
+ print STDERR sprintf($NoName, $filename);
return(1);
}
return(0);
}
+ if ($idpos == -1) {
+ print STDERR sprintf($NoId, $filename);
+ return(1);
+ }
+
+ $line = $all_lines[$idpos];
+ $pos = index($line, "Id: ");
+ if ($debug != 0) {
+ print STDERR sprintf("%d in '%s'.\n", $pos, $line);
+ }
+ ($id, $rname, $version) = split(' ', substr($line, $pos));
if ($rname ne "$filename,v") {
- printf($BadName, $filename, substr($rname, 0, length($rname)-2));
+ print STDERR sprintf($BadName, $filename, substr($rname, 0, length($rname)-2));
return(1);
}
if ($cvsversion{$filename} < $version) {
- printf($BadVersion, $filename, $filename, $cvsversion{$filename},
- "newer", $version, $filename);
+ print STDERR sprintf($BadVersion, $filename, $filename, $cvsversion{$filename},
+ "newer", $version, $filename);
return(1);
}
if ($cvsversion{$filename} > $version) {
- printf($BadVersion, $filename, $filename, $cvsversion{$filename},
- "older", $version, $filename);
+ print STDERR sprintf($BadVersion, $filename, $filename, $cvsversion{$filename},
+ "older", $version, $filename);
return(1);
}
return(0);
}
-#############################################################
#
-# Main Body
+# Main Body
+#
+
+$id = getpgrp(); # You *must* use a shell that does setpgrp()!
+
+# Check each file (except dot files) for an RCS "Id" keyword.
#
-############################################################
+$check_id = 0;
-$id = getpgrp();
-#print("ARGV - ", join(":", @ARGV), "\n");
-#print("id - ", id, "\n");
+# Record the directory for later use by the log_accumulate stript.
+#
+$record_directory = 0;
+# parse command line arguments
#
-# Suck in the Entries file
+while (@ARGV) {
+ $arg = shift @ARGV;
+
+ if ($arg eq '-d') {
+ $debug = 1;
+ print STDERR "Debug turned on...\n";
+ } elsif ($arg eq '-c') {
+ $check_id = 1;
+ } elsif ($arg eq '-r') {
+ $record_directory = 1;
+ } else {
+ push(@files, $arg);
+ }
+}
+
+$directory = shift @files;
+
+if ($debug != 0) {
+ print STDERR "dir - ", $directory, "\n";
+ print STDERR "files - ", join(":", @files), "\n";
+ print STDERR "id - ", $id, "\n";
+}
+
+# Suck in the CVS/Entries file
#
open(ENTRIES, $ENTRIES) || die("Cannot open $ENTRIES.\n");
while (<ENTRIES>) {
@@ -139,25 +189,23 @@ while (<ENTRIES>) {
$cvsversion{$filename} = $version;
}
-#
# Now check each file name passed in, except for dot files. Dot files
# are considered to be administrative files by this script.
#
if ($check_id != 0) {
$failed = 0;
- $directory = $ARGV[0];
- shift @ARGV;
- foreach $arg (@ARGV) {
- next if (index($arg, ".") == 0);
+ foreach $arg (@files) {
+ if (index($arg, ".") == 0) {
+ next;
+ }
$failed += &check_version($arg);
}
if ($failed) {
- print "\n";
+ print STDERR "\n";
exit(1);
}
}
-#
# Record this directory as the last one checked. This will be used
# by the log_accumulate script to determine when it is processing
# the final directory of a multi-directory commit.
diff --git a/gnu/usr.bin/cvs/contrib/cvs_acls.pl b/gnu/usr.bin/cvs/contrib/cvs_acls.pl
index 2a3b0d9..bcb544d 100644
--- a/gnu/usr.bin/cvs/contrib/cvs_acls.pl
+++ b/gnu/usr.bin/cvs/contrib/cvs_acls.pl
@@ -1,6 +1,7 @@
-#!/usr/bin/perl -- # -*-Perl-*-
+#! xPERL_PATHx
+# -*-Perl-*-
#
-# $Id: cvs_acls.pl,v 1.2 1992/04/11 16:01:24 berliner Exp $
+# $Id: cvs_acls.pl,v 1.2 1995/07/10 02:01:33 kfogel Exp $
#
# Access control lists for CVS. dgg@ksr.com (David G. Grubbs)
#
diff --git a/gnu/usr.bin/cvs/contrib/cvscheck.man b/gnu/usr.bin/cvs/contrib/cvscheck.man
index 84d7db7..61a064a 100644
--- a/gnu/usr.bin/cvs/contrib/cvscheck.man
+++ b/gnu/usr.bin/cvs/contrib/cvscheck.man
@@ -1,4 +1,4 @@
-.\" $Id: cvscheck.man,v 1.1 1992/04/10 03:04:20 berliner Exp $
+.\" $Id: cvscheck.man,v 1.1.1.3 1995/08/28 16:20:24 jimb Exp $
.\" Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
.TH CVSCHECK LOCAL "4 March 1991" FLUKE
.SH NAME
diff --git a/gnu/usr.bin/cvs/contrib/cvshelp.man b/gnu/usr.bin/cvs/contrib/cvshelp.man
index ba6590a..2cfae1f 100644
--- a/gnu/usr.bin/cvs/contrib/cvshelp.man
+++ b/gnu/usr.bin/cvs/contrib/cvshelp.man
@@ -1,4 +1,4 @@
-.\" $Id: cvshelp.man,v 1.1 1992/04/10 03:04:21 berliner Exp $
+.\" $Id: cvshelp.man,v 1.1.1.3 1995/08/28 16:20:28 jimb Exp $
.\" Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
.\" Full space in nroff; half space in troff
.de SP
diff --git a/gnu/usr.bin/cvs/contrib/descend.man b/gnu/usr.bin/cvs/contrib/descend.man
index a38d4ca..5ac46f4 100644
--- a/gnu/usr.bin/cvs/contrib/descend.man
+++ b/gnu/usr.bin/cvs/contrib/descend.man
@@ -1,4 +1,4 @@
-.\" $Id: descend.man,v 1.1 1992/04/03 05:22:53 berliner Exp $
+.\" $Id: descend.man,v 1.1.1.3 1995/08/28 16:20:31 jimb Exp $
.TH DESCEND 1 "31 March 1992"
.SH NAME
descend \- walk directory tree and execute a command at each node
diff --git a/gnu/usr.bin/cvs/contrib/log.pl b/gnu/usr.bin/cvs/contrib/log.pl
index d68cc82..5e3bf48 100644
--- a/gnu/usr.bin/cvs/contrib/log.pl
+++ b/gnu/usr.bin/cvs/contrib/log.pl
@@ -1,25 +1,31 @@
-#! /local/bin/perl
-
-# Modified by woods@web.apc.org to add support for mailing 3/29/93
-# use '-m user' for each user to receive cvs log reports
-# and use '-f logfile' for the logfile to append to
+#! xPERL_PATHx
+# -*-Perl-*-
+#
+#ident "$CVSid$"
#
-# Modified by berliner@Sun.COM to add support for CVS 1.3 2/27/92
+# XXX: FIXME: handle multiple '-f logfile' arguments
#
-# Date: Tue, 6 Aug 91 13:27 EDT
-# From: samborn@sunrise.com (Kevin Samborn)
+# XXX -- I HATE Perl! This *will* be re-written in shell/awk/sed soon!
#
-# I revised the perl script I sent you yesterday to use the info you
-# send in on stdin. (I am appending the newer script to the end)
+
+# Usage: log.pl [[-m user] ...] [-s] -f logfile 'dirname file ...'
+#
+# -m user - for each user to receive cvs log reports
+# (multiple -m's permitted)
+# -s - to prevent "cvs status -v" messages
+# -f logfile - for the logfile to append to (mandatory,
+# but only one logfile can be specified).
+
+# here is what the output looks like:
#
-# now the output looks like this:
+# From: woods@kuma.domain.top
+# Subject: CVS update: testmodule
#
-# **************************************
-# Date: Tuesday, August 6, 1991 @ 13:17
-# Author: samborn
+# Date: Wednesday November 23, 1994 @ 14:15
+# Author: woods
#
-# Update of /elmer/cvs/CVSROOT.adm
-# In directory astro:/home/samborn/CVSROOT.adm
+# Update of /local/src-CVS/testmodule
+# In directory kuma:/home/kuma/woods/work.d/testmodule
#
# Modified Files:
# test3
@@ -28,15 +34,24 @@
# Removed Files:
# test4
# Log Message:
-# wow, what a test
-#
-# File: test.3 Status: Up-to-date
-# Version: 1.4 Thu Apr 29 14:47:07 EDT 1993
-# File: test6 Status: Up-to-date
-# Version: 1.1 Thu Apr 29 14:47:33 EDT 1993
-# File: test4 Status: Up-to-date
-# Version: 1.1 Thu Apr 29 14:47:46 EDT 1993
+# - wow, what a test
+#
+# (and for each file the "cvs status -v" output is appended unless -s is used)
#
+# ==================================================================
+# File: test3 Status: Up-to-date
+#
+# Working revision: 1.41 Wed Nov 23 14:15:59 1994
+# Repository revision: 1.41 /local/src-CVS/cvs/testmodule/test3,v
+# Sticky Options: -ko
+#
+# Existing Tags:
+# local-v2 (revision: 1.7)
+# local-v1 (revision: 1.1.1.2)
+# CVS-1_4A2 (revision: 1.1.1.2)
+# local-v0 (revision: 1.2)
+# CVS-1_4A1 (revision: 1.1.1.1)
+# CVS (branch: 1.1.1)
$cvsroot = $ENV{'CVSROOT'};
@@ -44,6 +59,8 @@ $cvsroot = $ENV{'CVSROOT'};
#
$) = $(;
+$dostatus = 1;
+
# parse command line arguments
#
while (@ARGV) {
@@ -54,6 +71,8 @@ while (@ARGV) {
} elsif ($arg eq '-f') {
($logfile) && die "Too many '-f' args";
$logfile = shift @ARGV;
+ } elsif ($arg eq '-s') {
+ $dostatus = 0;
} else {
($donefiles) && die "Too many arguments!\n";
$donefiles = 1;
@@ -61,10 +80,13 @@ while (@ARGV) {
}
}
-$srepos = shift @files;
-$mailcmd = "| Mail -s 'CVS update: $srepos'";
+# the first argument is the module location relative to $CVSROOT
+#
+$modulepath = shift @files;
+
+$mailcmd = "| Mail -s 'CVS update: $modulepath'";
-# Some date and time arrays
+# Initialise some date and time arrays
#
@mos = (January,February,March,April,May,June,July,August,September,
October,November,December);
@@ -72,13 +94,16 @@ $mailcmd = "| Mail -s 'CVS update: $srepos'";
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
-# get login name
+# get a login name for the guy doing the commit....
#
$login = getlogin || (getpwuid($<))[0] || "nobody";
# open log file for appending
#
open(OUT, ">>" . $logfile) || die "Could not open(" . $logfile . "): $!\n";
+
+# send mail, if there's anyone to send to!
+#
if ($users) {
$mailcmd = "$mailcmd $users";
open(MAIL, $mailcmd) || die "Could not Exec($mailcmd): $!\n";
@@ -87,7 +112,7 @@ if ($users) {
# print out the log Header
#
print OUT "\n";
-print OUT "**************************************\n";
+print OUT "****************************************\n";
print OUT "Date:\t$days[$wday] $mos[$mon] $mday, 19$year @ $hour:" . sprintf("%02d", $min) . "\n";
print OUT "Author:\t$login\n\n";
@@ -110,29 +135,27 @@ close(IN);
print OUT "\n";
-# after log information, do an 'cvs -Qn status' on each file in the arguments.
+# after log information, do an 'cvs -Qq status -v' on each file in the arguments.
#
-while (@files) {
- $file = shift @files;
- if ($file eq "-") {
- print OUT "[input file was '-']\n";
- if (MAIL) {
- print MAIL "[input file was '-']\n";
+if ($dostatus != 0) {
+ while (@files) {
+ $file = shift @files;
+ if ($file eq "-") {
+ print OUT "[input file was '-']\n";
+ if (MAIL) {
+ print MAIL "[input file was '-']\n";
+ }
+ last;
}
- last;
- }
-
- open(RCS, "-|") || exec 'cvs', '-Qn', 'status', $file;
-
- while (<RCS>) {
- if (/^[ \t]*Version/ || /^File:/) {
+ open(RCS, "-|") || exec 'cvs', '-nQq', 'status', '-v', $file;
+ while (<RCS>) {
print OUT;
if (MAIL) {
print MAIL;
}
}
+ close(RCS);
}
- close(RCS);
}
close(OUT);
@@ -141,8 +164,6 @@ die "Write to $logfile failed" if $?;
close(MAIL);
die "Pipe to $mailcmd failed" if $?;
+## must exit cleanly
+##
exit 0;
-
-### Local Variables:
-### eval: (fundamental-mode)
-### End:
diff --git a/gnu/usr.bin/cvs/contrib/log_accum.pl b/gnu/usr.bin/cvs/contrib/log_accum.pl
index 798e25f..b47f433 100644
--- a/gnu/usr.bin/cvs/contrib/log_accum.pl
+++ b/gnu/usr.bin/cvs/contrib/log_accum.pl
@@ -1,4 +1,5 @@
-#!/usr/local/bin/perl -w
+#! xPERL_PATHx
+# -*-Perl-*-
#
# Perl filter to handle the log messages from the checkin of files in
# a directory. This script will group the lists of files by log
@@ -10,27 +11,27 @@
#
# Contributed by David Hampton <hampton@cisco.com>
#
+# hacked greatly by Greg A. Woods <woods@planix.com>
+
+# Usage: log_accum.pl [-d] [-s] [-M module] [[-m mailto] ...] [-f logfile]
+# -d - turn on debugging
+# -m mailto - send mail to "mailto" (multiple)
+# -M modulename - set module name to "modulename"
+# -f logfile - write commit messages to logfile too
+# -s - *don't* run "cvs status -v" for each file
-############################################################
-#
-# Configurable options
-#
-############################################################
#
-# Do cisco Systems, Inc. specific nonsense.
+# Configurable options
#
-$cisco_systems = 1;
+
+$MAILER = "Mail"; # set this to something that takes "-s"
#
-# Recipient of all mail messages
+# End user configurable options.
#
-$mailto = "sw-notification@cisco.com";
-############################################################
-#
-# Constants
+# Constants (don't change these!)
#
-############################################################
$STATE_NONE = 0;
$STATE_CHANGED = 1;
$STATE_ADDED = 2;
@@ -38,82 +39,113 @@ $STATE_REMOVED = 3;
$STATE_LOG = 4;
$LAST_FILE = "/tmp/#cvs.lastdir";
+
$CHANGED_FILE = "/tmp/#cvs.files.changed";
$ADDED_FILE = "/tmp/#cvs.files.added";
$REMOVED_FILE = "/tmp/#cvs.files.removed";
$LOG_FILE = "/tmp/#cvs.files.log";
-$FILE_PREFIX = "#cvs.files";
-$VERSION_FILE = "version";
-$TRUNKREV_FILE = "TrunkRev";
-$CHANGES_FILE = "Changes";
-$CHANGES_TEMP = "Changes.tmp";
+$FILE_PREFIX = "#cvs.files";
-############################################################
#
-# Subroutines
+# Subroutines
#
-############################################################
-
-sub format_names {
- local($dir, @files) = @_;
- local(@lines);
- $lines[0] = sprintf(" %-08s", $dir);
- foreach $file (@files) {
- if (length($lines[$#lines]) + length($file) > 60) {
- $lines[++$#lines] = sprintf(" %8s", " ");
- }
- $lines[$#lines] .= " ".$file;
- }
- @lines;
-}
sub cleanup_tmpfiles {
- local($all) = @_;
local($wd, @files);
$wd = `pwd`;
- chdir("/tmp");
+ chdir("/tmp") || die("Can't chdir('/tmp')\n");
opendir(DIR, ".");
- if ($all == 1) {
- push(@files, grep(/$id$/, readdir(DIR)));
- } else {
- push(@files, grep(/^$FILE_PREFIX.*$id$/, readdir(DIR)));
- }
+ push(@files, grep(/^$FILE_PREFIX\..*\.$id$/, readdir(DIR)));
closedir(DIR);
foreach (@files) {
unlink $_;
}
+ unlink $LAST_FILE . "." . $id;
+
chdir($wd);
}
sub write_logfile {
local($filename, @lines) = @_;
- open(FILE, ">$filename") || die ("Cannot open log file $filename.\n");
- print(FILE join("\n", @lines), "\n");
+
+ open(FILE, ">$filename") || die("Cannot open log file $filename.\n");
+ print FILE join("\n", @lines), "\n";
+ close(FILE);
+}
+
+sub append_to_logfile {
+ local($filename, @lines) = @_;
+
+ open(FILE, ">$filename") || die("Cannot open log file $filename.\n");
+ print FILE join("\n", @lines), "\n";
close(FILE);
}
-sub append_to_file {
+sub format_names {
+ local($dir, @files) = @_;
+ local(@lines);
+
+ $format = "\t%-" . sprintf("%d", length($dir)) . "s%s ";
+
+ $lines[0] = sprintf($format, $dir, ":");
+
+ if ($debug) {
+ print STDERR "format_names(): dir = ", $dir, "; files = ", join(":", @files), ".\n";
+ }
+ foreach $file (@files) {
+ if (length($lines[$#lines]) + length($file) > 65) {
+ $lines[++$#lines] = sprintf($format, " ", " ");
+ }
+ $lines[$#lines] .= $file . " ";
+ }
+
+ @lines;
+}
+
+sub format_lists {
+ local(@lines) = @_;
+ local(@text, @files, $lastdir);
+
+ if ($debug) {
+ print STDERR "format_lists(): ", join(":", @lines), "\n";
+ }
+ @text = ();
+ @files = ();
+ $lastdir = shift @lines; # first thing is always a directory
+ if ($lastdir !~ /.*\/$/) {
+ die("Damn, $lastdir doesn't look like a directory!\n");
+ }
+ foreach $line (@lines) {
+ if ($line =~ /.*\/$/) {
+ push(@text, &format_names($lastdir, @files));
+ $lastdir = $line;
+ @files = ();
+ } else {
+ push(@files, $line);
+ }
+ }
+ push(@text, &format_names($lastdir, @files));
+
+ @text;
+}
+
+sub append_names_to_file {
local($filename, $dir, @files) = @_;
+
if (@files) {
- local(@lines) = &format_names($dir, @files);
- open(FILE, ">>$filename") || die ("Cannot open file $filename.\n");
- print(FILE join("\n", @lines), "\n");
+ open(FILE, ">>$filename") || die("Cannot open file $filename.\n");
+ print FILE $dir, "\n";
+ print FILE join("\n", @files), "\n";
close(FILE);
}
}
-sub write_line {
- local($filename, $line) = @_;
- open(FILE, ">$filename") || die("Cannot open file $filename.\n");
- print(FILE $line, "\n");
- close(FILE);
-}
-
sub read_line {
local($line);
local($filename) = @_;
+
open(FILE, "<$filename") || die("Cannot open file $filename.\n");
$line = <FILE>;
close(FILE);
@@ -121,23 +153,11 @@ sub read_line {
$line;
}
-sub read_file {
- local(@text);
- local($filename, $leader) = @_;
- open(FILE, "<$filename") || return ();
- while (<FILE>) {
- chop;
- push(@text, sprintf(" %-10s %s", $leader, $_));
- $leader = "";
- }
- close(FILE);
- @text;
-}
-
sub read_logfile {
local(@text);
local($filename, $leader) = @_;
- open(FILE, "<$filename") || die ("Cannot open log file $filename.\n");
+
+ open(FILE, "<$filename");
while (<FILE>) {
chop;
push(@text, $leader.$_);
@@ -146,110 +166,179 @@ sub read_logfile {
@text;
}
-sub bump_version {
- local($trunkrev, $editnum, $version);
-
- $trunkrev = &read_line("$ENV{'CVSROOT'}/$repository/$TRUNKREV_FILE");
- $editnum = &read_line("$ENV{'CVSROOT'}/$repository/$VERSION_FILE");
- &write_line("$ENV{'CVSROOT'}/$repository/$VERSION_FILE", $editnum+1);
- $version = $trunkrev . "(" . $editnum . ")";
-}
-
sub build_header {
- local($version) = @_;
local($header);
local($sec,$min,$hour,$mday,$mon,$year) = localtime(time);
- $header = sprintf("%-8s %s %02d/%02d/%02d %02d:%02d:%02d",
- $login, $version, $year%100, $mon+1, $mday,
- $hour, $min, $sec);
-}
-
-sub do_changes_file {
- local($changes, $tmpchanges);
- local(@text) = @_;
-
- $changes = "$ENV{'CVSROOT'}/$repository/$CHANGES_FILE";
- $tmpchanges = "$ENV{'CVSROOT'}/$repository/$CHANGES_TEMP";
- if (rename($changes, $tmpchanges) != 1) {
- die("Cannot rename $changes to $tmpchanges.\n");
- }
- open(CHANGES, ">$changes") || die("Cannot open $changes.\n");
- open(TMPCHANGES, "<$tmpchanges") || die("Cannot open $tmpchanges.\n");
- print(CHANGES join("\n", @text), "\n\n");
- print(CHANGES <TMPCHANGES>);
- close(CHANGES);
- close(TMPCHANGES);
- unlink($tmpchanges);
+ $header = sprintf("CVSROOT:\t%s\nModule name:\t%s\nChanges by:\t%s@%s\t%02d/%02d/%02d %02d:%02d:%02d",
+ $cvsroot,
+ $modulename,
+ $login, $hostdomain,
+ $year%100, $mon+1, $mday,
+ $hour, $min, $sec);
}
sub mail_notification {
local($name, @text) = @_;
- open(MAIL, "| mail -s \"Source Repository Modification\" $name");
- print(MAIL join("\n", @text));
+ open(MAIL, "| $MAILER -s \"CVS Update: " . $modulename . "\" " . $name);
+ print MAIL join("\n", @text), "\n";
close(MAIL);
}
-#############################################################
+sub write_commitlog {
+ local($logfile, @text) = @_;
+
+ open(FILE, ">>$logfile");
+ print FILE join("\n", @text), "\n";
+ close(FILE);
+}
+
#
-# Main Body
+# Main Body
#
-############################################################
-#
# Initialize basic variables
#
-$id = getpgrp();
+$debug = 0;
+$id = getpgrp(); # note, you *must* use a shell which does setpgrp()
$state = $STATE_NONE;
-$login = getlogin || (getpwuid($<))[0] || die("Unknown user $<.\n");
-@files = split(' ', $ARGV[0]);
+$login = getlogin || (getpwuid($<))[0] || "nobody";
+chop($hostname = `hostname`);
+chop($domainname = `domainname`);
+$hostdomain = $hostname . $domainname;
+$cvsroot = $ENV{'CVSROOT'};
+$do_status = 1;
+$modulename = "";
+
+# parse command line arguments (file list is seen as one arg)
+#
+while (@ARGV) {
+ $arg = shift @ARGV;
+
+ if ($arg eq '-d') {
+ $debug = 1;
+ print STDERR "Debug turned on...\n";
+ } elsif ($arg eq '-m') {
+ $mailto = "$mailto " . shift @ARGV;
+ } elsif ($arg eq '-M') {
+ $modulename = shift @ARGV;
+ } elsif ($arg eq '-s') {
+ $do_status = 0;
+ } elsif ($arg eq '-f') {
+ ($commitlog) && die("Too many '-f' args\n");
+ $commitlog = shift @ARGV;
+ } else {
+ ($donefiles) && die("Too many arguments! Check usage.\n");
+ $donefiles = 1;
+ @files = split(/ /, $arg);
+ }
+}
+($mailto) || die("No -m mail recipient specified\n");
+
+# for now, the first "file" is the repository directory being committed,
+# relative to the $CVSROOT location
+#
@path = split('/', $files[0]);
-$repository = @path[0];
+
+# XXX there are some ugly assumptions in here about module names and
+# XXX directories relative to the $CVSROOT location -- really should
+# XXX read $CVSROOT/CVSROOT/modules, but that's not so easy to do, since
+# XXX we have to parse it backwards.
+#
+if ($modulename eq "") {
+ $modulename = $path[0]; # I.e. the module name == top-level dir
+}
if ($#path == 0) {
$dir = ".";
} else {
- $dir = join('/', @path[1..$#path]);
+ $dir = join('/', @path);
}
-#print("ARGV - ", join(":", @ARGV), "\n");
-#print("files - ", join(":", @files), "\n");
-#print("path - ", join(":", @path), "\n");
-#print("dir - ", $dir, "\n");
-#print("id - ", $id, "\n");
+$dir = $dir . "/";
+if ($debug) {
+ print STDERR "module - ", $modulename, "\n";
+ print STDERR "dir - ", $dir, "\n";
+ print STDERR "path - ", join(":", @path), "\n";
+ print STDERR "files - ", join(":", @files), "\n";
+ print STDERR "id - ", $id, "\n";
+}
+
+# Check for a new directory first. This appears with files set as follows:
#
-# Check for a new directory first. This will always appear as a
-# single item in the argument list, and an empty log message.
+# files[0] - "path/name/newdir"
+# files[1] - "-"
+# files[2] - "New"
+# files[3] - "directory"
#
-if ($ARGV[0] =~ /New directory/) {
- $version = &bump_version if ($cisco_systems != 0);
- $header = &build_header($version);
+if ($files[2] =~ /New/ && $files[3] =~ /directory/) {
+ local(@text);
+
@text = ();
- push(@text, $header);
+ push(@text, &build_header());
+ push(@text, "");
+ push(@text, $files[0]);
push(@text, "");
- push(@text, " ".$ARGV[0]);
- &do_changes_file(@text) if ($cisco_systems != 0);
+
+ while (<STDIN>) {
+ chop; # Drop the newline
+ push(@text, $_);
+ }
+
&mail_notification($mailto, @text);
+
exit 0;
}
+# Check for an import command. This appears with files set as follows:
+#
+# files[0] - "path/name"
+# files[1] - "-"
+# files[2] - "Imported"
+# files[3] - "sources"
#
+if ($files[2] =~ /Imported/ && $files[3] =~ /sources/) {
+ local(@text);
+
+ @text = ();
+ push(@text, &build_header());
+ push(@text, "");
+ push(@text, $files[0]);
+ push(@text, "");
+
+ while (<STDIN>) {
+ chop; # Drop the newline
+ push(@text, $_);
+ }
+
+ &mail_notification($mailto, @text);
+
+ exit 0;
+}
+
# Iterate over the body of the message collecting information.
#
while (<STDIN>) {
chop; # Drop the newline
+
+ if (/^In directory/) {
+ push(@log_lines, $_);
+ push(@log_lines, "");
+ next;
+ }
+
if (/^Modified Files/) { $state = $STATE_CHANGED; next; }
if (/^Added Files/) { $state = $STATE_ADDED; next; }
if (/^Removed Files/) { $state = $STATE_REMOVED; next; }
if (/^Log Message/) { $state = $STATE_LOG; next; }
- s/^[ \t\n]+//; # delete leading space
- s/[ \t\n]+$//; # delete trailing space
+
+ s/^[ \t\n]+//; # delete leading whitespace
+ s/[ \t\n]+$//; # delete trailing whitespace
- push (@changed_files, split) if ($state == $STATE_CHANGED);
- push (@added_files, split) if ($state == $STATE_ADDED);
- push (@removed_files, split) if ($state == $STATE_REMOVED);
- push (@log_lines, $_) if ($state == $STATE_LOG);
+ if ($state == $STATE_CHANGED) { push(@changed_files, split); }
+ if ($state == $STATE_ADDED) { push(@added_files, split); }
+ if ($state == $STATE_REMOVED) { push(@removed_files, split); }
+ if ($state == $STATE_LOG) { push(@log_lines, $_); }
}
-#
# Strip leading and trailing blank lines from the log message. Also
# compress multiple blank lines in the body of the message down to a
# single blank line.
@@ -268,64 +357,140 @@ for ($i = $#log_lines; $i > 0; $i--) {
}
}
-#
-# Find the log file that matches this log message
+if ($debug) {
+ print STDERR "Searching for log file index...";
+}
+# Find an index to a log file that matches this log message
#
for ($i = 0; ; $i++) {
- last if (! -e "$LOG_FILE.$i.$id");
+ local(@text);
+
+ last if (! -e "$LOG_FILE.$i.$id"); # the next available one
@text = &read_logfile("$LOG_FILE.$i.$id", "");
- last if ($#text == -1);
- last if (join(" ", @log_lines) eq join(" ", @text));
+ last if ($#text == -1); # nothing in this file, use it
+ last if (join(" ", @log_lines) eq join(" ", @text)); # it's the same log message as another
+}
+if ($debug) {
+ print STDERR " found log file at $i.$id, now writing tmp files.\n";
}
-#
# Spit out the information gathered in this pass.
#
+&append_names_to_file("$CHANGED_FILE.$i.$id", $dir, @changed_files);
+&append_names_to_file("$ADDED_FILE.$i.$id", $dir, @added_files);
+&append_names_to_file("$REMOVED_FILE.$i.$id", $dir, @removed_files);
&write_logfile("$LOG_FILE.$i.$id", @log_lines);
-&append_to_file("$ADDED_FILE.$i.$id", $dir, @added_files);
-&append_to_file("$CHANGED_FILE.$i.$id", $dir, @changed_files);
-&append_to_file("$REMOVED_FILE.$i.$id", $dir, @removed_files);
-#
# Check whether this is the last directory. If not, quit.
#
+if ($debug) {
+ print STDERR "Checking current dir against last dir.\n";
+}
$_ = &read_line("$LAST_FILE.$id");
-exit 0 if (! grep(/$files[0]$/, $_));
+if ($_ ne $cvsroot . "/" . $files[0]) {
+ if ($debug) {
+ print STDERR sprintf("Current directory %s is not last directory %s.\n", $cvsroot . "/" .$files[0], $_);
+ }
+ exit 0;
+}
+if ($debug) {
+ print STDERR sprintf("Current directory %s is last directory %s -- all commits done.\n", $files[0], $_);
+}
+
+#
+# End Of Commits!
#
+
# This is it. The commits are all finished. Lump everything together
# into a single message, fire a copy off to the mailing list, and drop
# it on the end of the Changes file.
#
-# Get the full version number
-#
-$version = &bump_version if ($cisco_systems != 0);
-$header = &build_header($version);
#
# Produce the final compilation of the log messages
#
@text = ();
-push(@text, $header);
+@status_txt = ();
+push(@text, &build_header());
push(@text, "");
+
for ($i = 0; ; $i++) {
- last if (! -e "$LOG_FILE.$i.$id");
- push(@text, &read_file("$CHANGED_FILE.$i.$id", "Modified:"));
- push(@text, &read_file("$ADDED_FILE.$i.$id", "Added:"));
- push(@text, &read_file("$REMOVED_FILE.$i.$id", "Removed:"));
- push(@text, " Log:");
- push(@text, &read_logfile("$LOG_FILE.$i.$id", " "));
- push(@text, "");
-}
-if ($cisco_systems != 0) {
- @ddts = grep(/^CSCdi/, split(' ', join(" ", @text)));
- $text[0] .= " " . join(" ", @ddts);
+ last if (! -e "$LOG_FILE.$i.$id"); # we're done them all!
+ @lines = &read_logfile("$CHANGED_FILE.$i.$id", "");
+ if ($#lines >= 0) {
+ push(@text, "Modified files:");
+ push(@text, &format_lists(@lines));
+ }
+ @lines = &read_logfile("$ADDED_FILE.$i.$id", "");
+ if ($#lines >= 0) {
+ push(@text, "Added files:");
+ push(@text, &format_lists(@lines));
+ }
+ @lines = &read_logfile("$REMOVED_FILE.$i.$id", "");
+ if ($#lines >= 0) {
+ push(@text, "Removed files:");
+ push(@text, &format_lists(@lines));
+ }
+ if ($#text >= 0) {
+ push(@text, "");
+ }
+ @lines = &read_logfile("$LOG_FILE.$i.$id", "\t");
+ if ($#lines >= 0) {
+ push(@text, "Log message:");
+ push(@text, @lines);
+ push(@text, "");
+ }
+ if ($do_status) {
+ local(@changed_files);
+
+ @changed_files = ();
+ push(@changed_files, &read_logfile("$CHANGED_FILE.$i.$id", ""));
+ push(@changed_files, &read_logfile("$ADDED_FILE.$i.$id", ""));
+ push(@changed_files, &read_logfile("$REMOVED_FILE.$i.$id", ""));
+
+ if ($debug) {
+ print STDERR "main: pre-sort changed_files = ", join(":", @changed_files), ".\n";
+ }
+ sort(@changed_files);
+ if ($debug) {
+ print STDERR "main: post-sort changed_files = ", join(":", @changed_files), ".\n";
+ }
+
+ foreach $dofile (@changed_files) {
+ if ($dofile =~ /\/$/) {
+ next; # ignore the silly "dir" entries
+ }
+ if ($debug) {
+ print STDERR "main(): doing 'cvs -nQq status -v $dofile'\n";
+ }
+ open(STATUS, "-|") || exec 'cvs', '-nQq', 'status', '-v', $dofile;
+ while (<STATUS>) {
+ chop;
+ push(@status_txt, $_);
+ }
+ }
+ }
}
+
+# Write to the commitlog file
#
-# Put the log message at the beginning of the Changes file and mail
-# out the notification.
+if ($commitlog) {
+ &write_commitlog($commitlog, @text);
+}
+
+if ($#status_txt >= 0) {
+ push(@text, @status_txt);
+}
+
+# Mailout the notification.
#
-&do_changes_file(@text) if ($cisco_systems != 0);
&mail_notification($mailto, @text);
-&cleanup_tmpfiles(1);
+
+# cleanup
+#
+if (! $debug) {
+ &cleanup_tmpfiles();
+}
+
exit 0;
diff --git a/gnu/usr.bin/cvs/contrib/mfpipe.pl b/gnu/usr.bin/cvs/contrib/mfpipe.pl
index 3e6357d..bae7a72 100644
--- a/gnu/usr.bin/cvs/contrib/mfpipe.pl
+++ b/gnu/usr.bin/cvs/contrib/mfpipe.pl
@@ -1,4 +1,5 @@
-#!/usr/bin/perl
+#! xPERL_PATHx
+# -*-Perl-*-
#
# From: clyne@niwot.scd.ucar.EDU (John Clyne)
# Date: Fri, 28 Feb 92 09:54:21 MST
@@ -11,7 +12,7 @@
# Especially if they regularly beat on the same directory. Anyway if you
# think anyone would be interested here it is.
#
-# $Id: mfpipe.pl,v 1.1 1992/03/02 01:22:41 berliner Exp $
+# $Id: mfpipe.pl,v 1.2 1995/07/10 02:01:57 kfogel Exp $
#
#
# File: mfpipe
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog b/gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog
index fad2eb1..ac24f44 100644
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog
+++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/ChangeLog
@@ -1,3 +1,109 @@
+Wed Nov 22 11:01:50 1995 Joshua Cowan <jcowan@hermit.reslife.okstate.edu>
+
+ * pcl-cvs.el (cvs-changelog-ours-p): use `user-full-name' if
+ `add-log-full-name' unbound, as not every uses the stuff in
+ add-log.el. Same with `add-log-mailing-address'.
+ (cvs-changelog-entries): change to `change-log-mode' unless
+ already in it.
+
+Sun Jul 9 20:57:11 1995 Karl Fogel <kfogel@floss.cyclic.com>
+
+ * "/bin/rmdir" as default, not "/usr/local/bin/rmdir".
+
+Fri Jun 16 15:24:34 1995 Jim Kingdon (kingdon@cyclic.com)
+
+ * pcl-cvs.elc, pcl-cvs-lucid.elc: Added.
+
+ * Makefile.in: Rename from Makefile and set srcdir.
+
+Thu May 18 17:10:27 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ Automatically guess CVS log entries from ChangeLog contents.
+ * pcl-cvs.el (cvs-mode-changelog-commit): New command.
+ (cvs-changelog-full-paragraphs): New variable.
+ (cvs-changelog-name, cvs-narrow-changelog,
+ cvs-changelog-paragraph, cvs-changelog-subparagraph,
+ cvs-changelog-entry, cvs-changelog-ours-p, cvs-relative-path,
+ cvs-changelog-entries, cvs-changelog-insert-entries, cvs-union,
+ cvs-insert-changelog-entries, cvs-edit-delete-common-indentation):
+ New functions.
+ (cvs-mode-map): Bind 'C' to cvs-mode-changelog-commit.
+ (cvs-mode): Mention cvs-mode-changelog-commit in docstring.
+
+ Give the info files names ending in ".info".
+ * Makefile (INFOFILES, install_info): Change pcl-cvs to
+ pcl-cvs.info.
+ (pcl-cvs.info): Target renamed from pcl-cvs.
+ (DISTFILES): pcl-cvs removed; we handle the info files explicitly
+ in the dist-dir target.
+ (dist-dir): Depend on pcl-cvs.info. Distribute pcl-cvs.info*.
+ * pcl-cvs.texinfo: Change @setfilename appropriately.
+ * INSTALL: Updated.
+ * .cvsignore: Correctly ignore the info files.
+
+ * README: Note that pcl-cvs has been tested under 19.28, and that
+ the "cookie" naming conflict was resolved in 19.11.
+
+ * Makefile (pcl-cvs-lucid.elc): Changed this target from
+ pcl-cvs-lucid.el. That's a source file, for goodness' sake!
+
+Tue May 9 13:56:50 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ * Change references to "Cygnus's remote CVS" to "Cyclic CVS".
+
+Wed May 3 13:55:27 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ * pcl-cvs.el (cvs-parse-stderr): Handle colons after both
+ "rcsmerge" and "warning".
+
+Fri Apr 28 22:38:14 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ * Makefile (ELFILES): Include pcl-cvs-startup.el.
+ (info, pcl-cvs): Call makeinfo appropriately for modern versions.
+ (pcl-cvs.aux): List dependency on pcl-cvs.texinfo.
+ (pcl-cvs.ps): New target.
+ (DVIPS): New variable.
+ (dist-dir): Renamed from dist, updated to accept DISTDIR value
+ passed from parent.
+ (DISTFILES): New varible.
+ (pcl-cvs.elc, pcl-cvs-lucid.elc): Add targets to elcfiles target.
+
+Tue Apr 25 21:33:49 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ * pcl-cvs.el: (cvs-parse-stderr): Recognize "conflicts" as well as
+ "overlaps" before "during merge."
+
+Thu Feb 16 12:17:20 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ * pcl-cvs.el (cvs-parse-stderr): Recognize "conflicts found in..."
+ messages attributed to "cvs server", as well as "cvs update".
+
+Sat Feb 4 01:47:01 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ * pcl-cvs.el: Deal with the 'P' action, produced by remote CVS.
+ (cvs-parse-stdout): Treat 'P' like 'U' --- file is updated.
+
+Tue Jan 31 23:31:39 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ * pcl-cvs.el (cvs-cvsroot-required): New variable.
+ (cvs-do-update): If cvs-cvsroot-required is not set, don't complain if
+ CVSROOT and cvs-cvsroot are both unset.
+
+Sun Jan 22 21:22:22 1995 Jim Blandy <jimb@totoro.bio.indiana.edu>
+
+ * pcl-cvs.el (cvs-parse-stderr):
+ Some changes for Cygnus's Remote CVS. Treat
+ messages like "cvs server: Updating DIRECTORY" as we treat those like
+ "cvs update: Updating DIRECTORY". Ignore other messages starting with
+ "cvs server".
+
+ * pcl-cvs.el (cvs-parse-stderr): Re-indent.
+
+ * .cvsignore: Add ignore list for Texinfo litter.
+
+ * Makefile (lispdir): Set appropriately for totoro.
+ * pcl-cvs.el (cvs-program, cvs-diff-program, cvs-rmdir-program): Same.
+
Tue Jun 1 00:00:03 1993 Per Cederqvist (ceder@lysator.liu.se)
* Release 1.05. (This release was promised before the end of May,
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL b/gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL
index f3c4480..7679967 100644
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL
+++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/INSTALL
@@ -51,22 +51,25 @@ Installation of the pcl-cvs program
Installation of the on-line manual.
===================================
- 1. Create the info file `pcl-cvs' from `pcl-cvs.texinfo' by typing
- `make info'. If you don't have the program `makeinfo' you can
- get it by anonymous ftp from e.g. `ftp.gnu.ai.mit.edu' as
- `pub/gnu/texinfo-2.14.tar.Z' (there might be a newer version
- there when you read this), or you could use the preformatted
- info file `pcl-cvs.info' that is included in the distribution
- (type `cp pcl-cvs.info pcl-cvs').
+ 1. Move the info file `pcl-cvs.info' to your standard info
+ directory. This might be called something like
+ `/usr/gnu/emacs/info'.
+
+ 2. Edit the file `dir' in the info directory and enter one line to
+ contain a pointer to the info file `pcl-cvs.info'. The line can,
+ for instance, look like this:
- 2. Move the info file `pcl-cvs' to your standard info directory.
- This might be called something like `/usr/gnu/emacs/info'.
+ * Pcl-cvs: (pcl-cvs.info). An Emacs front-end to CVS.
- 3. Edit the file `dir' in the info directory and enter one line to
- contain a pointer to the info file `pcl-cvs'. The line can, for
- instance, look like this:
- * Pcl-cvs: (pcl-cvs). An Emacs front-end to CVS.
+How to make the on-line manual from pcl-cvs.texinfo
+===================================================
+
+ 1. Create the info file `pcl-cvs.info' from `pcl-cvs.texinfo' by
+ typing `make info'. If you don't have the program `makeinfo' you
+ can get it by anonymous ftp from e.g. `ftp.gnu.ai.mit.edu' as
+ `pub/gnu/texinfo-2.14.tar.Z' (there might be a newer version
+ there when you read this).
How to make typeset documentation from pcl-cvs.texinfo
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/README b/gnu/usr.bin/cvs/contrib/pcl-cvs/README
index 779617f..a9b8106 100644
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/README
+++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/README
@@ -19,10 +19,11 @@ If you have been using a previous version of pcl-cvs (for instance
1.02 which is distributed with CVS 1.3) you should read through the
file NEWS to see what has changed.
-This release has been tested under Emacs 18.59, Emacs 19.10 and Lucid
+This release has been tested under Emacs 18.59, Emacs 19.28 and Lucid
Emacs 19.6. Emacs 19.10 unfortunately has a file named cookie.el that
-collides with the cookie.el that is distributed in Elib. We are
-trying to find a solution to that problem. In the mean time, there is
+collides with the cookie.el that is distributed in Elib. This
+conflict was resolved in 19.11. For earlier versions, there are
instructions in Elib 0.07 for how to work around the problem.
Per Cederqvist
+ (updated by Jim Blandy)
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el
index 9bbbd38..d9c15d5 100644
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el
+++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.el
@@ -37,13 +37,13 @@
;;; -------------------------------------------------------
;;; START OF THINGS TO CHECK WHEN INSTALLING
-(defvar cvs-program "/usr/gnu/bin/cvs"
+(defvar cvs-program "/usr/local/bin/cvs"
"*Full path to the cvs executable.")
-(defvar cvs-diff-program "/usr/gnu/bin/diff"
+(defvar cvs-diff-program "/usr/local/bin/diff"
"*Full path to the diff program.")
-(defvar cvs-rmdir-program "/usr/gnu/bin/rmdir"
+(defvar cvs-rmdir-program "/bin/rmdir"
"*Full path to the rmdir program. Typically /bin/rmdir.")
;; Uncomment the following line if you are running on 18.57 or earlier.
@@ -64,6 +64,20 @@
Overrides the $CVSROOT variable by sending \" -d dir\" to all cvs commands.
This switch is useful if you have multiple CVS repositories.")
+(defvar cvs-cvsroot-required t
+ "*Specifies whether CVS needs to be told where the repository is.
+
+In CVS 1.3, if your CVSROOT environment variable is not set, and you
+do not set the `cvs-cvsroot' lisp variable, CVS will have no idea
+where to find the repository, and refuse to run. CVS 1.4 and later
+store the repository path with the working directories, so most
+operations don't need to be told where the repository is.
+
+If you work with multiple repositories with CVS 1.4, it's probably
+advisable to leave your CVSROOT environment variable unset, set this
+variable to nil, and let CVS figure out where the repository is for
+itself.")
+
(defvar cvs-stdout-file nil
"Name of the file that holds the output that CVS sends to stdout.
This variable is buffer local.")
@@ -214,7 +228,7 @@ the process when a cvs update process is running.")
;;; slash.
;;; file-name The file name.
;;; base-revision The revision that the working file was based on.
-;;; Onlyy valid for MERGED and CONFLICT files.
+;;; Only valid for MERGED and CONFLICT files.
;;; cvs-diff-buffer A buffer that contains a 'cvs diff file'.
;;; backup-diff-buffer A buffer that contains a 'diff file backup-file'.
;;; full-log The output from cvs, unparsed.
@@ -450,7 +464,8 @@ Both LOCAL and DONT-CHANGE-DISC may be non-nil simultaneously.
(if (not (file-exists-p cvs-program))
(error "%s: file not found (check setting of cvs-program)"
cvs-program))
- (if (not (or (getenv "CVSROOT") cvs-cvsroot))
+ (if (and cvs-cvsroot-required
+ (not (or (getenv "CVSROOT") cvs-cvsroot)))
(error "Both cvs-cvsroot and environment variable CVSROOT unset."))
(let* ((this-dir (file-name-as-directory (expand-file-name directory)))
(update-buffer (generate-new-buffer
@@ -571,6 +586,7 @@ Full documentation is in the Texinfo file. These are the most useful commands:
\\[cvs-mode-emerge] Run emerge on base revision/backup file.
\\[cvs-mode-acknowledge] Delete line from buffer. \\[cvs-mode-ignore] Add file to the .cvsignore file.
\\[cvs-mode-log] Run ``cvs log''. \\[cvs-mode-status] Run ``cvs status''.
+\\[cvs-mode-changelog-commit] Like \\[cvs-mode-commit], but get default log text from ChangeLog.
\\[cvs-mode-undo-local-changes] Revert the last checked in version - discard your changes to the file.
Entry to this mode runs cvs-mode-hook.
@@ -898,12 +914,12 @@ This function returns the last cons-cell in the list that is built."
;; End of RCVS stuff.
;; CVS is descending a subdirectory.
-
- ((looking-at "cvs update: Updating \\(.*\\)$")
+ ;; (The "server" case is there to support Cyclic CVS.)
+ ((looking-at "cvs \\(update\\|server\\): Updating \\(.*\\)$")
(setq current-dir
(cvs-get-current-dir
root-dir
- (buffer-substring (match-beginning 1) (match-end 1))))
+ (buffer-substring (match-beginning 2) (match-end 2))))
(setcdr head (list (cvs-create-fileinfo
'DIRCHANGE current-dir
nil (buffer-substring (match-beginning 0)
@@ -1010,98 +1026,102 @@ second party")
(buffer-substring start (point)))))
(setq head (cdr head))))
- (t
-
- ;; CVS has decided to merge someone elses changes into this
- ;; document. This leads to a lot of garbage being printed.
- ;; First there is two lines that contains no information
- ;; that we skip (but we check that we recognize them).
-
- (let ((complex-start (point))
- initial-revision filename)
-
- (cvs-skip-line stdout-buffer stderr-buffer "^RCS file: .*$")
- (setq initial-revision
- (cvs-skip-line stdout-buffer stderr-buffer
- "^retrieving revision \\(.*\\)$" 1))
- (cvs-skip-line stdout-buffer stderr-buffer
- "^retrieving revision .*$")
+ ;; Ignore other messages from Cyclic CVS.
+ ((looking-at "cvs server:")
+ (forward-line 1))
- ;; Get the file name from the next line.
+ (t
- (setq
- filename
- (cvs-skip-line
- stdout-buffer stderr-buffer
- "^Merging differences between [0-9.]+ and [0-9.]+ into \\(.*\\)$"
- 1))
+ ;; CVS has decided to merge someone elses changes into this
+ ;; document. This leads to a lot of garbage being printed.
+ ;; First there is two lines that contains no information
+ ;; that we skip (but we check that we recognize them).
- (cond
- ;; Was it a conflict?
- ((looking-at
- ;; Allow both RCS 5.5 and 5.6. (5.6 prints "rcs" and " warning").
- "^\\(rcs\\)?merge\\( warning\\)?: overlaps during merge$")
-
- ;; Yes, this is a conflict.
- (cvs-skip-line
- stdout-buffer stderr-buffer
- "^\\(rcs\\)?merge\\( warning\\)?: overlaps during merge$")
+ (let ((complex-start (point))
+ initial-revision filename)
+ (cvs-skip-line stdout-buffer stderr-buffer "^RCS file: .*$")
+ (setq initial-revision
+ (cvs-skip-line stdout-buffer stderr-buffer
+ "^retrieving revision \\(.*\\)$" 1))
(cvs-skip-line stdout-buffer stderr-buffer
- "^cvs update: conflicts found in ")
+ "^retrieving revision .*$")
- (let ((fileinfo
- (cvs-create-fileinfo
- 'CONFLICT current-dir
- filename
- (buffer-substring complex-start (point)))))
+ ;; Get the file name from the next line.
+
+ (setq
+ filename
+ (cvs-skip-line
+ stdout-buffer stderr-buffer
+ "^Merging differences between [0-9.]+ and [0-9.]+ into \\(.*\\)$"
+ 1))
- (cvs-set-fileinfo->base-revision fileinfo initial-revision)
+ (cond
+ ;; Was it a conflict?
+ ((looking-at
+ ;; Allow both RCS 5.5 and 5.6. (5.6 prints "rcs" and " warning").
+ "^\\(rcs\\)?merge:?\\( warning\\)?: \\(overlaps\\|conflicts\\) during merge$")
- (setcdr head (list fileinfo))
- (setq head (cdr head))))
+ ;; Yes, this is a conflict.
+ (cvs-skip-line
+ stdout-buffer stderr-buffer
+ "^\\(rcs\\)?merge:?\\( warning\\)?: \\(overlaps\\|conflicts\\) during merge$")
- ;; Was it a conflict, and was RCS compiled without DIFF3_BIN?
+ (cvs-skip-line stdout-buffer stderr-buffer
+ "^cvs \\(update\\|server\\): conflicts found in ")
- ((looking-at
- ;; Allow both RCS 5.5 and 5.6. (5.6 prints "rcs" and " warning").
- "^\\(rcs\\)?merge\\( warning\\)?: overlaps or other probl\
-ems during merge$")
+ (let ((fileinfo
+ (cvs-create-fileinfo
+ 'CONFLICT current-dir
+ filename
+ (buffer-substring complex-start (point)))))
- ;; Yes, this is a conflict.
- (cvs-skip-line
- stdout-buffer stderr-buffer
- "^\\(rcs\\)?merge\\( warning\\)?: overlaps .*during merge$")
+ (cvs-set-fileinfo->base-revision fileinfo initial-revision)
- (cvs-skip-line stdout-buffer stderr-buffer
- "^cvs update: could not merge ")
- (cvs-skip-line stdout-buffer stderr-buffer
- "^cvs update: restoring .* from backup file ")
+ (setcdr head (list fileinfo))
+ (setq head (cdr head))))
- (let ((fileinfo
- (cvs-create-fileinfo
- 'CONFLICT current-dir
- filename
- (buffer-substring complex-start (point)))))
+ ;; Was it a conflict, and was RCS compiled without DIFF3_BIN?
- (setcdr head (list fileinfo))
- (setq head (cdr head))))
+ ((looking-at
+ ;; Allow both RCS 5.5 and 5.6. (5.6 prints "rcs" and " warning").
+ "^\\(rcs\\)?merge\\( warning\\)?: overlaps or other probl\
+ems during merge$")
- (t
- ;; Not a conflict; it must be a succesful merge.
- (let ((fileinfo
- (cvs-create-fileinfo
- 'MERGED current-dir
- filename
- (buffer-substring complex-start (point)))))
- (cvs-set-fileinfo->base-revision fileinfo initial-revision)
- (setcdr head (list fileinfo))
- (setq head (cdr head)))))))))))
+ ;; Yes, this is a conflict.
+ (cvs-skip-line
+ stdout-buffer stderr-buffer
+ "^\\(rcs\\)?merge\\( warning\\)?: overlaps .*during merge$")
+
+ (cvs-skip-line stdout-buffer stderr-buffer
+ "^cvs update: could not merge ")
+ (cvs-skip-line stdout-buffer stderr-buffer
+ "^cvs update: restoring .* from backup file ")
+
+ (let ((fileinfo
+ (cvs-create-fileinfo
+ 'CONFLICT current-dir
+ filename
+ (buffer-substring complex-start (point)))))
+
+ (setcdr head (list fileinfo))
+ (setq head (cdr head))))
+
+ (t
+ ;; Not a conflict; it must be a succesful merge.
+ (let ((fileinfo
+ (cvs-create-fileinfo
+ 'MERGED current-dir
+ filename
+ (buffer-substring complex-start (point)))))
+ (cvs-set-fileinfo->base-revision fileinfo initial-revision)
+ (setcdr head (list fileinfo))
+ (setq head (cdr head)))))))))))
head)
(defun cvs-parse-stdout (stdout-buffer stderr-buffer head root-dir)
- "Parse the output from CVS that is written to stderr.
+ "Parse the output from CVS that is written to stdout.
Args: STDOUT-BUFFER STDERR-BUFFER HEAD ROOT-DIR
STDOUT-BUFFER is the buffer that holds the output to parse.
STDERR-BUFFER holds the output that cvs sent to stderr. It is only
@@ -1121,11 +1141,11 @@ This function doesn't return anything particular."
;; A: The file is "cvs add"ed, but not "cvs ci"ed.
;; R: The file is "cvs remove"ed, but not "cvs ci"ed.
;; C: Conflict
- ;; U: The file is copied from the repository.
+ ;; U, P: The file is copied from the repository.
;; ?: Unknown file.
- ((looking-at "\\([MARCU?]\\) \\(.*\\)$")
+ ((looking-at "\\([MARCUP?]\\) \\(.*\\)$")
(let*
((c (char-after (match-beginning 1)))
(full-path
@@ -1137,12 +1157,15 @@ This function doesn't return anything particular."
((eq c ?R) 'REMOVED)
((eq c ?C) 'CONFLICT)
((eq c ?U) 'UPDATED)
+ ;; generated when Cyclic CVS sends a
+ ;; patch instead of the full file:
+ ((eq c ?P) 'UPDATED)
((eq c ??) 'UNKNOWN))
(substring (file-name-directory full-path) 0 -1)
(file-name-nondirectory full-path)
(buffer-substring (match-beginning 0) (match-end 0)))))
;; Updated files require no further action.
- (if (eq c ?U)
+ (if (memq c '(?U ?P))
(cvs-set-fileinfo->handled fileinfo t))
;; Link this last on the list.
@@ -1227,6 +1250,7 @@ For use by the cookie package."
(define-key cvs-mode-map "a" 'cvs-mode-add)
(define-key cvs-mode-map "b" 'cvs-mode-diff-backup)
(define-key cvs-mode-map "c" 'cvs-mode-commit)
+ (define-key cvs-mode-map "C" 'cvs-mode-changelog-commit)
(define-key cvs-mode-map "d" 'cvs-mode-diff-cvs)
(define-key cvs-mode-map "e" 'cvs-mode-emerge)
(define-key cvs-mode-map "f" 'cvs-mode-find-file)
@@ -2204,3 +2228,266 @@ If second optional argument REVISION is given, retrieve that revision instead."
(progn
(autoload 'pcl-cvs-fontify "pcl-cvs-lucid")
(add-hook 'cvs-mode-hook 'pcl-cvs-fontify)))
+
+
+(defvar cvs-changelog-full-paragraphs t
+ "If non-nil, include full ChangeLog paragraphs in the CVS log.
+This may be set in the ``local variables'' section of a ChangeLog, to
+indicate the policy for that ChangeLog.
+
+A ChangeLog paragraph is a bunch of log text containing no blank lines;
+a paragraph usually describes a set of changes with a single purpose,
+but perhaps spanning several functions in several files. Changes in
+different paragraphs are unrelated.
+
+You could argue that the CVS log entry for a file should contain the
+full ChangeLog paragraph mentioning the change to the file, even though
+it may mention other files, because that gives you the full context you
+need to understand the change. This is the behavior you get when this
+variable is set to t.
+
+On the other hand, you could argue that the CVS log entry for a change
+should contain only the text for the changes which occurred in that
+file, because the CVS log is per-file. This is the behavior you get
+when this variable is set to nil.")
+
+(defun cvs-changelog-name (directory)
+ "Return the name of the ChangeLog file that handles DIRECTORY.
+This is in DIRECTORY or one of its parents.
+Signal an error if we can't find an appropriate ChangeLog file."
+ (let ((dir (file-name-as-directory directory))
+ file)
+ (while (and dir
+ (not (file-exists-p
+ (setq file (expand-file-name "ChangeLog" dir)))))
+ (let ((last dir))
+ (setq dir (file-name-directory (directory-file-name dir)))
+ (if (equal last dir)
+ (setq dir nil))))
+ (or dir
+ (error "Can't find ChangeLog for %s" directory))
+ file))
+
+(defun cvs-narrow-changelog ()
+ "Narrow to the top page of the current buffer, a ChangeLog file.
+Actually, the narrowed region doesn't include the date line.
+A \"page\" in a ChangeLog file is the area between two dates."
+ (or (eq major-mode 'change-log-mode)
+ (error "cvs-narrow-changelog: current buffer isn't a ChangeLog"))
+
+ (goto-char (point-min))
+
+ ;; Skip date line and subsequent blank lines.
+ (forward-line 1)
+ (if (looking-at "[ \t\n]*\n")
+ (goto-char (match-end 0)))
+
+ (let ((start (point)))
+ (forward-page 1)
+ (narrow-to-region start (point))
+ (goto-char (point-min))))
+
+(defun cvs-changelog-paragraph ()
+ "Return the bounds of the ChangeLog paragraph containing point.
+If we are between paragraphs, return the previous paragraph."
+ (save-excursion
+ (beginning-of-line)
+ (if (looking-at "^[ \t]*$")
+ (skip-chars-backward " \t\n" (point-min)))
+ (list (progn
+ (if (re-search-backward "^[ \t]*\n" nil 'or-to-limit)
+ (goto-char (match-end 0)))
+ (point))
+ (if (re-search-forward "^[ \t\n]*$" nil t)
+ (match-beginning 0)
+ (point)))))
+
+(defun cvs-changelog-subparagraph ()
+ "Return the bounds of the ChangeLog subparagraph containing point.
+A subparagraph is a block of non-blank lines beginning with an asterisk.
+If we are between subparagraphs, return the previous subparagraph."
+ (save-excursion
+ (end-of-line)
+ (if (search-backward "*" nil t)
+ (list (progn (beginning-of-line) (point))
+ (progn
+ (forward-line 1)
+ (if (re-search-forward "^[ \t]*[\n*]" nil t)
+ (match-beginning 0)
+ (point-max))))
+ (list (point) (point)))))
+
+(defun cvs-changelog-entry ()
+ "Return the bounds of the ChangeLog entry containing point.
+The variable `cvs-changelog-full-paragraphs' decides whether an
+\"entry\" is a paragraph or a subparagraph; see its documentation string
+for more details."
+ (if cvs-changelog-full-paragraphs
+ (cvs-changelog-paragraph)
+ (cvs-changelog-subparagraph)))
+
+(defun cvs-changelog-ours-p ()
+ "See if ChangeLog entry at point is for the current user, today.
+Return non-nil iff it is."
+ ;; Code adapted from add-change-log-entry.
+ (looking-at (concat (regexp-quote (substring (current-time-string)
+ 0 10))
+ ".* "
+ (regexp-quote (substring (current-time-string) -4))
+ "[ \t]+"
+ (regexp-quote (if (boundp 'add-log-full-name)
+ add-log-full-name
+ user-full-name))
+ " <"
+ (regexp-quote
+ (if (boundp 'add-log-mailing-address)
+ add-log-mailing-address
+ user-mail-address)))))
+
+(defun cvs-relative-path (base child)
+ "Return a directory path relative to BASE for CHILD.
+If CHILD doesn't seem to be in a subdirectory of BASE, just return
+the full path to CHILD."
+ (let ((base (file-name-as-directory (expand-file-name base)))
+ (child (expand-file-name child)))
+ (or (string= base (substring child 0 (length base)))
+ (error "cvs-relative-path: %s isn't in %s" child base))
+ (substring child (length base))))
+
+(defun cvs-changelog-entries (file)
+ "Return the ChangeLog entries for FILE, and the ChangeLog they came from.
+The return value looks like this:
+ (LOGBUFFER (ENTRYSTART . ENTRYEND) ...)
+where LOGBUFFER is the name of the ChangeLog buffer, and each
+\(ENTRYSTART . ENTRYEND\) pair is a buffer region."
+ (save-excursion
+ (set-buffer (find-file-noselect
+ (cvs-changelog-name
+ (file-name-directory
+ (expand-file-name file)))))
+ (or (eq major-mode 'change-log-mode)
+ (change-log-mode))
+ (goto-char (point-min))
+ (if (looking-at "[ \t\n]*\n")
+ (goto-char (match-end 0)))
+ (if (not (cvs-changelog-ours-p))
+ (list (current-buffer))
+ (save-restriction
+ (cvs-narrow-changelog)
+ (goto-char (point-min))
+
+ ;; Search for the name of FILE relative to the ChangeLog. If that
+ ;; doesn't occur anywhere, they're not using full relative
+ ;; filenames in the ChangeLog, so just look for FILE; we'll accept
+ ;; some false positives.
+ (let ((pattern (cvs-relative-path
+ (file-name-directory buffer-file-name) file)))
+ (if (or (string= pattern "")
+ (not (save-excursion
+ (search-forward pattern nil t))))
+ (setq pattern file))
+
+ (let (texts)
+ (while (search-forward pattern nil t)
+ (let ((entry (cvs-changelog-entry)))
+ (setq texts (cons entry texts))
+ (goto-char (elt entry 1))))
+
+ (cons (current-buffer) texts)))))))
+
+(defun cvs-changelog-insert-entries (buffer regions)
+ "Insert those regions in BUFFER specified in REGIONS.
+Sort REGIONS front-to-back first."
+ (let ((regions (sort regions 'car-less-than-car))
+ (last))
+ (while regions
+ (if (and last (< last (car (car regions))))
+ (newline))
+ (setq last (elt (car regions) 1))
+ (apply 'insert-buffer-substring buffer (car regions))
+ (setq regions (cdr regions)))))
+
+(defun cvs-union (set1 set2)
+ "Return the union of SET1 and SET2, according to `equal'."
+ (while set2
+ (or (member (car set2) set1)
+ (setq set1 (cons (car set2) set1)))
+ (setq set2 (cdr set2)))
+ set1)
+
+(defun cvs-insert-changelog-entries (files)
+ "Given a list of files FILES, insert the ChangeLog entries for them."
+ (let ((buffer-entries nil))
+
+ ;; Add each buffer to buffer-entries, and associate it with the list
+ ;; of entries we want from that file.
+ (while files
+ (let* ((entries (cvs-changelog-entries (car files)))
+ (pair (assq (car entries) buffer-entries)))
+ (if pair
+ (setcdr pair (cvs-union (cdr pair) (cdr entries)))
+ (setq buffer-entries (cons entries buffer-entries))))
+ (setq files (cdr files)))
+
+ ;; Now map over each buffer in buffer-entries, sort the entries for
+ ;; each buffer, and extract them as strings.
+ (while buffer-entries
+ (cvs-changelog-insert-entries (car (car buffer-entries))
+ (cdr (car buffer-entries)))
+ (if (and (cdr buffer-entries) (cdr (car buffer-entries)))
+ (newline))
+ (setq buffer-entries (cdr buffer-entries)))))
+
+(defun cvs-edit-delete-common-indentation ()
+ "Unindent the current buffer rigidly until at least one line is flush left."
+ (save-excursion
+ (let ((common 100000))
+ (goto-char (point-min))
+ (while (< (point) (point-max))
+ (if (not (looking-at "^[ \t]*$"))
+ (setq common (min common (current-indentation))))
+ (forward-line 1))
+ (indent-rigidly (point-min) (point-max) (- common)))))
+
+(defun cvs-mode-changelog-commit ()
+
+ "Check in all marked files, or the current file.
+Ask the user for a log message in a buffer.
+
+This is just like `\\[cvs-mode-commit]', except that it tries to provide
+appropriate default log messages by looking at the ChangeLogs. The
+idea is to write your ChangeLog entries first, and then use this
+command to commit your changes.
+
+To select default log text, we:
+- find the ChangeLogs for the files to be checked in,
+- verify that the top entry in the ChangeLog is on the current date
+ and by the current user; if not, we don't provide any default text,
+- search the ChangeLog entry for paragraphs containing the names of
+ the files we're checking in, and finally
+- use those paragraphs as the log text."
+
+ (interactive)
+
+ (let* ((cvs-buf (current-buffer))
+ (marked (cvs-filter (function cvs-committable)
+ (cvs-get-marked))))
+ (if (null marked)
+ (error "Nothing to commit!")
+ (pop-to-buffer (get-buffer-create cvs-commit-prompt-buffer))
+ (goto-char (point-min))
+
+ (erase-buffer)
+ (cvs-insert-changelog-entries
+ (mapcar (lambda (tin)
+ (let ((cookie (tin-cookie cvs-cookie-handle tin)))
+ (expand-file-name
+ (cvs-fileinfo->file-name cookie)
+ (cvs-fileinfo->dir cookie))))
+ marked))
+ (cvs-edit-delete-common-indentation)
+
+ (cvs-edit-mode)
+ (make-local-variable 'cvs-commit-list)
+ (setq cvs-commit-list marked)
+ (message "Press C-c C-c when you are done editing."))))
diff --git a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo
index 0b51f77..bb0a4fe 100644
--- a/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo
+++ b/gnu/usr.bin/cvs/contrib/pcl-cvs/pcl-cvs.texinfo
@@ -20,7 +20,7 @@
@comment along with pcl-cvs; see the file COPYING. If not, write to
@comment the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-@setfilename pcl-cvs
+@setfilename pcl-cvs.info
@settitle Pcl-cvs - The Emacs Front-End to CVS
@setchapternewpage on
diff --git a/gnu/usr.bin/cvs/contrib/rcslock.pl b/gnu/usr.bin/cvs/contrib/rcslock.pl
index db09b4b..01e349f 100644
--- a/gnu/usr.bin/cvs/contrib/rcslock.pl
+++ b/gnu/usr.bin/cvs/contrib/rcslock.pl
@@ -1,4 +1,5 @@
-#!/usr/bin/perl
+#! xPERL_PATHx
+# -*-Perl-*-
# Author: John Rouillard (rouilj@cs.umb.edu)
# Supported: Yeah right. (Well what do you expect for 2 hours work?)
OpenPOWER on IntegriCloud