This commit was generated by cvs2svn to compensate for changes in r7514,
which included commits to RCS files with non-trunk default branches.
This commit is contained in:
commit
789377fada
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=7515
@ -1,4 +1,4 @@
|
||||
@(#)README 1.8 92/04/10
|
||||
$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
|
||||
@ -66,3 +66,22 @@ Contents of this directory:
|
||||
$CVSROOT/CVSROOT/history file, as it can grow quite
|
||||
large after extended use.
|
||||
Contributed by David G. Grubbs <dgg@ksr.com>
|
||||
sccs2rcs A C-shell script that can convert (some) SCCS files
|
||||
into RCS files, retaining the info contained in the
|
||||
SCCS file (like dates, author, and log message).
|
||||
Contributed by Ken Cox <kenstir@viewlogic.com>.
|
||||
intro.doc A user's view of what you need to know to get
|
||||
started with CVS.
|
||||
Contributed by <Steven.Pemberton@cwi.nl>.
|
||||
rcs2sccs A shell script to convert simple RCS files into
|
||||
SCCS files, originally gleaned off the network
|
||||
somewhere (originally by "kenc") and modified by
|
||||
Jerry Jelinek <jerry@rmtc.Central.Sun.COM> and
|
||||
Brian Berliner <berliner@sun.com> to increase
|
||||
robustness and add support for one-level of branches.
|
||||
rcs2log A shell script to create a ChangeLog-format file
|
||||
given only a set of RCS files.
|
||||
Contributed by Paul Eggert <eggert@twinsun.com>.
|
||||
clmerge A perl script to handle merge conflicts in GNU
|
||||
style ChangeLog files .
|
||||
Contributed by Tom Tromey <tromey@busco.lanl.gov>.
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/perl -- # -*-Perl-*-
|
||||
#
|
||||
# cln_hist.pl,v 1.1 1992/04/10 03:04:15 berliner Exp
|
||||
# $Id: cln_hist.pl,v 1.1 1992/04/10 03:04:15 berliner Exp $
|
||||
# Contributed by David G. Grubbs <dgg@ksr.com>
|
||||
#
|
||||
# Clean up the history file. 10 Record types: MAR OFT WUCG
|
||||
|
@ -1,6 +1,6 @@
|
||||
#!/usr/bin/perl -- # -*-Perl-*-
|
||||
#
|
||||
# cvs_acls.pl,v 1.2 1992/04/11 16:01:24 berliner Exp
|
||||
# $Id: cvs_acls.pl,v 1.2 1992/04/11 16:01:24 berliner Exp $
|
||||
#
|
||||
# Access control lists for CVS. dgg@ksr.com (David G. Grubbs)
|
||||
#
|
||||
|
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# cvscheck,v 1.2 1992/04/10 03:04:19 berliner Exp
|
||||
# $Id: cvscheck,v 1.2 1992/04/10 03:04:19 berliner Exp $
|
||||
#
|
||||
# cvscheck - identify files added, changed, or removed
|
||||
# in CVS working directory
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" cvscheck.man,v 1.1 1992/04/10 03:04:20 berliner Exp
|
||||
.\" $Id: cvscheck.man,v 1.1 1992/04/10 03:04:20 berliner Exp $
|
||||
.\" Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
|
||||
.TH CVSCHECK LOCAL "4 March 1991" FLUKE
|
||||
.SH NAME
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" cvshelp.man,v 1.1 1992/04/10 03:04:21 berliner Exp
|
||||
.\" $Id: cvshelp.man,v 1.1 1992/04/10 03:04:21 berliner Exp $
|
||||
.\" Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
|
||||
.\" Full space in nroff; half space in troff
|
||||
.de SP
|
||||
|
@ -1,5 +1,5 @@
|
||||
#! /bin/sh
|
||||
# descend,v 1.1 1992/04/03 05:22:52 berliner Exp
|
||||
# $Id: descend,v 1.1 1992/04/03 05:22:52 berliner Exp $
|
||||
#
|
||||
# descend - walk down a directory tree and execute a command at each node
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
.\" descend.man,v 1.1 1992/04/03 05:22:53 berliner Exp
|
||||
.\" $Id: descend.man,v 1.1 1992/04/03 05:22:53 berliner Exp $
|
||||
.TH DESCEND 1 "31 March 1992"
|
||||
.SH NAME
|
||||
descend \- walk directory tree and execute a command at each node
|
||||
|
@ -1,5 +1,9 @@
|
||||
#!/usr/bin/perl
|
||||
#! /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
|
||||
#
|
||||
# Modified by berliner@Sun.COM to add support for CVS 1.3 2/27/92
|
||||
#
|
||||
# Date: Tue, 6 Aug 91 13:27 EDT
|
||||
@ -11,94 +15,134 @@
|
||||
# now the output looks like this:
|
||||
#
|
||||
# **************************************
|
||||
# date: Tuesday, August 6, 1991 @ 13:17
|
||||
# author: samborn
|
||||
# Date: Tuesday, August 6, 1991 @ 13:17
|
||||
# Author: samborn
|
||||
#
|
||||
# Update of /elmer/cvs/CVSROOT.adm
|
||||
# In directory astro:/home/samborn/CVSROOT.adm
|
||||
#
|
||||
# Modified Files:
|
||||
# test3
|
||||
#
|
||||
# Added Files:
|
||||
# test6
|
||||
#
|
||||
# Removed Files:
|
||||
# test4
|
||||
#
|
||||
# Log Message:
|
||||
# wow, what a test
|
||||
#
|
||||
# RCS: 1.4 /elmer/cvs/CVSROOT.adm/test3,v
|
||||
# RCS: 1.1 /elmer/cvs/CVSROOT.adm/test6,v
|
||||
# RCS: 1.1 /elmer/cvs/CVSROOT.adm/Attic/test4,v
|
||||
# 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
|
||||
#
|
||||
|
||||
#
|
||||
$cvsroot = $ENV{'CVSROOT'};
|
||||
|
||||
# turn off setgid
|
||||
#
|
||||
$) = $(;
|
||||
|
||||
#
|
||||
# parse command line arguments
|
||||
#
|
||||
@files = split(/ /,$ARGV[0]);
|
||||
$logfile = $ARGV[1];
|
||||
$cvsroot = $ENV{'CVSROOT'};
|
||||
while (@ARGV) {
|
||||
$arg = shift @ARGV;
|
||||
|
||||
if ($arg eq '-m') {
|
||||
$users = "$users " . shift @ARGV;
|
||||
} elsif ($arg eq '-f') {
|
||||
($logfile) && die "Too many '-f' args";
|
||||
$logfile = shift @ARGV;
|
||||
} else {
|
||||
($donefiles) && die "Too many arguments!\n";
|
||||
$donefiles = 1;
|
||||
@files = split(/ /, $arg);
|
||||
}
|
||||
}
|
||||
|
||||
$srepos = shift @files;
|
||||
$mailcmd = "| Mail -s 'CVS update: $srepos'";
|
||||
|
||||
#
|
||||
# Some date and time arrays
|
||||
#
|
||||
@mos = (January,February,March,April,May,June,July,August,September,
|
||||
October,November,December);
|
||||
@days = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
|
||||
|
||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||
|
||||
#
|
||||
# get login name
|
||||
#
|
||||
$login = getlogin || (getpwuid($<))[0] || "nobody";
|
||||
|
||||
#
|
||||
# open log file for appending
|
||||
#
|
||||
if ((open(OUT, ">>" . $logfile)) != 1) {
|
||||
die "Could not open logfile " . $logfile . "\n";
|
||||
open(OUT, ">>" . $logfile) || die "Could not open(" . $logfile . "): $!\n";
|
||||
if ($users) {
|
||||
$mailcmd = "$mailcmd $users";
|
||||
open(MAIL, $mailcmd) || die "Could not Exec($mailcmd): $!\n";
|
||||
}
|
||||
|
||||
#
|
||||
# Header
|
||||
# print out the log Header
|
||||
#
|
||||
print OUT "\n";
|
||||
print OUT "**************************************\n";
|
||||
print OUT "date: " . $days[$wday] . ", " . $mos[$mon] . " " . $mday . ", 19" . $year .
|
||||
" @ " . $hour . ":" . sprintf("%02d", $min) . "\n";
|
||||
print OUT "author: " . $login . "\n";
|
||||
print OUT "Date:\t$days[$wday] $mos[$mon] $mday, 19$year @ $hour:" . sprintf("%02d", $min) . "\n";
|
||||
print OUT "Author:\t$login\n\n";
|
||||
|
||||
#
|
||||
#print the stuff on stdin to the logfile
|
||||
if (MAIL) {
|
||||
print MAIL "\n";
|
||||
print MAIL "Date:\t$days[$wday] $mos[$mon] $mday, 19$year @ $hour:" . sprintf("%02d", $min) . "\n";
|
||||
print MAIL "Author:\t$login\n\n";
|
||||
}
|
||||
|
||||
# print the stuff from logmsg that comes in on stdin to the logfile
|
||||
#
|
||||
open(IN, "-");
|
||||
while (<IN>) {
|
||||
print OUT $_;
|
||||
if (MAIL) {
|
||||
print MAIL $_;
|
||||
}
|
||||
}
|
||||
close(IN);
|
||||
|
||||
print OUT "\n";
|
||||
|
||||
#
|
||||
# after log information, do an 'cvs -Qn status' on each file in the arguments.
|
||||
#
|
||||
for $file (@files[1..$#files]) {
|
||||
while (@files) {
|
||||
$file = shift @files;
|
||||
if ($file eq "-") {
|
||||
print OUT "[input file was '-']\n";
|
||||
if (MAIL) {
|
||||
print MAIL "[input file was '-']\n";
|
||||
}
|
||||
last;
|
||||
}
|
||||
|
||||
open(RCS, "-|") || exec 'cvs', '-Qn', 'status', $file;
|
||||
|
||||
while (<RCS>) {
|
||||
if (substr($_, 0, 7) eq " RCS") {
|
||||
if (/^[ \t]*Version/ || /^File:/) {
|
||||
print OUT;
|
||||
if (MAIL) {
|
||||
print MAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(RCS);
|
||||
}
|
||||
|
||||
close(OUT);
|
||||
die "Write to $logfile failed" if $?;
|
||||
|
||||
close(MAIL);
|
||||
die "Pipe to $mailcmd failed" if $?;
|
||||
|
||||
exit 0;
|
||||
|
||||
### Local Variables:
|
||||
### eval: (fundamental-mode)
|
||||
### End:
|
||||
|
@ -11,7 +11,7 @@
|
||||
# Especially if they regularly beat on the same directory. Anyway if you
|
||||
# think anyone would be interested here it is.
|
||||
#
|
||||
# mfpipe.pl,v 1.1 1992/03/02 01:22:41 berliner Exp
|
||||
# $Id: mfpipe.pl,v 1.1 1992/03/02 01:22:41 berliner Exp $
|
||||
#
|
||||
#
|
||||
# File: mfpipe
|
||||
|
@ -1,3 +1,552 @@
|
||||
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,
|
||||
but I didn't quite make it. No, I didn't fake the date above).
|
||||
|
||||
Mon May 31 01:32:25 1993 Per Cederqvist (ceder@lysator.liu.se)
|
||||
|
||||
* Removed the elib sub-directory. Users must now get the Elib
|
||||
library separately.
|
||||
* pcl-cvs.texinfo: Document it.
|
||||
|
||||
* pcl-cvs-lucid.el: A new version, supplied by Jamie Zawinsky,
|
||||
added.
|
||||
|
||||
* pcl-cvs Id 68: Transform RCS keywords
|
||||
* Makefile (pcl-cvs-$(VER)): Remove the $ signs in most files in
|
||||
the distribution.
|
||||
|
||||
* pcl-cvs Id 76: Extra " in cvs-mode-add.
|
||||
* pcl-cvs.el (cvs-mode-add): Don't add the extra level of quotes
|
||||
around the log message, since it doesn't work with CVS.
|
||||
|
||||
* pcl-cvs Id 56: '-d <CVSROOT>' support in pcl-cvs
|
||||
* pcl-cvs.el (cvs-change-cvsroot): New function.
|
||||
|
||||
* pcl-cvs Id 77: *cvs* isn't cleared properly
|
||||
* pcl-cvs.el (cvs-do-update): Always erase the *cvs* buffer and
|
||||
re-create the collection.
|
||||
|
||||
* pcl-cvs.el (cvs-do-update): Set mode-line-process in the *cvs*
|
||||
buffer.
|
||||
* pcl-cvs.el (cvs-mode): Reset mode-line-process.
|
||||
|
||||
* pcl-cvs Id 59: sort .cvsignore alphabetically!
|
||||
* pcl-cvs.el (cvs-sort-ignore-file): New variable.
|
||||
* pcl-cvs.el (cvs-mode-ignore): Use it.
|
||||
* pcl-cvs.texinfo: Document it.
|
||||
|
||||
* pcl-cvs Id 75: Require final newline.
|
||||
* pcl-cvs.el (cvs-commit-buffer-require-final-newline): New
|
||||
variable.
|
||||
* pcl-cvs.el (cvs-edit-done): Use it.
|
||||
* pcl-cvs.texinfo: Document it.
|
||||
|
||||
* pcl-cvs Id 72: make clean deletes lucid-emacs.el
|
||||
* dist-makefile (ELCFILES): Fixed a typo.
|
||||
|
||||
* pcl-cvs Id 46: "cvs remove f" "touch f" "cvs update f" -> parse err.
|
||||
* pcl-cvs.el (cvs-fileinfo->type): New type: REM-EXIST.
|
||||
* pcl-cvs.el (cvs-shadow-entry-p): A REMOVED that follows a
|
||||
REM-EXIST is a shadow.
|
||||
* pcl-cvs.el (cvs-parse-stderr): Recognize the "should be removed
|
||||
and is still there" message.
|
||||
* pcl-cvs.el (cvs-pp): Recognize REM-EXIST.
|
||||
* pcl-cvs.el (cvs-mode-undo-local-changes): Recognize and complain
|
||||
about REM-EXIST. Defensive test added: complain about unknown types.
|
||||
|
||||
* pcl-cvs.el (cvs-mode-add): Add an extra level of quotes around
|
||||
the log message. This is apparently needed by RCVS. <This change
|
||||
has been removed. --ceder>.
|
||||
|
||||
* pcl-cvs.el (cvs-parse-stderr): Ignore output from RCVS.
|
||||
|
||||
Tue Apr 27 00:48:40 1993 Per Cederqvist (ceder@lysator.liu.se)
|
||||
|
||||
* pcl-cvs.el (cvs-startup-message): Now a defconst instead of a
|
||||
defvar.
|
||||
* pcl-cvs.el (cvs-mode-commit): Add a defvar for it.
|
||||
|
||||
* dist-makefile (EMACS): Use $(EMACS) instead of hard-coding 'emacs'.
|
||||
|
||||
Sat Apr 17 12:47:10 1993 Per Cederqvist (ceder@lysator.liu.se)
|
||||
|
||||
* Release 1.04.
|
||||
|
||||
* pcl-cvs.texinfo: Updated the Contributors node.
|
||||
|
||||
* pcl-cvs Id 58: Lucid GNU Emacs support
|
||||
* pcl-cvs-lucid.el: New file, contributed by the people at Lucid.
|
||||
* pcl-cvs.el: Autoload pcl-cvs-lucid if running in an Lucid GNU
|
||||
Emacs.
|
||||
* compile-all.el: (files-to-compile): Add pcl-cvs-lucid.
|
||||
* dist-makefile (ELFILES, ELCFILES): Dito.
|
||||
|
||||
* pcl-cvs Id 55: cvs-diff-backup swaps old and new version.
|
||||
* pcl-cvs.el (cvs-diff-backup-extractor): Old version should be
|
||||
first.
|
||||
* pcl-cvs.el (cvs-mode-diff-backup): Call cvs-backup-diffable
|
||||
correctly.
|
||||
|
||||
* pcl-cvs Id 64: elib substitute
|
||||
* dist-makefile (install): Warn about Elib.
|
||||
* pcl-cvs.texinfo: Talk about Elib.
|
||||
|
||||
* pcl-cvs Id 50: Committing the *commit* buffer twice.
|
||||
* pcl-cvs.el (cvs-edit-done): Report an error if cvs-commit-list
|
||||
is empty, and empty it when the commit is done.
|
||||
|
||||
* pcl-cvs Id 56: '-d <CVSROOT>' support.
|
||||
* pcl-cvs.el (cvs-cvsroot): New variable.
|
||||
* pcl-cvs.el (cvs-do-update, all callers of cvs-execute-list): Use
|
||||
it everywhere CVS is called, to override CVSROOT.
|
||||
* pcl-cvs.texinfo (Customization): Document it.
|
||||
|
||||
Thu Apr 1 00:34:55 1993 Per Cederqvist (ceder@lysator.liu.se)
|
||||
|
||||
* pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): Exit status nil
|
||||
from call-process means everything was successful in some Emacs
|
||||
versions.
|
||||
|
||||
* pcl-cvs.el (cvs-mode-map): Bind "q" to bury-buffer.
|
||||
* pcl-cvs.texinfo: Document it.
|
||||
|
||||
Thu Mar 11 00:05:03 1993 Per Cederqvist (ceder@lysator.liu.se)
|
||||
|
||||
* Release 1.03-Emerge (not released).
|
||||
|
||||
* Makefile (pcl-cvs-$(VER)): Don't includ elib-dll-debug.el in the
|
||||
distribution. (It's included as elib/dll-debug.el).
|
||||
|
||||
* pcl-cvs.el (cvs-mode): Document the "e" key (cvs-mode-emerge).
|
||||
|
||||
Tue Mar 9 00:02:57 1993 Per Cederqvist (ceder@lysator.liu.se)
|
||||
|
||||
* pcl-cvs.texinfo (Emerge): New node.
|
||||
|
||||
* pcl-cvs.el (cvs-kill-buffer-visiting): New function.
|
||||
|
||||
* pcl-cvs.el (cvs-mode-emerge): Handle Conflict and Merged files.
|
||||
|
||||
* pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): Handle any revision.
|
||||
|
||||
* pcl-cvs.el (cvs-fileinfo-*): Store base-revision instead of
|
||||
backup-file.
|
||||
|
||||
* pcl-cvs.el (cvs-backup-diffable): The file is only diffable if
|
||||
the backup file is readable.
|
||||
|
||||
* pcl-cvs.el (cvs-mode-map): Bind "e" to cvs-mode-emerge instead
|
||||
of cvs-mode-find-file (which is anyhow bound to "f").
|
||||
|
||||
Mon Mar 8 23:06:52 1993 Per Cederqvist (ceder@lysator.liu.se)
|
||||
|
||||
* pcl-cvs.el (cvs-mode-emerge): New function. Currently only
|
||||
handles emerge of Modified files.
|
||||
|
||||
* pcl-cvs.el (cvs-retrieve-revision-to-tmpfile): New function.
|
||||
|
||||
Sun Jan 24 20:07:18 1993 Per Cederqvist (ceder@lysator.liu.se)
|
||||
|
||||
* elib-dll-debug.el: Moved to elib.
|
||||
|
||||
Mon Jan 18 00:35:59 1993 Per Cederqvist (ceder@mauritz)
|
||||
|
||||
* pcl-cvs.el (cvs-do-update): Added a probably unnecessary sit-for.
|
||||
|
||||
* Release 1.03-Elib-0.05.1 (not released).
|
||||
|
||||
* Elib 0.05 compatibility:
|
||||
* elib-dll-debug.el, pcl-cvs-buffer.el, test-dll.el: Fix the
|
||||
require strings.
|
||||
* pcl-cvs.el (cvs-pp): Insert the string.
|
||||
|
||||
* Release 1.03-Elib-0.05 (not released).
|
||||
|
||||
* elib: New directory, containing the parts of elib that are
|
||||
required for pcl-cvs. Changes to the files in that directory
|
||||
that are present in Elib are documented in the ChangeLog of
|
||||
Elib, not here.
|
||||
* Makefile (pcl-cvs-$(VER)): Copy the new dir to the distribution.
|
||||
* dist-makefile (ELFILES, ELCFILES): Don't include the Elib files.
|
||||
|
||||
Fri Jan 8 02:43:49 1993 Per Cederqvist (ceder@konrad)
|
||||
|
||||
* pcl-cvs.el (cvs-mode-map): Bind "e" to cvs-mode-find-file, like
|
||||
in dired.
|
||||
|
||||
Sun Jan 3 23:25:13 1993 Per Cederqvist (ceder@konrad)
|
||||
|
||||
* elib-dll.el, elib-node.el, cookie.el: Moved to the elib package.
|
||||
Pcl-cvs now requires elib.
|
||||
|
||||
Tue Dec 29 22:06:57 1992 Per Cederqvist (ceder@konrad)
|
||||
|
||||
* pcl-cvs.el: Tracked the latest (last?) rename of all functions
|
||||
in cookie.el.
|
||||
|
||||
Thu Sep 24 00:29:16 1992 Per Cederqvist (ceder@robert)
|
||||
|
||||
* pcl-cvs.texinfo (Archives): This version is not distributed with
|
||||
CVS 1.3, so don't claim that it is.
|
||||
|
||||
Fri Aug 21 15:17:08 1992 Per Cederqvist (ceder@maskros)
|
||||
|
||||
* pcl-cvs.el (cvs-parse-stderr): Fixed two "(set head" that should
|
||||
be "(setq head".
|
||||
|
||||
Thu Aug 20 05:53:58 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* cookie.el: Changes to this file is documented in the ChangeLog
|
||||
of elib in the future.
|
||||
|
||||
Tue Aug 18 03:30:28 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el: Don't use cookie-last-tin (which no longer exists).
|
||||
|
||||
* cookie.el: Use prefix cookie:: for internal functions.
|
||||
|
||||
* cookie.el: (cookie:enter-after, cookie:enter-before,
|
||||
cookie:nth-cookie): Implemented.
|
||||
* cookie.el: No longer define (impl).
|
||||
|
||||
* cookie.el: More renames:
|
||||
cookie:next-cookie -> cookie:goto-next-tin
|
||||
cookie:previous-cookie -> cookie:goto-previous-tin
|
||||
tin-next -> cookie:next-tin
|
||||
tin-previous -> cookie:previous-tin
|
||||
tin-nth -> cookie:nth-tin
|
||||
tin-delete -> cookie:delete-tin
|
||||
cookie:collect -> cookie:collect-cookies
|
||||
cookie:tin-collect -> cookie:collect-tins
|
||||
(new) -> cookie:tin-collect-cookies
|
||||
(new) -> cookie:tin-collect-tins
|
||||
cookie:refresh -> cookie:refresh-all
|
||||
tin-invalidate-tins -> cookie:invalidate-tins
|
||||
|
||||
Mon Aug 17 01:39:49 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* cookie.el (cookie:set-buffer-bind-dll-let*): New macro. Used in
|
||||
many places instead of cookie:set-buffer-bind-dll.
|
||||
* cookie.el (cookie:set-buffer-bind-dll): Renamed the macro
|
||||
cookie:set-buffer to this.
|
||||
|
||||
* pcl-cvs.el (cvs-use-temp-buffer): Set default-directory.
|
||||
|
||||
Sun Aug 16 20:51:30 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el (cvs-add-sub): Fixed call to cvs-add-file-update-buffer.
|
||||
|
||||
Sat Aug 8 20:28:21 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* Release 1.03-Cookie-II (not released).
|
||||
|
||||
* pcl-cvs.el (cvs-mode-diff-cvs): Don't care about the exit status
|
||||
from ``cvs diff''.
|
||||
|
||||
* pcl-cvs.el (cvs-mode): Document cvs-mode-undo-local-changes.
|
||||
* pcl-cvs.el (cvs-diffable): New function.
|
||||
|
||||
* pcl-cvs.el: Use the new cookie package.
|
||||
* pcl-cvs.el (cvs-cookie-handle): New variable.
|
||||
* pcl-cvs.el (cvs-do-update): User the new cookie:create
|
||||
interface, and cookie:clear if the buffer already existed. Make
|
||||
the buffer read-only.
|
||||
* pcl-cvs.el (cvs-mode-next-line, cvs-mode-previous-line): New
|
||||
functions (used instead of cookie:next-cookie and
|
||||
cookie:previous-cookie).
|
||||
|
||||
* cookie.el: Major redesign. The handle that is passed to all
|
||||
cookie functions is now a new datatype, and not the buffer that
|
||||
the cookies resides in. This way it is possible to have more than
|
||||
one set of cookies in a buffer. Things that used to be
|
||||
buffer-local variables are now fields in the handle data type.
|
||||
cookie-last-tin is no longer available.
|
||||
* cookie.el (cookie:create): The buffer is not cleared, nor set to
|
||||
be read-only.
|
||||
* cookie.el (cookie:next-cookie, cookie:previous-cookie): Since
|
||||
the first argument is now a handle and not a buffer, these can no
|
||||
longer be called interactively. You have to write a small wrapper
|
||||
about them.
|
||||
* cookie.el (cookie:buffer): New function.
|
||||
|
||||
Tue Aug 4 03:02:25 1992 Per Cederqvist (ceder@robert)
|
||||
|
||||
* pcl-cvs.texinfo (Bugs): Renamed "Reporting bugs and ideas" to
|
||||
"Bugs" and added a table of known bugs/FAQ:s.
|
||||
|
||||
Mon Aug 3 00:19:39 1992 Per Cederqvist (ceder@robert)
|
||||
|
||||
* pcl-cvs.el, pcl-cvs.texinfo: Big Renaming Time!
|
||||
The commands that operate in the *cvs* buffer:
|
||||
cvs-add-change-log-entry-other-window -> cvs-mode-add-change-log-entry-other-window
|
||||
cvs-mark-all-files -> cvs-mode-mark-all-files
|
||||
cvs-revert-updated-buffers -> cvs-mode-revert-updated-buffers
|
||||
cvs-undo-local-changes -> cvs-mode-undo-local-changes
|
||||
cvs-unmark-up -> cvs-mode-unmark-up
|
||||
cvs-acknowledge -> cvs-mode-acknowledge
|
||||
cvs-unmark-all-files -> cvs-mode-unmark-all-files
|
||||
cvs-add -> cvs-mode-add
|
||||
cvs-diff-backup -> cvs-mode-diff-backup
|
||||
cvs-commit -> cvs-mode-commit
|
||||
cvs-diff-cvs -> cvs-mode-diff-cvs
|
||||
cvs-find-file -> cvs-mode-find-file
|
||||
cvs-update-no-prompt -> cvs-mode-update-no-prompt
|
||||
cvs-ignore -> cvs-mode-ignore
|
||||
cvs-log -> cvs-mode-log
|
||||
cvs-mark -> cvs-mode-mark
|
||||
cvs-find-file-other-window -> cvs-mode-find-file-other-window
|
||||
cvs-remove-file -> cvs-mode-remove-file
|
||||
cvs-status -> cvs-mode-status
|
||||
cvs-remove-handled -> cvs-mode-remove-handled
|
||||
cvs-unmark -> cvs-mode-unmark
|
||||
|
||||
* pcl-cvs.el (cvs-cvs-diff-flags): Variable deleted.
|
||||
* pcl-cvs.el (cvs-diff-cvs): Use cvs-diff-flags instead.
|
||||
* pcl-cvs.texinfo (Customization): Update the doc.
|
||||
|
||||
* pcl-cvs.el (cvs-diff-cvs): Handle exit status 0 (no diffs), 1
|
||||
(diffs) and other (error).
|
||||
* pcl-cvs.el (cvs-execute-list): Add support for this kind of
|
||||
thing.
|
||||
|
||||
* Revert buffers for committed files:
|
||||
* pcl-cvs.el (cvs-auto-revert-after-commit): New variable.
|
||||
* pcl-cvs.texinfo (Committing changes, Customization): Document
|
||||
it.
|
||||
* pcl-cvs.el (cvs-after-commit-function): New function.
|
||||
|
||||
* pcl-cvs.el (cvs-execute-list): Return the exit status or nil.
|
||||
* pcl-cvs.el (cvs-edit-done, cvs-diff-cvs, cvs-remove-file,
|
||||
cvs-undo-local-changes, cvs-add, cvs-status, cvs-log): Use the
|
||||
exit status to generate an error message.
|
||||
|
||||
|
||||
* pcl-cvs.el (cvs-do-update): It should be "cvs -n update -l", not
|
||||
"cvs -l update -n". Put the -n and/or -l in the message that is
|
||||
displayed in the *cvs* buffer during the update.
|
||||
|
||||
Sat Aug 1 00:55:49 1992 Per Cederqvist (ceder@robert)
|
||||
|
||||
* cookie.el (cookie-sort): New function.
|
||||
|
||||
* cookie.el (cookie-clear): Rewritten. No longer clears all local
|
||||
variables.
|
||||
|
||||
Tue Jul 28 17:21:17 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el (cvs-parse-stderr): Try to handle the output from RCS
|
||||
when it is compiled without DIFF3_BIN and a conflict occurs.
|
||||
|
||||
* pcl-cvs.texinfo (Getting Started): Fixed typo.
|
||||
|
||||
* pcl-cvs-startup.el (cvs-update-other-window): Make the autoload
|
||||
be interactive.
|
||||
|
||||
Mon Jul 27 19:36:40 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el (cvs-revert-updated-buffers, cvs-revert-fileinfo):
|
||||
New functions.
|
||||
* pcl-cvs.texinfo (Reverting your buffers): Document it.
|
||||
|
||||
* pcl-cvs.el (cvs-fileinfo->full-path): New function.
|
||||
* pcl-cvs.el (cvs-full-path): Use it.
|
||||
|
||||
* cookie.el (cookie-map, cookie-map-reverse): Better doc-
|
||||
string. Removed the unused local variable 'result'.
|
||||
|
||||
* compile-all.el: Renamed elib-files to files-to-compare.
|
||||
* compile-all.el (compile-pcl-cvs): Bind load-path in a let
|
||||
statement instead of globally.
|
||||
|
||||
Thu Jul 23 19:02:41 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el (cvs-do-update): Check that CVSROOT is set.
|
||||
* pcl-cvs.el (cvs-diff-cvs): Check that cvs-cvs-diff-flags is a
|
||||
list.
|
||||
* pcl-cvs.el (cvs-diff-backup): Check that cvs-diff-flags is a
|
||||
list.
|
||||
|
||||
Tue Jul 21 11:27:39 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el (cvs-parse-error): Make the *cvs* buffer writeable
|
||||
before trying to write the email message. Require sendmail before
|
||||
trying to switch to mail-mode.
|
||||
|
||||
* pcl-cvs.el (cvs-do-update): Check that cvs-program exists.
|
||||
|
||||
* pcl-cvs.el (cvs-skip-line): Fixed bracketing error.
|
||||
|
||||
Mon Jul 20 10:31:51 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* Release 1.03.
|
||||
|
||||
* pcl-cvs.el, cookie.el: Indentation fixes.
|
||||
|
||||
* Makefile (pcl-cvs-$(VER)): Include NEWS in the distribution.
|
||||
|
||||
* pcl-cvs.el (cvs-rm-program): Deleted.
|
||||
* pcl-cvs.el (cvs-rmdir-program, cvs-lock-file): New variables.
|
||||
|
||||
* Handle lock files in a nicer way:
|
||||
* pcl-cvs.el (cvs-update-filter, cvs-delete-lock,
|
||||
cvs-lock-file-p): New functions.
|
||||
* pcl-cvs.el (cvs-do-update, cvs-sentinel): Redirect stdout to the
|
||||
temporary file, not stderr. Use cvs-update-filter.
|
||||
* pcl-cvs.el (cvs-parse-update): New arguments.
|
||||
* pcl-cvs.el (cvs-parse-buffer): Renamed to cvs-parse-update.
|
||||
* pcl-cvs.el (cvs-stderr-file): Renamed to cvs-stdout-file.
|
||||
* pcl-cvs.texinfo (Miscellaneous commands, Updating the
|
||||
directory): Document cvs-delete-lock.
|
||||
|
||||
* pcl-cvs.el (cvs-mode): Don't reset buffer-read-only.
|
||||
|
||||
* pcl-cvs.el (cvs-find-file-other-window): Don't save-some-buffers.
|
||||
|
||||
Thu Jul 16 00:19:58 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el, test-cookie-el: Use the new names from cookie.el.
|
||||
|
||||
* cookie.el: Big Renaming Time!
|
||||
External functions:
|
||||
cookie-next -> tin-next
|
||||
cookie-previous -> tin-previous
|
||||
cookie-nth -> tin-nth
|
||||
cookie-delete -> tin-delete
|
||||
cookie-filter-tins -> tin-filter
|
||||
cookie-get-selection -> tin-get-selection
|
||||
cookie-start-marker -> tin-start-marker
|
||||
cookie-end-marker -> tin-end-marker
|
||||
cookie-invalidate-tins -> tin-invalidate-tins
|
||||
cookie-collect-tins -> tin-collect
|
||||
cookie-collect-cookies -> cookie-collect
|
||||
Internal functions:
|
||||
cookie-create-tin -> cookie-create-wrapper
|
||||
cookie-tin-start-marker -> cookie-wrapper-start-marker
|
||||
cookie-tin-cookie-safe -> cookie-wrapper-cookie-safe
|
||||
cookie-tin-cookie -> cookie-wrapper-cookie
|
||||
set-cookie-tin-start-marker -> cookie-wrapper-set-start-marker
|
||||
set-cookie-tin-cookie -> cookie-wrapper-set-cookie
|
||||
cookie-tin-p -> cookie-wrapper-p
|
||||
cookie-create-tin-and-insert -> cookie-create-wrapper-and-insert
|
||||
|
||||
* pcl-cvs.el (cvs-find-file, cvs-find-file-other-window): Signal
|
||||
an appropriate error message if the *cvs* buffer is empty.
|
||||
|
||||
* cookie.el (cookie-create): Make the buffer read-only.
|
||||
* cookie.el (cookie-create-tin-and-insert, cookie-refresh,
|
||||
cookie-delete-tin-internal, cookie-refresh-tin): Bind
|
||||
buffer-read-only to nil while changing the contents of
|
||||
the buffer.
|
||||
|
||||
* pcl-cvs.el (cvs-byte-compile-files): New function.
|
||||
* pcl-cvs.texinfo (Miscellaneous commands): Document it.
|
||||
|
||||
* pcl-cvs.el (cvs-diff-ignore-marks): New variable.
|
||||
* pcl-cvs.el (cvs-diff-cvs, cvs-diff-backup): Don't consider
|
||||
marked files to be selected if a prefix argument is given XOR the
|
||||
variable cvs-diff-ignore-marks is non-nil.
|
||||
* pcl-cvs.el (cvs-get-marked): New optional argument `ignore-marks'.
|
||||
* pcl-cvs.texinfo (Customization, Viewing differences): Document
|
||||
this behaviour.
|
||||
|
||||
* pcl-cvs.el (cvs-undo-local-changes): New function.
|
||||
* pcl-cvs.texinfo (Undoing changes): Document
|
||||
cvs-undo-local-changes.
|
||||
* pcl-cvs.el (cvs-mode-map): cvs-unmark-all-files moved from "U"
|
||||
to "ESC DEL". cvs-undo-local-changes bound to "U".
|
||||
* pcl-cvs.texinfo (Marking files): Document ESC DEL.
|
||||
|
||||
* pcl-cvs.el (cvs-skip-line): New arguments. All callers updated.
|
||||
Now calls cvs-parse-error if a parse error occurs.
|
||||
* pcl-cvs.el (cvs-parse-error): New function that creates a bug
|
||||
report.
|
||||
* pcl-cvs.el (cvs-parse-stderr, cvs-parse-stdout): New arguments.
|
||||
The only caller (cvs-parse-buffer) updated. Call cvs-parse-error
|
||||
in case of parse error.
|
||||
|
||||
* pcl-cvs.el (pcl-cvs-version): New variable.
|
||||
|
||||
* cookie.el (cookie-create): Kill all local variables in the buffer.
|
||||
|
||||
Fri Jul 10 11:17:40 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* Release 1.03beta1.
|
||||
|
||||
Thu Jul 9 03:12:00 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el (cvs-update-running): New variable.
|
||||
* pcl-cvs.el (cvs-do-update): Use it instead of the previous local
|
||||
variable cvs-process (that no longer exists). Make sure that only
|
||||
one `cvs update' runs at any given moment.
|
||||
* pcl-cvs.el (cvs-sentinel): Reset cvs-update-running when the
|
||||
update process exits.
|
||||
|
||||
* pcl-cvs.el (cvs-update): Switch to the *cvs* buffer.
|
||||
* pcl-cvs.el (cvs-update-other-window): New function.
|
||||
* pcl-cvs-startup.el (cvs-update-other-window): Added a autoload
|
||||
for it.
|
||||
* pcl-cvs.el (cvs-do-update): Don't pop up any buffer in a window
|
||||
- let cvs-update or cvs-update-other-window handle that. Also
|
||||
don't kill the *cvs* buffer, but rather insert a "Running cvs..."
|
||||
message into it.
|
||||
* pcl-cvs.el (cvs-parse-buffer): Don't change the window
|
||||
configuration.
|
||||
|
||||
* pcl-cvs.el (cvs-create-fileinfo, cvs-pp, cvs-fileninfo->type):
|
||||
New type for a fileinfo: MESSAGE.
|
||||
|
||||
* pcl-cvs.el (cvs-cvs-buffer): Deleted the variable. Use
|
||||
cvs-buffer-name instead. (I no longer have any plans to allow more
|
||||
than one cvs update to run at the same time - things only get
|
||||
confusing). Changed all places where cvs-cvs-buffer was used.
|
||||
|
||||
* pcl-cvs.el: Take care of update programs (the -u option in the
|
||||
modules file):
|
||||
* pcl-cvs.el (cvs-update-prog-output-skip-regexp): New variable.
|
||||
* pcl-cvs.el (cvs-parse-stdout): Skip output from the update
|
||||
program (using cvs-update-prog-output-skip-regexp).
|
||||
* pcl-cvs.texinfo (Future enhancements): Document that the
|
||||
solution is not as good as it should be.
|
||||
* pcl-cvs.texinfo (Customization): Document the variable.
|
||||
|
||||
Wed Jul 8 20:29:44 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.el (cvs-do-update): Check that this-dir really exists
|
||||
and is a directory, and that this-dir/CVS exists and is a
|
||||
directory.
|
||||
|
||||
Tue Jul 7 01:02:24 1992 Per Cederqvist (ceder@robin)
|
||||
|
||||
* pcl-cvs.texinfo (Customization): Document TMPDIR.
|
||||
|
||||
* This chunk of modifications should make it possible to run
|
||||
pcl-cvs on hosts that do not line-buffer stdout (such as
|
||||
DECstation). They work by diverting stdout and stderr from
|
||||
`cvs update' and later sorting them together.
|
||||
* pcl-cvs.el (cvs-parse-stderr): Don't fail to parse conflict
|
||||
data.
|
||||
* pcl-cvs.el (cvs-remove-stdout-shadows, cvs-shadow-entry-p): New
|
||||
functions.
|
||||
* pcl-cvs.el (cvs-parse-buffer): Use it.
|
||||
* pcl-cvs.el (cvs-remove-empty-directories): New function.
|
||||
* pcl-cvs.el (cvs-remove-handled, cvs-parse-buffer): Use it.
|
||||
* pcl-cvs.el (cvs-get-current-dir): New argument ROOT-DIR. All
|
||||
calls to cvs-get-current-dir updated.
|
||||
* pcl-cvs.el (cvs-do-update): Allocate a tmp file. Use cvs-shell
|
||||
(typically /bin/sh) to redirect stderr from CVS to the tmp file.
|
||||
* pcl-cvs.el (cvs-sentinel): Handle the tmp file. Remove it when
|
||||
it is parsed.
|
||||
* pcl-cvs.el (cvs-parse-buffer): New argument STDERR-BUFFER. All
|
||||
calls to cvs-parse-buffer updated. Rewritten to handle the
|
||||
separation of stderr and stdout.
|
||||
* pcl-cvs.el (cvs-shell, cvs-stderr-file): New variables.
|
||||
* pcl-cvs.el (cvs-compare-fileinfos, cvs-parse-stderr,
|
||||
cvs-parse-stdout): New functions.
|
||||
|
||||
* pcl-cvs.el (cvs-parse-buffer): Some modifications for output
|
||||
from RCS 5.6.
|
||||
|
||||
Tue Apr 7 09:11:27 1992 Per Cederqvist (ceder@leopold)
|
||||
|
||||
* Release 1.02.
|
||||
|
@ -4,46 +4,50 @@ Installation of the pcl-cvs program
|
||||
===================================
|
||||
|
||||
1. Edit the file `Makefile' to reflect the situation at your site.
|
||||
The only things you have to change is the definition of
|
||||
`lispdir' and `infodir'. The elisp files will be copied to
|
||||
`lispdir', and the info file to `infodir'.
|
||||
The only things you have to change is the definition of `lispdir'
|
||||
and `infodir'. The elisp files will be copied to `lispdir', and
|
||||
the info file to `infodir'.
|
||||
|
||||
2. Configure pcl-cvs.el
|
||||
|
||||
There are a couple of paths that you have to check to make
|
||||
sure that they match you system. They appear early in the file
|
||||
There are a couple of paths that you have to check to make sure
|
||||
that they match you system. They appear early in the file
|
||||
pcl-cvs.el.
|
||||
|
||||
*NOTE:* If your system is running emacs 18.57 or earlier
|
||||
you MUST uncomment the line that says:
|
||||
*NOTE:* If your system is running emacs 18.57 or earlier you
|
||||
MUST uncomment the line that says:
|
||||
|
||||
(setq delete-exited-processes nil)
|
||||
|
||||
Setting `delete-exited-processes' to `nil' works around a bug
|
||||
in emacs that causes it to dump core. The bug was fixed in
|
||||
emacs 18.58.
|
||||
Setting `delete-exited-processes' to `nil' works around a bug in
|
||||
emacs that causes it to dump core. The bug was fixed in emacs
|
||||
18.58.
|
||||
|
||||
3. Type `make install' in the source directory. This will
|
||||
3. Release 1.05 and later of pcl-cvs requires parts of the Elib
|
||||
library, version 0.07 or later. Elib is available via anonymous
|
||||
ftp from prep.ai.mit.edu in `pub/gnu/elib-0.07.tar.z', and from
|
||||
a lot of other sites that mirrors prep. Get Elib, and install
|
||||
it, before proceeding.
|
||||
|
||||
4. Type `make install' in the source directory. This will
|
||||
byte-compile all `.el' files and copy both the `.el' and the
|
||||
`.elc' into the directory you specified in step 1.
|
||||
|
||||
If you don't want to install the `.el' files but only the
|
||||
`.elc' files (the byte-compiled files), you can type ``make
|
||||
If you don't want to install the `.el' files but only the `.elc'
|
||||
files (the byte-compiled files), you can type ``make
|
||||
install_elc'' instead of ``make install''.
|
||||
|
||||
If you only want to create the compiled elisp files, but
|
||||
don't want to install them, you can type `make elcfiles'
|
||||
instead. This is what happens if you only type `make' without
|
||||
parameters.
|
||||
If you only want to create the compiled elisp files, but don't
|
||||
want to install them, you can type `make elcfiles' instead.
|
||||
This is what happens if you only type `make' without parameters.
|
||||
|
||||
4. Edit the file `default.el' in your emacs lisp directory (usually
|
||||
5. Edit the file `default.el' in your emacs lisp directory (usually
|
||||
`/usr/gnu/emacs/lisp' or something similar) and enter the
|
||||
contents of the file `pcl-cvs-startup.el' into it. It contains
|
||||
a couple of `auto-load's that facilitates the use of pcl-cvs.
|
||||
|
||||
|
||||
|
||||
|
||||
Installation of the on-line manual.
|
||||
===================================
|
||||
|
||||
@ -65,8 +69,6 @@ Installation of the on-line manual.
|
||||
* Pcl-cvs: (pcl-cvs). An Emacs front-end to CVS.
|
||||
|
||||
|
||||
|
||||
|
||||
How to make typeset documentation from pcl-cvs.texinfo
|
||||
======================================================
|
||||
|
||||
@ -81,3 +83,4 @@ manual from `pcl-cvs.texinfo'.
|
||||
postscript printer there is a program, `dvi2ps', which does.
|
||||
There is also a program which comes together with TeX, `dvips',
|
||||
which you can use.
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Makefile,v 1.2 1992/04/07 20:49:07 berliner Exp
|
||||
# Makefile for pcl-cvs release 1.02.
|
||||
# Copyright (C) 1992 Per Cederqvist
|
||||
# @(#) Id: dist-makefile,v 1.19 1993/05/31 22:43:45 ceder Exp
|
||||
# Makefile for pcl-cvs release 1.05.
|
||||
# Copyright (C) 1992, 1993 Per Cederqvist
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@ -26,6 +26,10 @@ lispdir = /usr/local/lib/elisp
|
||||
prefix=/usr/local
|
||||
infodir = $(prefix)/info
|
||||
|
||||
# Used to byte-compile files.
|
||||
|
||||
EMACS=emacs
|
||||
|
||||
#
|
||||
# The rest of this file should not need to be modified.
|
||||
#
|
||||
@ -33,8 +37,8 @@ infodir = $(prefix)/info
|
||||
# Just in case...
|
||||
SHELL = /bin/sh
|
||||
|
||||
ELFILES = pcl-cvs.el cookie.el elib-dll.el elib-node.el
|
||||
ELCFILES = pcl-cvs.elc cookie.elc elib-dll.elc elib-node.elc
|
||||
ELFILES = pcl-cvs.el pcl-cvs-lucid.el
|
||||
ELCFILES = pcl-cvs.elc pcl-cvs-lucid.elc
|
||||
INFOFILES = pcl-cvs
|
||||
TEXTMPS = pcl-cvs.aux pcl-cvs.log pcl-cvs.toc pcl-cvs.dvi pcl-cvs.cp \
|
||||
pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky pcl-cvs.pg \
|
||||
@ -45,7 +49,7 @@ INSTALL = install
|
||||
INSTALL_DATA = $(INSTALL)
|
||||
|
||||
elcfiles:
|
||||
emacs -batch -l ./compile-all.el -f compile-pcl-cvs
|
||||
$(EMACS) -batch -l ./compile-all.el -f compile-pcl-cvs
|
||||
|
||||
all: elcfiles info
|
||||
|
||||
@ -66,6 +70,7 @@ info pcl-cvs: pcl-cvs.texinfo
|
||||
makeinfo +fill-column=70 pcl-cvs.texinfo
|
||||
|
||||
pcl-cvs.dvi: pcl-cvs.texinfo
|
||||
tex pcl-cvs.texinfo
|
||||
tex pcl-cvs.texinfo
|
||||
-texindex pcl-cvs.cp pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky \
|
||||
pcl-cvs.pg
|
||||
|
@ -1,6 +1,10 @@
|
||||
README,v 1.2 1992/04/07 20:49:09 berliner Exp
|
||||
@(#) Id: README,v 1.14 1993/05/31 22:43:36 ceder Exp
|
||||
|
||||
This is the readme file for pcl-cvs, release 1.02.
|
||||
This is the readme file for pcl-cvs, release 1.05.
|
||||
|
||||
This release of pcl-cvs requires Elib 0.07 or later. Elib is no
|
||||
longer distributed with pcl-cvs, since that caused too much confusion.
|
||||
You can get Elib from ftp.lysator.liu.se in pub/emacs/elib-*.tar.?.
|
||||
|
||||
Pcl-cvs is a front-end to CVS version 1.3. It integrates the most
|
||||
frequently used CVS commands into emacs.
|
||||
@ -9,6 +13,16 @@ There is some configuration that needs to be done in pcl-cvs.el to get
|
||||
it to work. See the instructions in file INSTALL.
|
||||
|
||||
Full documentation is in pcl-cvs.texinfo. Since it requires makeinfo
|
||||
2.14 a preformatted info file is also included (pcl-cvs.info).
|
||||
version 2 or 3 a preformatted info file is also included (pcl-cvs.info).
|
||||
|
||||
ceder@lysator.liu.se
|
||||
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
|
||||
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
|
||||
instructions in Elib 0.07 for how to work around the problem.
|
||||
|
||||
Per Cederqvist
|
||||
|
@ -1,9 +1,10 @@
|
||||
;;;; compile-all.el,v 1.2 1992/04/07 20:49:10 berliner Exp
|
||||
;;;; This file byte-compiles all .el files in pcl-cvs release 1.02.
|
||||
;;;; @(#) Id: compile-all.el,v 1.11 1993/05/31 18:40:25 ceder Exp
|
||||
;;;; This file byte-compiles all .el files in pcl-cvs release 1.05.
|
||||
;;;;
|
||||
;;;; Copyright (C) 1991 Inge Wallin
|
||||
;;;;
|
||||
;;;; This file is part of the GNU Emacs lisp library, Elib.
|
||||
;;;; This file was once upon a time part of Elib, but have since been
|
||||
;;;; modified by Per Cederqvist.
|
||||
;;;;
|
||||
;;;; GNU Elib is free software; you can redistribute it and/or modify
|
||||
;;;; it under the terms of the GNU General Public License as published by
|
||||
@ -21,14 +22,11 @@
|
||||
;;;;
|
||||
|
||||
|
||||
(setq elib-files '("elib-node"
|
||||
"elib-dll"
|
||||
"cookie"
|
||||
"pcl-cvs"))
|
||||
(setq files-to-compile '("pcl-cvs" "pcl-cvs-lucid"))
|
||||
|
||||
|
||||
(defun compile-file-if-necessary (file)
|
||||
"Compile the Elib file FILE if necessary.
|
||||
"Compile FILE if necessary.
|
||||
|
||||
This is done if FILE.el is newer than FILE.elc or if FILE.elc doesn't exist."
|
||||
(let ((el-name (concat file ".el"))
|
||||
@ -41,12 +39,14 @@ This is done if FILE.el is newer than FILE.elc or if FILE.elc doesn't exist."
|
||||
|
||||
|
||||
(defun compile-pcl-cvs ()
|
||||
"Byte-compile all uncompiled files of elib.
|
||||
Be sure to have . in load-path since a number of files in elib
|
||||
depend on other files and we always want the newer one even if
|
||||
a previous version of elib exists."
|
||||
"Byte-compile all uncompiled files of pcl-cvs."
|
||||
|
||||
(interactive)
|
||||
(setq load-path (append '(".") load-path))
|
||||
|
||||
;; Be sure to have . in load-path since a number of files
|
||||
;; depend on other files and we always want the newer one even if
|
||||
;; a previous version of pcl-cvs exists.
|
||||
(let ((load-path (append '(".") load-path)))
|
||||
|
||||
(mapcar (function compile-file-if-necessary)
|
||||
elib-files))
|
||||
files-to-compile)))
|
||||
|
@ -1,6 +1,14 @@
|
||||
;;; pcl-cvs-startup.el,v 1.2 1992/04/07 20:49:17 berliner Exp
|
||||
;;; @(#) Id: pcl-cvs-startup.el,v 1.4 1993/05/31 18:40:33 ceder Exp
|
||||
(autoload 'cvs-update "pcl-cvs"
|
||||
"Run a 'cvs update' in the current working directory. Feed the
|
||||
output to a *cvs* buffer and run cvs-mode on it.
|
||||
If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
|
||||
t)
|
||||
|
||||
(autoload 'cvs-update-other-window "pcl-cvs"
|
||||
"Run a 'cvs update' in the current working directory. Feed the
|
||||
output to a *cvs* buffer, display it in the other window, and run
|
||||
cvs-mode on it.
|
||||
|
||||
If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
|
||||
t)
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
|
||||
@comment pcl-cvs.texinfo,v 1.2 1992/04/07 20:49:23 berliner Exp
|
||||
@comment Id: pcl-cvs.texinfo,v 1.45 1993/05/31 22:38:15 ceder Exp
|
||||
@comment Documentation for the GNU Emacs CVS mode.
|
||||
@comment Copyright (C) 1992 Per Cederqvist
|
||||
|
||||
@ -62,12 +62,12 @@ Free Software Foundation instead of in the original English.
|
||||
@sp
|
||||
@center @titlefont{pcl-cvs - the Emacs Front-End to CVS}
|
||||
@sp 2
|
||||
@center release 1.02
|
||||
@center release 1.05
|
||||
@comment -release-
|
||||
@sp 3
|
||||
@center Per Cederqvist
|
||||
@sp 3
|
||||
@center last updated 29 Mar 1992
|
||||
@center last updated 31 May 1993
|
||||
@comment -date-
|
||||
|
||||
@comment The following two commands start the copyright page
|
||||
@ -104,7 +104,7 @@ Free Software Foundation instead of in the original English.
|
||||
@ifinfo
|
||||
This info manual describes pcl-cvs which is a GNU Emacs front-end to
|
||||
CVS. It works with CVS version 1.3. This manual is updated to release
|
||||
1.02 of pcl-cvs.
|
||||
1.05 of pcl-cvs.
|
||||
@end ifinfo
|
||||
@comment -release-
|
||||
|
||||
@ -119,8 +119,7 @@ CVS. It works with CVS version 1.3. This manual is updated to release
|
||||
|
||||
* Customization:: How you can tailor pcl-cvs to suit your needs.
|
||||
* Future enhancements:: Future enhancements of pcl-cvs.
|
||||
* Reporting bugs and ideas:: Where to report bugs.
|
||||
|
||||
* Bugs:: Bugs (known and unknown).
|
||||
* Function and Variable Index:: List of functions and variables.
|
||||
* Concept Index:: List of concepts.
|
||||
* Key Index:: List of keystrokes.
|
||||
@ -155,9 +154,13 @@ Commands
|
||||
* Editing files:: Loading files into Emacs.
|
||||
* Getting info about files:: Display the log and status of files.
|
||||
* Adding and removing files:: Adding and removing files
|
||||
* Undoing changes:: Undoing changes
|
||||
* Removing handled entries:: Uninteresting lines can easily be removed.
|
||||
* Ignoring files:: Telling CVS to ignore generated files.
|
||||
* Viewing differences:: Commands to @samp{diff} different versions.
|
||||
* Emerge::
|
||||
* Reverting your buffers:: Reverting your buffers
|
||||
* Miscellaneous commands:: Miscellaneous commands
|
||||
@end menu
|
||||
|
||||
@node Copying, Installation, Top, Top
|
||||
@ -600,6 +603,13 @@ Setting @code{delete-exited-processes} to @code{nil} works around a bug
|
||||
in emacs that causes it to dump core. The bug was fixed in emacs
|
||||
18.58.@refill
|
||||
|
||||
@item
|
||||
Release 1.05 and later of pcl-cvs requires parts of the Elib library,
|
||||
version 0.07 or later. Elib is available via anonymous ftp from
|
||||
prep.ai.mit.edu in @file{pub/gnu/elib-0.07.tar.z}, and from a lot of
|
||||
other sites that mirrors prep. Get Elib, and install it, before
|
||||
proceeding.
|
||||
|
||||
@item
|
||||
Type @samp{make install} in the source directory. This will
|
||||
byte-compile all @file{.el} files and copy both the @file{.el} and the
|
||||
@ -701,7 +711,7 @@ frequently used CVS commands into emacs.
|
||||
|
||||
Contributions to the package are welcome. I have limited time to work
|
||||
on this project, but I will gladly add any code that you contribute to
|
||||
me to this package (@pxref{Reporting bugs and ideas}).
|
||||
me to this package (@pxref{Bugs}).
|
||||
|
||||
The following persons have made contributions to pcl-cvs.
|
||||
|
||||
@ -724,8 +734,17 @@ the files @file{elib-node.el} and @file{compile-all.el}. The file
|
||||
Linus Tolke (@samp{linus@@lysator.liu.se}) contributed useful comments
|
||||
on both the functionality and the documentation.@refill
|
||||
|
||||
@item
|
||||
Jamie Zawinski (@samp{jwz@@lucid.com}) contributed
|
||||
@file{pcl-cvs-lucid.el}.
|
||||
|
||||
@item
|
||||
Leif Lonnblad contributed RCVS support.
|
||||
@end itemize
|
||||
|
||||
Apart from these, a lot of people have send me suggestions, ideas,
|
||||
requests, bug reports and encouragement. Thanks a lot! Without your
|
||||
there would be no new releases of pcl-cvs.
|
||||
|
||||
@node Archives, , Contributors, About pcl-cvs
|
||||
@comment node-name, next, previous, up
|
||||
@ -736,11 +755,6 @@ on both the functionality and the documentation.@refill
|
||||
@cindex Getting pcl-cvs
|
||||
@cindex Email archives
|
||||
|
||||
This release of pcl-cvs is included in the CVS 1.3 distribution.
|
||||
However, since pcl-cvs has had less time to mature (the first line of
|
||||
code was written less than a year ago) it is likely that there will be a
|
||||
new release of pcl-cvs before the next release of CVS.
|
||||
|
||||
The latest release of pcl-cvs can be fetched via anonymous ftp from
|
||||
@code{ftp.lysator.liu.se}, (IP no. 130.236.254.1) in the directory
|
||||
@code{pub/emacs}. If you don't live in Scandinavia you should probably
|
||||
@ -765,7 +779,7 @@ Pcl-cvs is only useful once you have checked out a module. So before
|
||||
you invoke it you must have a copy of a module somewhere in the file
|
||||
system.
|
||||
|
||||
You invoke pcl-cvs by typing @kbd{M-x pcl-cvs RET}. If your emacs
|
||||
You invoke pcl-cvs by typing @kbd{M-x cvs-update RET}. If your emacs
|
||||
responds with @samp{[No match]} your system administrator has not
|
||||
installed pcl-cvs properly. Try @kbd{M-x load-library RET pcl-cvs RET}.
|
||||
If that also fails - talk to your root. If it succeeds you might put
|
||||
@ -783,7 +797,7 @@ files that have been checked out from a CVS archive.) The output from
|
||||
@samp{*cvs*}. It might look something like this:
|
||||
|
||||
@example
|
||||
PCL-CVS release 1.02.
|
||||
PCL-CVS release 1.05.
|
||||
@comment -release-
|
||||
|
||||
In directory /users/ceder/FOO/test:
|
||||
@ -979,16 +993,22 @@ you can use in pcl-cvs. They are grouped together by type.
|
||||
* Editing files:: Loading files into Emacs.
|
||||
* Getting info about files:: Display the log and status of files.
|
||||
* Adding and removing files:: Adding and removing files
|
||||
* Undoing changes:: Undoing changes
|
||||
* Removing handled entries:: Uninteresting lines can easily be removed.
|
||||
* Ignoring files:: Telling CVS to ignore generated files.
|
||||
* Viewing differences:: Commands to @samp{diff} different versions.
|
||||
* Emerge::
|
||||
* Reverting your buffers:: Reverting your buffers
|
||||
* Miscellaneous commands:: Miscellaneous commands
|
||||
@end menu
|
||||
|
||||
@node Updating the directory, Movement commands, Commands, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@section Updating the directory
|
||||
@findex cvs-update
|
||||
@findex cvs-update-no-prompt
|
||||
@findex cvs-mode-update-no-prompt
|
||||
@findex cvs-delete-lock
|
||||
@cindex Getting the *cvs* buffer
|
||||
@kindex g - Rerun @samp{cvs update}
|
||||
|
||||
|
||||
@ -1007,11 +1027,21 @@ argument to it (e.g., by typing @kbd{C-u M-x cvs-update RET}).@refill
|
||||
All other commands in pcl-cvs requires that you have a @samp{*cvs*}
|
||||
buffer. This is the command that you use to get one.@refill
|
||||
|
||||
CVS uses lock files in the repository to ensure the integrity of the
|
||||
data files in the repository. They might be left behind i.e. if a
|
||||
workstation crashes in the middle of a CVS operation. CVS outputs a
|
||||
message when it is waiting for a lock file to go away. Pcl-cvs will
|
||||
show the same message in the *cvs* buffer, together with instructions
|
||||
for deleting the lock files. You should normally not have to delete
|
||||
them manually --- just wait a little while and the problem should fix
|
||||
itself. But if the lock files doesn't disappear you can delete them
|
||||
with @kbd{M-x cvs-delete-lock RET}.@refill
|
||||
|
||||
@item g
|
||||
This will run @samp{cvs update} again. It will always use the same
|
||||
buffer that was used with the previous @samp{cvs update}. Give a prefix
|
||||
argument to avoid descending into subdirectories. This runs the command
|
||||
@samp{cvs-update-no-prompt}.@refill
|
||||
@samp{cvs-mode-update-no-prompt}.@refill
|
||||
@end table
|
||||
@node Movement commands, Marking files, Updating the directory, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@ -1051,13 +1081,13 @@ These keys move one file backward, towards the beginning of the buffer
|
||||
@kindex m - marking a file
|
||||
@kindex M - marking all files
|
||||
@kindex u - unmark a file
|
||||
@kindex U - unmark all files
|
||||
@kindex ESC DEL - unmark all files
|
||||
@kindex DEL - unmark previous file
|
||||
@findex cvs-mark
|
||||
@findex cvs-unmark
|
||||
@findex cvs-mark-all-files
|
||||
@findex cvs-unmark-all-files
|
||||
@findex cvs-unmark-up
|
||||
@findex cvs-mode-mark
|
||||
@findex cvs-mode-unmark
|
||||
@findex cvs-mode-mark-all-files
|
||||
@findex cvs-mode-unmark-all-files
|
||||
@findex cvs-mode-unmark-up
|
||||
|
||||
Pcl-cvs works on a set of @dfn{selected files} (@pxref{Selected files}).
|
||||
You can mark and unmark files with these commands:
|
||||
@ -1066,22 +1096,22 @@ You can mark and unmark files with these commands:
|
||||
@item m
|
||||
This marks the file that the cursor is positioned on. If the cursor is
|
||||
positioned on a directory all files in that directory will be marked.
|
||||
(@code{cvs-mark}).
|
||||
(@code{cvs-mode-mark}).
|
||||
|
||||
@item u
|
||||
Unmark the file that the cursor is positioned on. If the cursor is on a
|
||||
directory, all files in that directory will be unmarked.
|
||||
(@code{cvs-unmark}).@refill
|
||||
(@code{cvs-mode-unmark}).@refill
|
||||
|
||||
@item M
|
||||
Mark @emph{all} files in the buffer (@code{cvs-mark-all-files}).
|
||||
Mark @emph{all} files in the buffer (@code{cvs-mode-mark-all-files}).
|
||||
|
||||
@item U
|
||||
Unmark @emph{all} files (@code{cvs-unmark-all-files}).
|
||||
@item @key{ESC} @key{DEL}
|
||||
Unmark @emph{all} files (@code{cvs-mode-unmark-all-files}).
|
||||
|
||||
@item @key{DEL}
|
||||
Unmark the file on the previous line, and move point to that line
|
||||
(@code{cvs-unmark-up}).
|
||||
(@code{cvs-mode-unmark-up}).
|
||||
@end table
|
||||
|
||||
@node Committing changes, Editing files, Marking files, Commands
|
||||
@ -1089,12 +1119,14 @@ Unmark the file on the previous line, and move point to that line
|
||||
@section Committing changes
|
||||
@cindex Committing changes
|
||||
@cindex Ci
|
||||
@findex cvs-commit
|
||||
@findex cvs-mode-commit
|
||||
@kindex c - commit files
|
||||
@vindex cvs-erase-input-buffer (variable)
|
||||
@vindex cvs-auto-revert-after-commit (variable)
|
||||
@cindex Commit buffer
|
||||
@cindex Edit buffer
|
||||
@cindex Erasing commit message
|
||||
@cindex Reverting buffers after commit
|
||||
|
||||
@table @kbd
|
||||
@item c
|
||||
@ -1102,7 +1134,7 @@ All files that have a "need to be checked in"-marker (@pxref{Buffer
|
||||
contents}) can be checked in with the @kbd{c} command. It checks in all
|
||||
selected files (@pxref{Selected files}) (except those who lack the
|
||||
"ci"-marker - they are ignored). Pressing @kbd{c} causes
|
||||
@code{cvs-commit} to be run.@refill
|
||||
@code{cvs-mode-commit} to be run.@refill
|
||||
|
||||
When you press @kbd{c} you will get a buffer called
|
||||
@samp{*cvs-commit-message*}. Enter the log message for the file(s) in
|
||||
@ -1111,10 +1143,18 @@ commit the files (using @code{cvs-edit-done}).
|
||||
|
||||
Normally the @samp{*cvs-commit-message*} buffer will retain the log
|
||||
message from the previous commit, but if the variable
|
||||
@code{cvs-erase-input-buffer} is set to a non-nil value the buffer will
|
||||
be erased. Point and mark will always be located around the entire
|
||||
buffer so that you can easily erase it with @kbd{C-w}
|
||||
@code{cvs-erase-input-buffer} is set to a non-@code{nil} value the
|
||||
buffer will be erased. Point and mark will always be located around the
|
||||
entire buffer so that you can easily erase it with @kbd{C-w}
|
||||
(@samp{kill-region}).@refill
|
||||
|
||||
If you are editing the files in your emacs an automatic
|
||||
@samp{revert-buffer} will be performed. (If the file contains
|
||||
@samp{$@asis{Id}$} keywords @samp{cvs commit} will write a new file with
|
||||
the new values substituted. The auto-revert makes sure that you get
|
||||
them into your buffer). The revert will not occur if you have modified
|
||||
your buffer, or if @samp{cvs-auto-revert-after-commit} is set to
|
||||
@samp{nil}.@refill
|
||||
@end table
|
||||
|
||||
@node Editing files, Getting info about files, Committing changes, Commands
|
||||
@ -1126,9 +1166,9 @@ buffer so that you can easily erase it with @kbd{C-w}
|
||||
@cindex Loading files
|
||||
@cindex Dired
|
||||
@cindex Invoking dired
|
||||
@findex cvs-find-file
|
||||
@findex cvs-find-file-other-window
|
||||
@findex cvs-add-change-log-entry-other-window
|
||||
@findex cvs-mode-find-file
|
||||
@findex cvs-mode-find-file-other-window
|
||||
@findex cvs-mode-add-change-log-entry-other-window
|
||||
@kindex f - find file or directory
|
||||
@kindex o - find file in other window
|
||||
@kindex A - add ChangeLog entry
|
||||
@ -1144,17 +1184,17 @@ Find the file that the cursor points to. Run @samp{dired}
|
||||
@ifinfo
|
||||
(@pxref{Dired,,,Emacs})
|
||||
@end ifinfo
|
||||
if the cursor points to a directory (@code{cvs-find-file}).@refill
|
||||
if the cursor points to a directory (@code{cvs-mode-find-file}).@refill
|
||||
|
||||
@item o
|
||||
Like @kbd{f}, but use another window
|
||||
(@code{cvs-find-file-other-window}).@refill
|
||||
(@code{cvs-mode-find-file-other-window}).@refill
|
||||
|
||||
@item A
|
||||
Invoke @samp{add-change-log-entry-other-window} to edit a
|
||||
@samp{ChangeLog} file. The @samp{ChangeLog} will be found in the
|
||||
directory of the file the cursor points to.
|
||||
(@code{cvs-add-change-log-entry-other-window}).@refill
|
||||
(@code{cvs-mode-add-change-log-entry-other-window}).@refill
|
||||
@end table
|
||||
|
||||
@node Getting info about files, Adding and removing files, Editing files, Commands
|
||||
@ -1165,8 +1205,8 @@ directory of the file the cursor points to.
|
||||
@cindex Getting status
|
||||
@kindex l - run @samp{cvs log}
|
||||
@kindex s - run @samp{cvs status}
|
||||
@findex cvs-log
|
||||
@findex cvs-status
|
||||
@findex cvs-mode-log
|
||||
@findex cvs-mode-status
|
||||
|
||||
Both of the following commands can be customized.
|
||||
@xref{Customization}.@refill
|
||||
@ -1174,14 +1214,14 @@ Both of the following commands can be customized.
|
||||
@table @kbd
|
||||
@item l
|
||||
Run @samp{cvs log} on all selected files, and show the result in a
|
||||
temporary buffer (@code{cvs-log}).
|
||||
temporary buffer (@code{cvs-mode-log}).
|
||||
|
||||
@item s
|
||||
Run @samp{cvs status} on all selected files, and show the result in a
|
||||
temporary buffer (@code{cvs-status}).
|
||||
temporary buffer (@code{cvs-mode-status}).
|
||||
@end table
|
||||
|
||||
@node Adding and removing files, Removing handled entries, Getting info about files, Commands
|
||||
@node Adding and removing files, Undoing changes, Getting info about files, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@section Adding and removing files
|
||||
@cindex Adding files
|
||||
@ -1191,8 +1231,8 @@ temporary buffer (@code{cvs-status}).
|
||||
@cindex Putting files under CVS control
|
||||
@kindex a - add a file
|
||||
@kindex r - remove a file
|
||||
@findex cvs-add
|
||||
@findex cvs-remove-file
|
||||
@findex cvs-mode-add
|
||||
@findex cvs-mode-remove-file
|
||||
|
||||
The following commands are available to make it easy to add and remove
|
||||
files from the CVS repository.
|
||||
@ -1201,7 +1241,7 @@ files from the CVS repository.
|
||||
@item a
|
||||
Add all selected files. This command can be used on @samp{Unknown}
|
||||
files (see @pxref{File status}). The status of the file will change to
|
||||
@samp{Added}, and you will have to use @kbd{c} (@samp{cvs-commit}, see
|
||||
@samp{Added}, and you will have to use @kbd{c} (@samp{cvs-mode-commit}, see
|
||||
@pxref{Committing changes}) to really add the file to the
|
||||
repository.@refill
|
||||
|
||||
@ -1211,7 +1251,7 @@ them) to resurrect them.
|
||||
Selected files that are neither @samp{Unknown} nor @samp{Removed} will
|
||||
be ignored by this command.
|
||||
|
||||
The command that is run is @code{cvs-add}.
|
||||
The command that is run is @code{cvs-mode-add}.
|
||||
|
||||
@item r
|
||||
This command removes the selected files (after prompting for
|
||||
@ -1219,13 +1259,29 @@ confirmation). The files are @samp{rm}ed from your directory and
|
||||
(unless the status was @samp{Unknown}; @pxref{File status}) they will
|
||||
also be @samp{cvs remove}d. If the files were @samp{Unknown} they will
|
||||
disappear from the buffer. Otherwise their status will change to
|
||||
@samp{Removed}, and you must use @kbd{c} (@samp{cvs-commit},
|
||||
@samp{Removed}, and you must use @kbd{c} (@samp{cvs-mode-commit},
|
||||
@pxref{Committing changes}) to commit the removal.@refill
|
||||
|
||||
The command that is run is @code{cvs-remove-file}.
|
||||
The command that is run is @code{cvs-mode-remove-file}.
|
||||
@end table
|
||||
|
||||
@node Removing handled entries, Ignoring files, Adding and removing files, Commands
|
||||
@node Undoing changes, Removing handled entries, Adding and removing files, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@section Undoing changes
|
||||
@cindex Undo changes
|
||||
@cindex Flush changes
|
||||
@kindex U - undo changes
|
||||
@findex cvs-mode-undo-local-changes
|
||||
|
||||
@table @kbd
|
||||
@item U
|
||||
If you have modified a file, and for some reason decide that you don't
|
||||
want to keep the changes, you can undo them with this command. It works
|
||||
by removing your working copy of the file and then getting the latest
|
||||
version from the repository (@code{cvs-mode-undo-local-changes}.
|
||||
@end table
|
||||
|
||||
@node Removing handled entries, Ignoring files, Undoing changes, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@section Removing handled entries
|
||||
@cindex Expunging uninteresting entries
|
||||
@ -1235,8 +1291,9 @@ The command that is run is @code{cvs-remove-file}.
|
||||
@cindex Handled lines, removing them
|
||||
@kindex x - remove processed entries
|
||||
@kindex C-k - remove selected entries
|
||||
@findex cvs-remove-handled
|
||||
@findex cvs-acknowledge
|
||||
@findex cvs-mode-remove-handled
|
||||
@findex cvs-mode-acknowledge
|
||||
@findex cvs-mode-ignore
|
||||
|
||||
@table @kbd
|
||||
@item x
|
||||
@ -1247,13 +1304,13 @@ are removed from the buffer. If a directory becomes empty the heading
|
||||
for that directory is also removed. This makes it easier to get an
|
||||
overview of what needs to be done.
|
||||
|
||||
The command is called @code{cvs-remove-handled}. If
|
||||
@samp{cvs-auto-remove-handled} is set to non-@samp{nil} this will
|
||||
The command is called @code{cvs-mode-remove-handled}. If
|
||||
@samp{cvs-auto-remove-handled} is set to non-@code{nil} this will
|
||||
automatically be performed after every commit.@refill
|
||||
|
||||
@item C-k
|
||||
This command can be used for lines that @samp{cvs-remove-handled} would
|
||||
not delete, but that you want to delete (@code{cvs-acknowledge}).
|
||||
This command can be used for lines that @samp{cvs-mode-remove-handled} would
|
||||
not delete, but that you want to delete (@code{cvs-mode-acknowledge}).
|
||||
@end table
|
||||
|
||||
@node Ignoring files, Viewing differences, Removing handled entries, Commands
|
||||
@ -1269,10 +1326,10 @@ the @file{.cvsignore} doesn't exist it will be created.
|
||||
The @file{.cvsignore} file should normally be added to the repository,
|
||||
but you could ignore it also if you like it better that way.
|
||||
|
||||
This runs @code{cvs-ignore}.
|
||||
This runs @code{cvs-mode-ignore}.
|
||||
@end table
|
||||
|
||||
@node Viewing differences, , Ignoring files, Commands
|
||||
@node Viewing differences, Emerge, Ignoring files, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@section Viewing differences
|
||||
@cindex Diff
|
||||
@ -1280,29 +1337,122 @@ This runs @code{cvs-ignore}.
|
||||
@cindex Viewing differences
|
||||
@kindex d - run @samp{cvs diff}
|
||||
@kindex b - diff backup file
|
||||
@findex cvs-diff-cvs
|
||||
@findex cvs-diff-backup
|
||||
@findex cvs-mode-diff-cvs
|
||||
@findex cvs-mode-diff-backup
|
||||
@vindex cvs-diff-ignore-marks (variable)
|
||||
|
||||
@table @kbd
|
||||
@item d
|
||||
Display a @samp{cvs diff} between the selected files and the RCS version
|
||||
that they are based on. @xref{Customization} describes how you can send
|
||||
flags to @samp{cvs diff}. (The function that does the job is
|
||||
@code{cvs-diff-cvs}).@refill
|
||||
flags to @samp{cvs diff}. If @var{cvs-diff-ignore-marks} is set to a
|
||||
non-@code{nil} value or if a prefix argument is given (but not both) any
|
||||
marked files will not be considered to be selected.
|
||||
(@code{cvs-mode-diff-cvs}).@refill
|
||||
|
||||
@item b
|
||||
If CVS finds a conflict while merging two versions of a file (during a
|
||||
@samp{cvs update}, @pxref{Updating the directory}) it will save the
|
||||
original file in a file called @file{.#@var{FILE}.@var{VERSION}} where
|
||||
@var{FILE} is the name of the file, and @var{VERSION} is the RCS version
|
||||
number that your file was based on.
|
||||
number that your file was based on.@refill
|
||||
|
||||
With the @kbd{b} command you can run a @samp{diff} on the files
|
||||
@file{.#@var{FILE}.@var{VERSION}} and @file{@var{FILE}}. You can get a
|
||||
context- or Unidiff by setting @samp{cvs-diff-flags} -
|
||||
@pxref{Customization}. This command only works on files that have
|
||||
status @samp{Conflict} or @samp{Merged}. The name of the command is
|
||||
@code{cvs-diff-backup}. @refill
|
||||
status @samp{Conflict} or @samp{Merged}.@refill
|
||||
|
||||
If @var{cvs-diff-ignore-marks} is set to a non-@code{nil} value or if a
|
||||
prefix argument is given (but not both) any marked files will not be
|
||||
considered to be selected. (@code{cvs-mode-diff-backup}).@refill
|
||||
@end table
|
||||
|
||||
@node Emerge, Reverting your buffers, Viewing differences, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@section Running emerge
|
||||
@cindex Emerge
|
||||
@cindex Invoking emerge
|
||||
@cindex Conflicts, resolving
|
||||
@cindex Resolving conflicts
|
||||
@kindex e - invoke @samp{emerge}
|
||||
@findex cvs-mode-emerge
|
||||
|
||||
@table @kbd
|
||||
@item e
|
||||
Invoke @samp{emerge} on one file. This command works slightly different
|
||||
depending on the file status.
|
||||
|
||||
@table @asis
|
||||
@item @samp{Modified}
|
||||
Run @samp{emerge-files} with your working file as file A, and the latest
|
||||
revision in the repository as file B.
|
||||
|
||||
@item @samp{Merged}
|
||||
@itemx @samp{Conflict}
|
||||
Run @samp{emerge-files-with-ancestor} with your working file (as it was
|
||||
prior to your invocation of @samp{cvs-update}) as file A, the latest
|
||||
revision in the repository as file B, and the revision that you based
|
||||
your local modifications on as ancestor.
|
||||
@end table
|
||||
|
||||
@strong{Note:} CVS has already performed a merge. The resulting file is
|
||||
not used in any way if you use this command. If you use the @kbd{q}
|
||||
command inside @samp{emerge} (to successfully terminate the merge) the
|
||||
file that CVS created will be overwritten.
|
||||
@end table
|
||||
|
||||
@node Reverting your buffers, Miscellaneous commands, Emerge, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@section Reverting your buffers
|
||||
@findex cvs-mode-revert-updated-buffers
|
||||
@kindex R - revert buffers
|
||||
@cindex Syncing buffers
|
||||
@cindex Reverting buffers
|
||||
|
||||
@table @kbd
|
||||
@item R
|
||||
If you are editing (or just viewing) a file in a buffer, and that file
|
||||
is changed by CVS during a @samp{cvs-update}, all you have to do is type
|
||||
@kbd{R} in the *cvs* buffer to read in the new versions of the
|
||||
files.@refill
|
||||
|
||||
All files that are @samp{Updated}, @samp{Merged} or in @samp{Conflict}
|
||||
are reverted from the disk. Any other files are ignored. Only files
|
||||
that you were already editing are read.@refill
|
||||
|
||||
An error is signalled if you have modified the buffer since it was last
|
||||
changed. (@code{cvs-mode-revert-updated-buffers}).@refill
|
||||
@end table
|
||||
|
||||
@node Miscellaneous commands, , Reverting your buffers, Commands
|
||||
@comment node-name, next, previous, up
|
||||
@section Miscellaneous commands
|
||||
@findex cvs-byte-compile-files
|
||||
@cindex Recompiling elisp files
|
||||
@cindex Byte compilation
|
||||
@cindex Getting rid of lock files
|
||||
@cindex Lock files
|
||||
@kindex q - bury the *cvs* buffer
|
||||
@findex bury-buffer
|
||||
|
||||
@table @kbd
|
||||
@item M-x cvs-byte-compile-files
|
||||
Byte compile all selected files that end in .el.
|
||||
|
||||
@item M-x cvs-delete-lock
|
||||
This command can be used in any buffer, and deletes the lock files that
|
||||
the *cvs* buffer informs you about. You should normally never have to
|
||||
use this command since CVS tries very carefully to always remove the
|
||||
lock files itself.
|
||||
|
||||
You can only use this command when a message in the *cvs* buffer tells
|
||||
you so. You should wait a while before using this command in case
|
||||
someone else is running a cvs command.
|
||||
|
||||
@item q
|
||||
Bury the *cvs* buffer. (@code{bury-buffer}).
|
||||
|
||||
@end table
|
||||
|
||||
@node Customization, Future enhancements, Commands, Top
|
||||
@ -1310,11 +1460,17 @@ status @samp{Conflict} or @samp{Merged}. The name of the command is
|
||||
@chapter Customization
|
||||
@vindex cvs-erase-input-buffer (variable)
|
||||
@vindex cvs-inhibit-copyright-message (variable)
|
||||
@vindex cvs-cvs-diff-flags (variable)
|
||||
@vindex cvs-diff-flags (variable)
|
||||
@vindex cvs-diff-ignore-marks (variable)
|
||||
@vindex cvs-log-flags (variable)
|
||||
@vindex cvs-status-flags (variable)
|
||||
@vindex cvs-auto-remove-handled (variable)
|
||||
@vindex cvs-update-prog-output-skip-regexp (variable)
|
||||
@vindex cvs-cvsroot (variable)
|
||||
@vindex TMPDIR (environment variable)
|
||||
@vindex cvs-auto-revert-after-commit (variable)
|
||||
@vindex cvs-commit-buffer-require-final-newline (variable)
|
||||
@vindex cvs-sort-ignore-file (variable)
|
||||
@cindex Inhibiting the Copyright message.
|
||||
@cindex Copyright message, getting rid of it
|
||||
@cindex Getting rid of the Copyright message.
|
||||
@ -1324,14 +1480,24 @@ status @samp{Conflict} or @samp{Merged}. The name of the command is
|
||||
@cindex Context diff, how to get
|
||||
@cindex Unidiff, how to get
|
||||
@cindex Automatically remove handled files
|
||||
@cindex -u option in modules file
|
||||
@cindex Modules file (-u option)
|
||||
@cindex Update program (-u option in modules file)
|
||||
@cindex Reverting buffers after commit
|
||||
@cindex Require final newline
|
||||
@cindex Automatically inserting newline
|
||||
@cindex Commit message, inserting newline
|
||||
@cindex Sorting the .cvsignore file
|
||||
@cindex .cvsignore file, sorting
|
||||
@cindex Automatically sorting .cvsignore
|
||||
|
||||
If you have an idea about any customization that would be handy but
|
||||
isn't present in this list, please tell me! @xref{Reporting bugs and
|
||||
ideas} for info on how to reach me.@refill
|
||||
isn't present in this list, please tell me! @xref{Bugs} for info on how
|
||||
to reach me.@refill
|
||||
|
||||
@table @samp
|
||||
@item cvs-erase-input-buffer
|
||||
If set to anything else than @samp{nil} the edit buffer will be erased
|
||||
If set to anything else than @code{nil} the edit buffer will be erased
|
||||
before you write the log message (@pxref{Committing changes}).
|
||||
|
||||
@item cvs-inhibit-copyright-message
|
||||
@ -1340,71 +1506,180 @@ a while. Set this variable to @samp{t} if you want to get rid of it.
|
||||
(But don't set this to @samp{t} in the system defaults file - new users
|
||||
should see this message at least once).
|
||||
|
||||
@item cvs-cvs-diff-flags
|
||||
A list of strings to pass as arguments to the @samp{cvs diff} program.
|
||||
This is used by @samp{cvs-diff-cvs} (key @kbd{d}, @pxref{Viewing
|
||||
differences}). If you prefer the Unidiff format you could add this line
|
||||
to your @file{.emacs} file:@refill
|
||||
@item cvs-diff-flags
|
||||
A list of strings to pass as arguments to the @samp{cvs diff} and
|
||||
@samp{diff} programs. This is used by @samp{cvs-mode-diff-cvs} and
|
||||
@samp{cvs-mode-diff-backup} (key @kbd{b}, @pxref{Viewing differences}). If
|
||||
you prefer the Unidiff format you could add this line to your
|
||||
@file{.emacs} file:@refill
|
||||
|
||||
@example
|
||||
(setq cvs-cvs-diff-flags '("-u"))
|
||||
(setq cvs-diff-flags '("-u"))
|
||||
@end example
|
||||
|
||||
@item cvs-diff-flags
|
||||
Like @samp{cvs-cvs-diff-flags}, but passed to @samp{diff}. This is used
|
||||
by @samp{cvs-diff-backup} (key @kbd{b}, @pxref{Viewing differences}).
|
||||
@item cvs-diff-ignore-marks
|
||||
If this variable is non-@code{nil} or if a prefix argument is given (but
|
||||
not both) to @samp{cvs-mode-diff-cvs} or @samp{cvs-mode-diff-backup}
|
||||
marked files are not considered selected.
|
||||
|
||||
@item cvs-log-flags
|
||||
List of strings to send to @samp{cvs log}. Used by @samp{cvs-log} (key
|
||||
@kbd{l}, @pxref{Getting info about files}).
|
||||
List of strings to send to @samp{cvs log}. Used by @samp{cvs-mode-log}
|
||||
(key @kbd{l}, @pxref{Getting info about files}).
|
||||
|
||||
@item cvs-status-flags
|
||||
List of strings to send to @samp{cvs status}. Used by @samp{cvs-status}
|
||||
List of strings to send to @samp{cvs status}. Used by @samp{cvs-mode-status}
|
||||
(key @kbd{s}, @pxref{Getting info about files}).
|
||||
|
||||
@item cvs-auto-remove-handled
|
||||
If this variable is set to any non-@samp{nil} value
|
||||
@samp{cvs-remove-handled} will be called every time you check in files,
|
||||
after the check-in is ready. @xref{Removing handled entries}.@refill
|
||||
If this variable is set to any non-@code{nil} value
|
||||
@samp{cvs-mode-remove-handled} will be called every time you check in
|
||||
files, after the check-in is ready. @xref{Removing handled
|
||||
entries}.@refill
|
||||
|
||||
@item cvs-auto-revert-after-commit
|
||||
If this variable is set to any non-@samp{nil} value any buffers you have
|
||||
that visit a file that is committed will be automatically reverted.
|
||||
This variable is default @samp{t}. @xref{Committing changes}.@refill
|
||||
|
||||
@item cvs-update-prog-output-skip-regexp
|
||||
The @samp{-u} flag in the @file{modules} file can be used to run a command
|
||||
whenever a @samp{cvs update} is performed (see cvs(5)). This regexp
|
||||
is used to search for the last line in that output. It is normally set
|
||||
to @samp{"$"}. That setting is only correct if the command outputs
|
||||
nothing. Note that pcl-cvs will get very confused if the command
|
||||
outputs @emph{anything} to @samp{stderr}.
|
||||
|
||||
@item cvs-cvsroot
|
||||
This variable can be set to override @samp{CVSROOT}. It should be a
|
||||
string. If it is set then everytime a cvs command is run it will be
|
||||
called as @samp{cvs -d @var{cvs-cvsroot}@dots{}} This can be useful if
|
||||
your site has several repositories.
|
||||
|
||||
@item TMPDIR
|
||||
Pcl-cvs uses this @emph{environment variable} to decide where to put the
|
||||
temporary files it needs. It defaults to @file{/tmp} if it is not set.
|
||||
|
||||
@item cvs-commit-buffer-require-final-newline
|
||||
When you enter a log message in the @samp{*cvs-commit-message*} buffer
|
||||
pcl-cvs will normally automatically insert a trailing newline, unless
|
||||
there already is one. This behavior can be controlled via
|
||||
@samp{cvs-commit-buffer-require-final-newline}. If it is @samp{t} (the
|
||||
default behavior), a newline will always be appended. If it is
|
||||
@samp{nil}, newlines will never be appended. Any other value causes
|
||||
pcl-cvs to ask the user whenever there is no trailing newline in the
|
||||
commit message buffer.
|
||||
|
||||
@item cvs-sort-ignore-file
|
||||
If this variable is set to any non-@samp{nil} value the
|
||||
@file{.cvsignore} will always be sorted whenever you use
|
||||
@samp{cvs-mode-ignore} to add a file to it. This option is on by
|
||||
default.
|
||||
|
||||
@end table
|
||||
@node Future enhancements, Reporting bugs and ideas, Customization, Top
|
||||
@node Future enhancements, Bugs, Customization, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Future enhancements
|
||||
@cindex Enhancements
|
||||
|
||||
Pcl-cvs is still under development and needs a number of enhancements to
|
||||
be called complete. Here is my current wish-list for future releases of
|
||||
pcl-cvs:
|
||||
be called complete. Below is my current wish-list for future releases
|
||||
of pcl-cvs. Please, let me know which of these features you want most.
|
||||
They are listed below in approximately the order that I currently think
|
||||
I will implement them in.
|
||||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Dired support. I have an experimental @file{dired-cvs.el} that works
|
||||
together with CVS 1.2. Unfortunately I wrote it on top of a
|
||||
non-standard @file{dired.el}, so it must be rewritten.@refill
|
||||
Rewritten parser code. There are many situations where pcl-cvs will
|
||||
fail to recognize the output from CVS. The situation could be greatly
|
||||
increased.
|
||||
|
||||
@item
|
||||
@samp{cvs-status}. This will run @samp{cvs status} in a directory and
|
||||
produce a buffer that looks pretty much like the current *cvs* buffer.
|
||||
That buffer will include information for all version-controlled files.
|
||||
(There will be a simple keystroke to remove all "uninteresting" files,
|
||||
that is, files that are "Up-to-date"). In this new buffer you will be
|
||||
able to update a file, commit a file, et c. The big win with this is
|
||||
that you will be able to watch the differences between your current
|
||||
working file and the head revision in the repository before you update
|
||||
the file, and you can then choose to update it or let it wait for a
|
||||
while longer.
|
||||
|
||||
@item
|
||||
Log mode. When this mode is finished you will be able to move around
|
||||
(using @kbd{n} and @kbd{p}) between the revisions of a file, mark two of
|
||||
them, and run a diff between them. You will be able to hide branches
|
||||
(similar to the way you can hide sub-paragraphs in outline-mode) and do
|
||||
merges between revisions. Other ideas about this are welcome.
|
||||
|
||||
@item
|
||||
The current model for marks in the *cvs* buffer seems to be confusing.
|
||||
I am considering to use the VM model instead, where marks are normally
|
||||
inactive. To activate the mark, you issue a command like
|
||||
@samp{cvs-mode-next-command-uses-marks}. I might implement a flag so
|
||||
that you can use either version. Feedback on this before I start coding
|
||||
it is very welcome.
|
||||
|
||||
@item
|
||||
It should be possible to run commands such as @samp{cvs log}, @samp{cvs
|
||||
status} and @samp{cvs commit} directly from a buffer containing a file,
|
||||
instead of having to @samp{cvs-update}. If the directory contains many
|
||||
files the @samp{cvs-update} can take quite some time, especially on a
|
||||
slow machine.
|
||||
slow machine. I planed to put these kind of commands on the prefix
|
||||
@kbd{C-c C-v}, but that turned out to be used by for instance c++-mode.
|
||||
If you have any suggestions for a better prefix key, please let me know.
|
||||
|
||||
@item
|
||||
Increased robustness. For instance, you can not currently press
|
||||
@kbd{C-g} when you are entering the description of a file that you are
|
||||
adding without confusing pcl-cvs.
|
||||
|
||||
@item
|
||||
Support for multiple active *cvs* buffers.
|
||||
|
||||
@item
|
||||
Dired support. I have an experimental @file{dired-cvs.el} that works
|
||||
together with CVS 1.2. Unfortunately I wrote it on top of a
|
||||
non-standard @file{dired.el}, so it must be rewritten.@refill
|
||||
|
||||
@item
|
||||
An ability to send user-supplied options to all the cvs commands.
|
||||
|
||||
@item
|
||||
Pcl-cvs is not at all clever about what it should do when @samp{cvs
|
||||
update} runs a program (due to the @samp{-u} option in the
|
||||
@file{modules} file --- see @samp{cvs(5)}). The current release uses a
|
||||
regexp to search for the end. At the very least that regexp should be
|
||||
configured for different modules. Tell me if you have any idea about
|
||||
what is the right thing to do. In a perfect world the program should
|
||||
also be allowed to print to @samp{stderr} without causing pcl-cvs to
|
||||
crash.
|
||||
@end itemize
|
||||
|
||||
|
||||
If you miss something in this wish-list, let me know! I don't promise
|
||||
that I will write it, but I will at least try to coordinate the efforts
|
||||
of making a good Emacs front end to CVS. See @xref{Reporting bugs and
|
||||
ideas} for information about how to reach me.@refill
|
||||
of making a good Emacs front end to CVS. See @xref{Bugs} for
|
||||
information about how to reach me.@refill
|
||||
|
||||
So far, I have written most of pcl-cvs in my all-to-rare spare time. If
|
||||
you want pcl-cvs to be developed faster you can write a contract with
|
||||
Signum Support to do the extension. You can reach Signum Support by
|
||||
email to @samp{info@@signum.se} or via mail to Signum Support AB, Box
|
||||
2044, S-580 02 Linkoping, Sweden. Phone: +46 (0) 13 - 21 46 00. Fax: +46
|
||||
(0) 13 - 21 47 00.
|
||||
|
||||
@node Reporting bugs and ideas, Function and Variable Index, Future enhancements, Top
|
||||
@node Bugs, Function and Variable Index, Future enhancements, Top
|
||||
@comment node-name, next, previous, up
|
||||
@chapter Reporting bugs and ideas
|
||||
@chapter Bugs (known and unknown)
|
||||
@cindex Reporting bugs and ideas
|
||||
@cindex Bugs, how to report them
|
||||
@cindex Author, how to reach
|
||||
@cindex Email to the author
|
||||
@cindex Known bugs
|
||||
@cindex Bugs, known
|
||||
@cindex FAQ
|
||||
@cindex Problems, list of common
|
||||
|
||||
If you find a bug or misfeature, don't hesitate to tell me! Send email
|
||||
to @samp{ceder@@lysator.liu.se}.
|
||||
@ -1413,8 +1688,40 @@ If you have ideas for improvements, or if you have written some
|
||||
extensions to this package, I would like to hear from you. I hope that
|
||||
you find this package useful!
|
||||
|
||||
Below is a partial list of currently known problems with pcl-cvs version
|
||||
1.05.
|
||||
|
||||
@node Function and Variable Index, Concept Index, Reporting bugs and ideas, Top
|
||||
@table @asis
|
||||
@item Commit causes Emacs to hang
|
||||
Emacs waits for the @samp{cvs commit} command to finish before you can
|
||||
do anything. If you start a background job from the loginfo file you
|
||||
must take care that it closes @samp{stdout} and @samp{stderr} if you do
|
||||
not want to wait for it. (You do that with @samp{background-command &>-
|
||||
2&>- &} if you are starting @samp{background-command} from a
|
||||
@samp{/bin/sh} shell script).
|
||||
|
||||
Your emacs will also hang if there was a lock file in the repository.
|
||||
In this case you can type @kbd{C-g} to get control over your emacs
|
||||
again.
|
||||
|
||||
@item Name clash in Emacs 19
|
||||
This is really a bug in Elib or the Emacs 19 distribution. Both Elib and
|
||||
Emacs 19.6 through at least 19.10 contains a file named
|
||||
@file{cookie.el}. One of the files will have to be renamed, and we are
|
||||
currently negotiating about which of the files to rename.
|
||||
|
||||
@item Commands while cvs-update is running
|
||||
It is possible to type commands in the *cvs* buffer while the update is
|
||||
running, but error messages is all that you will get. The error
|
||||
messages should be better.
|
||||
|
||||
@item Unexpected output from CVS
|
||||
Unexpected output from CVS confuses pcl-cvs. It will currently create a
|
||||
bug report that you can mail to me. It should do something more
|
||||
civilized.
|
||||
@end table
|
||||
|
||||
@node Function and Variable Index, Concept Index, Bugs, Top
|
||||
@comment node-name, next, previous, up
|
||||
@unnumbered Function and Variable Index
|
||||
|
||||
|
@ -1,208 +1,184 @@
|
||||
#!/bin/csh
|
||||
#!/bin/sh
|
||||
#
|
||||
# rcs-to-cvs,v 1.3 1992/04/10 03:04:25 berliner Exp
|
||||
# Contributed by Per Cederqvist <ceder@lysator.liu.se>.
|
||||
# $Id: rcs-to-cvs,v 1.4 1994/09/21 07:23:16 berliner Exp $
|
||||
# Based on the CVS 1.0 checkin csh script.
|
||||
# Contributed by Per Cederqvist <ceder@signum.se>.
|
||||
# Rewritten in sh by David MacKenzie <djm@cygnus.com>.
|
||||
#
|
||||
# Copyright (c) 1989, Brian Berliner
|
||||
#
|
||||
# You may distribute under the terms of the GNU General Public License
|
||||
# as specified in the README file that comes with the CVS 1.0 kit.
|
||||
# You may distribute under the terms of the GNU General Public License.
|
||||
#
|
||||
#############################################################################
|
||||
# #
|
||||
# This script is used to check in sources that previously was under RCS or #
|
||||
# no source control system. #
|
||||
# #
|
||||
# Usage: rcs-to-cvs repository #
|
||||
# #
|
||||
# The repository is the directory where the sources should #
|
||||
# be deposited.
|
||||
# #
|
||||
# checkin traverses the current directory, ensuring that an #
|
||||
# identical directory structure exists in the repository directory. It #
|
||||
# then checks the files in in the following manner: #
|
||||
# #
|
||||
# 1) If the file doesn't yet exist, check it in #
|
||||
# as revision 0.1 #
|
||||
# #
|
||||
# The script also is somewhat verbose in letting the user know what is #
|
||||
# going on. It prints a diagnostic when it creates a new file, or updates #
|
||||
# a file that has been modified on the trunk. #
|
||||
# #
|
||||
#
|
||||
# Check in sources that previously were under RCS or no source control system.
|
||||
#
|
||||
# The repository is the directory where the sources should be deposited.
|
||||
#
|
||||
# Traverses the current directory, ensuring that an
|
||||
# identical directory structure exists in the repository directory. It
|
||||
# then checks the files in in the following manner:
|
||||
#
|
||||
# 1) If the file doesn't yet exist, check it in as revision 1.1
|
||||
#
|
||||
# The script also is somewhat verbose in letting the user know what is
|
||||
# going on. It prints a diagnostic when it creates a new file, or updates
|
||||
# a file that has been modified on the trunk.
|
||||
#
|
||||
# Bugs: doesn't put the files in branch 1.1.1
|
||||
# doesn't put in release and vendor tags
|
||||
#
|
||||
#############################################################################
|
||||
|
||||
set vbose = 0
|
||||
set message = ""
|
||||
set cvsbin = /usr/gnu/bin
|
||||
set rcsbin = /usr/gnu/bin
|
||||
set grep = /bin/grep
|
||||
set message_file = /usr/tmp/checkin.$$
|
||||
set got_one = 0
|
||||
usage="Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository"
|
||||
vbose=0
|
||||
message=""
|
||||
message_file=/usr/tmp/checkin.$$
|
||||
got_one=0
|
||||
|
||||
if ( $#argv < 1 ) then
|
||||
echo "Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository"
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "$usage" >&2
|
||||
exit 1
|
||||
endif
|
||||
while ( $#argv )
|
||||
switch ( $argv[1] )
|
||||
case -v:
|
||||
set vbose = 1
|
||||
breaksw
|
||||
case -m:
|
||||
fi
|
||||
|
||||
while [ $# -ne 0 ]; do
|
||||
case "$1" in
|
||||
-v)
|
||||
vbose=1
|
||||
;;
|
||||
-m)
|
||||
shift
|
||||
echo $argv[1] > $message_file
|
||||
set got_one = 1
|
||||
breaksw
|
||||
case -f:
|
||||
echo $1 > $message_file
|
||||
got_one=1
|
||||
;;
|
||||
-f)
|
||||
shift
|
||||
set message_file = $argv[1]
|
||||
set got_one = 2
|
||||
breaksw
|
||||
default:
|
||||
message_file=$1
|
||||
got_one=2
|
||||
;;
|
||||
*)
|
||||
break
|
||||
endsw
|
||||
esac
|
||||
shift
|
||||
end
|
||||
if ( $#argv < 1 ) then
|
||||
echo "Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository"
|
||||
done
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "$usage" >&2
|
||||
exit 1
|
||||
endif
|
||||
set repository = $argv[1]
|
||||
fi
|
||||
|
||||
repository=$1
|
||||
shift
|
||||
|
||||
if ( ! $?CVSROOT ) then
|
||||
echo "Please set the environmental variable CVSROOT to the root"
|
||||
echo " of the tree you wish to update"
|
||||
if [ -z "$CVSROOT" ]; then
|
||||
echo "Please the environmental variable CVSROOT to the root" >&2
|
||||
echo " of the tree you wish to update" >&2
|
||||
exit 1
|
||||
endif
|
||||
fi
|
||||
|
||||
if ( $got_one == 0 ) then
|
||||
if [ $got_one -eq 0 ]; then
|
||||
echo "Please Edit this file to contain the RCS log information" >$message_file
|
||||
echo "to be associated with this file (please remove these lines)">>$message_file
|
||||
if ( $?EDITOR ) then
|
||||
$EDITOR $message_file > /dev/tty
|
||||
else
|
||||
/usr/ucb/vi $message_file > /dev/tty
|
||||
endif
|
||||
set got_one = 1
|
||||
endif
|
||||
echo "to be associated with this directory (please remove these lines)">>$message_file
|
||||
${EDITOR-/usr/ucb/vi} $message_file
|
||||
got_one=1
|
||||
fi
|
||||
|
||||
umask 22
|
||||
|
||||
set update_dir = ${CVSROOT}/${repository}
|
||||
if ( -d SCCS ) then
|
||||
echo SCCS files detected!
|
||||
update_dir=${CVSROOT}/${repository}
|
||||
[ ! -d ${update_dir} ] && mkdir $update_dir
|
||||
|
||||
if [ -d SCCS ]; then
|
||||
echo SCCS files detected! >&2
|
||||
exit 1
|
||||
endif
|
||||
if ( -d RCS ) then
|
||||
$rcsbin/co RCS/* >& /dev/null
|
||||
endif
|
||||
foreach name ( * .[a-zA-Z0-9]* )
|
||||
fi
|
||||
if [ -d RCS ]; then
|
||||
co RCS/*
|
||||
fi
|
||||
|
||||
for name in * .[a-zA-Z0-9]*
|
||||
do
|
||||
case "$name" in
|
||||
RCS | \* | .\[a-zA-Z0-9\]\* ) continue ;;
|
||||
esac
|
||||
echo $name
|
||||
if ( "$name" == SCCS ) then
|
||||
continue
|
||||
endif
|
||||
if ( "$name" == RCS ) then
|
||||
continue
|
||||
endif
|
||||
if ( $vbose ) then
|
||||
if [ $vbose -ne 0 ]; then
|
||||
echo "Updating ${repository}/${name}"
|
||||
endif
|
||||
if ( -d "$name" ) then
|
||||
if ( ! -d "${update_dir}/${name}" ) then
|
||||
fi
|
||||
if [ -d "$name" ]; then
|
||||
if [ ! -d "${update_dir}/${name}" ]; then
|
||||
echo "WARNING: Creating new directory ${repository}/${name}"
|
||||
mkdir "${update_dir}/${name}"
|
||||
if ( $status ) then
|
||||
echo "ERROR: mkdir failed - aborting"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: mkdir failed - aborting" >&2
|
||||
exit 1
|
||||
endif
|
||||
endif
|
||||
chdir "$name"
|
||||
if ( $status ) then
|
||||
echo "ERROR: Couldn\'t chdir to "$name" - aborting"
|
||||
fi
|
||||
fi
|
||||
cd "$name"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Couldn\'t cd to $name - aborting" >&2
|
||||
exit 1
|
||||
endif
|
||||
if ( $vbose ) then
|
||||
rcs-to-cvs -v -f $message_file "${repository}/${name}"
|
||||
fi
|
||||
if [ $vbose -ne 0 ]; then
|
||||
$0 -v -f $message_file "${repository}/${name}"
|
||||
else
|
||||
rcs-to-cvs -f $message_file "${repository}/${name}"
|
||||
endif
|
||||
if ( $status ) then
|
||||
$0 -f $message_file "${repository}/${name}"
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
exit 1
|
||||
endif
|
||||
chdir ..
|
||||
fi
|
||||
cd ..
|
||||
else # if not directory
|
||||
if ( ! -f "$name" ) then
|
||||
echo "WARNING: "$name" is neither a regular file"
|
||||
if [ ! -f "$name" ]; then
|
||||
echo "WARNING: $name is neither a regular file"
|
||||
echo " nor a directory - ignored"
|
||||
continue
|
||||
endif
|
||||
set file = "${update_dir}/${name},v"
|
||||
set new = 0
|
||||
set comment = ""
|
||||
grep -s '\$Log.*\$' "${name}"
|
||||
if ( $status == 0 ) then # If $Log keyword
|
||||
set myext = ${name:e}
|
||||
set knownext = 0
|
||||
foreach xx ( "c" "csh" "e" "f" "h" "l" "mac" "me" "mm" "ms" "p" "r" "red" "s" "sh" "sl" "cl" "ml" "el" "tex" "y" "ye" "yr" "" )
|
||||
if ( "${myext}" == "${xx}" ) then
|
||||
set knownext = 1
|
||||
break
|
||||
endif
|
||||
end
|
||||
if ( $knownext == 0 ) then
|
||||
echo For file ${file}:
|
||||
fi
|
||||
file="${update_dir}/${name},v"
|
||||
comment=""
|
||||
if grep -s '\$Log.*\$' "${name}"; then # If $Log keyword
|
||||
myext=`echo $name | sed 's,.*\.,,'`
|
||||
[ "$myext" = "$name" ] && myext=
|
||||
case "$myext" in
|
||||
c | csh | e | f | h | l | mac | me | mm | ms | p | r | red | s | sh | sl | cl | ml | el | tex | y | ye | yr | "" )
|
||||
;;
|
||||
|
||||
* )
|
||||
echo "For file ${file}:"
|
||||
grep '\$Log.*\$' "${name}"
|
||||
echo -n "Please insert a comment leader for file ${name} > "
|
||||
set comment = $<
|
||||
endif
|
||||
endif
|
||||
if ( ! -f "$file" ) then # If not exists in repository
|
||||
if ( ! -f "${update_dir}/Attic/${name},v" ) then
|
||||
read comment
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
if [ ! -f "$file" ]; then # If not exists in repository
|
||||
if [ ! -f "${update_dir}/Attic/${name},v" ]; then
|
||||
echo "WARNING: Creating new file ${repository}/${name}"
|
||||
if ( -f RCS/"${name}",v ) then
|
||||
if [ -f RCS/"${name}",v ]; then
|
||||
echo "MSG: Copying old rcs file."
|
||||
cp RCS/"${name}",v "$file"
|
||||
else
|
||||
if ( "${comment}" != "" ) then
|
||||
$rcsbin/rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file"
|
||||
endif
|
||||
$rcsbin/ci -q -u0.1 -t${message_file} -m'.' "$file"
|
||||
if ( $status ) then
|
||||
echo "ERROR: Initial check-in of $file failed - aborting"
|
||||
if [ -n "${comment}" ]; then
|
||||
rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file"
|
||||
fi
|
||||
ci -q -u1.1 -t${message_file} -m'.' "$file"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "ERROR: Initial check-in of $file failed - aborting" >&2
|
||||
exit 1
|
||||
endif
|
||||
set new = 1
|
||||
endif
|
||||
fi
|
||||
fi
|
||||
else
|
||||
set file = "${update_dir}/Attic/${name},v"
|
||||
file="${update_dir}/Attic/${name},v"
|
||||
echo "WARNING: IGNORED: ${repository}/Attic/${name}"
|
||||
continue
|
||||
endif
|
||||
fi
|
||||
else # File existed
|
||||
echo ERROR: File exists: Ignored: "$file"
|
||||
echo "ERROR: File exists in repository: Ignored: $file"
|
||||
continue
|
||||
# set headbranch = `sed -n '/^head/p; /^branch/p; 2q' $file`
|
||||
# if ( $#headbranch != 2 && $#headbranch != 4 ) then
|
||||
# echo "ERROR: corrupted RCS file $file - aborting"
|
||||
# endif
|
||||
# set head = "$headbranch[2]"
|
||||
# set branch = ""
|
||||
# if ( $#headbranch == 4 ) then
|
||||
# set branch = "$headbranch[4]"
|
||||
# endif
|
||||
# if ( "$head" == "1.1;" && "$branch" != "1.1.1;" ) then
|
||||
# ${rcsbin}/rcsdiff -q -r1.1 $file > /dev/null
|
||||
# if ( ! $status ) then
|
||||
# set new = 1
|
||||
# endif
|
||||
# else
|
||||
# if ( "$branch" != "1.1.1;" ) then
|
||||
# echo -n "WARNING: Updating locally modified file "
|
||||
# echo "${repository}/${name}"
|
||||
# endif
|
||||
# endif
|
||||
endif
|
||||
endif
|
||||
end
|
||||
if ( $got_one == 1 ) rm $message_file
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
[ $got_one -eq 1 ] && rm -f $message_file
|
||||
|
||||
exit 0
|
||||
|
@ -43,7 +43,7 @@
|
||||
#
|
||||
# Various hacks made by Brian Berliner before inclusion in CVS contrib area.
|
||||
#
|
||||
# sccs2rcs,v 1.1 1992/04/10 03:04:26 berliner Exp
|
||||
# $Id: sccs2rcs,v 1.1 1992/04/10 03:04:26 berliner Exp $
|
||||
|
||||
|
||||
#we'll assume the user set up the path correctly
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Add
|
||||
*
|
||||
@ -27,17 +27,13 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)add.c 1.46 92/04/03";
|
||||
static char rcsid[] = "$CVSid: @(#)add.c 1.55 94/10/22 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static int add_directory (char *repository, char *dir);
|
||||
static int build_entry (char *repository, char *user, char *options,
|
||||
char *message, List * entries);
|
||||
#else
|
||||
static int add_directory ();
|
||||
static int build_entry ();
|
||||
#endif /* __STDC__ */
|
||||
static int add_directory PROTO((char *repository, char *dir));
|
||||
static int build_entry PROTO((char *repository, char *user, char *options,
|
||||
char *message, List * entries, char *tag));
|
||||
|
||||
static char *add_usage[] =
|
||||
{
|
||||
@ -52,7 +48,7 @@ add (argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
char message[MAXMESGLEN];
|
||||
char *message = NULL;
|
||||
char *user;
|
||||
int i;
|
||||
char *repository;
|
||||
@ -67,9 +63,8 @@ add (argc, argv)
|
||||
usage (add_usage);
|
||||
|
||||
/* parse args */
|
||||
message[0] = '\0';
|
||||
optind = 1;
|
||||
while ((c = gnu_getopt (argc, argv, "k:m:")) != -1)
|
||||
while ((c = getopt (argc, argv, "k:m:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -80,14 +75,7 @@ add (argc, argv)
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (strlen (optarg) >= sizeof (message))
|
||||
{
|
||||
error (0, 0, "warning: message too long; truncated!");
|
||||
(void) strncpy (message, optarg, sizeof (message));
|
||||
message[sizeof (message) - 1] = '\0';
|
||||
}
|
||||
else
|
||||
(void) strcpy (message, optarg);
|
||||
message = xstrdup (optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
@ -111,7 +99,8 @@ add (argc, argv)
|
||||
int begin_err = err;
|
||||
|
||||
user = argv[i];
|
||||
if (index (user, '/') != NULL)
|
||||
strip_trailing_slashes (user);
|
||||
if (strchr (user, '/') != NULL)
|
||||
{
|
||||
error (0, 0,
|
||||
"cannot add files with '/' in their name; %s not added", user);
|
||||
@ -153,19 +142,18 @@ add (argc, argv)
|
||||
|
||||
/* There is a user file, so build the entry for it */
|
||||
if (build_entry (repository, user, vers->options,
|
||||
message, entries) != 0)
|
||||
message, entries, vers->tag) != 0)
|
||||
err++;
|
||||
else if (!quiet)
|
||||
else
|
||||
{
|
||||
added_files++;
|
||||
error (0, 0, "scheduling file `%s' for addition",
|
||||
user);
|
||||
if (!quiet)
|
||||
error (0, 0, "scheduling file `%s' for addition", user);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
/*
|
||||
* There is an RCS file already, so somebody else must've
|
||||
* added it
|
||||
@ -214,7 +202,7 @@ add (argc, argv)
|
||||
(void) strcpy (vers->vn_user, tmp);
|
||||
(void) sprintf (tmp, "Resurrected %s", user);
|
||||
Register (entries, user, vers->vn_user, tmp, vers->options,
|
||||
vers->tag, vers->date);
|
||||
vers->tag, vers->date, vers->ts_conflict);
|
||||
free (tmp);
|
||||
|
||||
/* XXX - bugs here; this really resurrect the head */
|
||||
@ -257,6 +245,10 @@ add (argc, argv)
|
||||
error (0, 0, "use 'cvs commit' to add %s permanently",
|
||||
(added_files == 1) ? "this file" : "these files");
|
||||
dellist (&entries);
|
||||
|
||||
if (message)
|
||||
free (message);
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
@ -276,7 +268,7 @@ add_directory (repository, dir)
|
||||
char message[PATH_MAX + 100];
|
||||
char *tag, *date;
|
||||
|
||||
if (index (dir, '/') != NULL)
|
||||
if (strchr (dir, '/') != NULL)
|
||||
{
|
||||
error (0, 0,
|
||||
"directory %s not added; must be a direct sub-directory", dir);
|
||||
@ -334,10 +326,12 @@ add_directory (repository, dir)
|
||||
if (!isdir (rcsdir))
|
||||
{
|
||||
mode_t omask;
|
||||
char line[MAXLINELEN];
|
||||
Node *p;
|
||||
List *ulist;
|
||||
|
||||
#if 0
|
||||
char line[MAXLINELEN];
|
||||
|
||||
(void) printf ("Add directory %s to the repository (y/n) [n] ? ",
|
||||
rcsdir);
|
||||
(void) fflush (stdout);
|
||||
@ -348,6 +342,8 @@ add_directory (repository, dir)
|
||||
error (0, 0, "directory %s not added", rcsdir);
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
|
||||
omask = umask (2);
|
||||
if (mkdir (rcsdir, 0777) < 0)
|
||||
{
|
||||
@ -389,12 +385,13 @@ add_directory (repository, dir)
|
||||
* interrogating the user. Returns non-zero on error.
|
||||
*/
|
||||
static int
|
||||
build_entry (repository, user, options, message, entries)
|
||||
build_entry (repository, user, options, message, entries, tag)
|
||||
char *repository;
|
||||
char *user;
|
||||
char *options;
|
||||
char *message;
|
||||
List *entries;
|
||||
char *tag;
|
||||
{
|
||||
char fname[PATH_MAX];
|
||||
char line[MAXLINELEN];
|
||||
@ -418,6 +415,7 @@ build_entry (repository, user, options, message, entries)
|
||||
|
||||
/*
|
||||
* The options for the "add" command are store in the file CVS/user,p
|
||||
* XXX - no they are not!
|
||||
*/
|
||||
(void) sprintf (fname, "%s/%s%s", CVSADM, user, CVSEXT_OPT);
|
||||
fp = open_file (fname, "w+");
|
||||
@ -431,7 +429,7 @@ build_entry (repository, user, options, message, entries)
|
||||
*/
|
||||
(void) sprintf (fname, "%s/%s%s", CVSADM, user, CVSEXT_LOG);
|
||||
fp = open_file (fname, "w+");
|
||||
if (*message && fputs (message, fp) == EOF)
|
||||
if (message && fputs (message, fp) == EOF)
|
||||
error (1, errno, "cannot write to %s", fname);
|
||||
if (fclose(fp) == EOF)
|
||||
error(1, errno, "cannot close %s", fname);
|
||||
@ -442,6 +440,6 @@ build_entry (repository, user, options, message, entries)
|
||||
* and ,t files, but who cares).
|
||||
*/
|
||||
(void) sprintf (line, "Initial %s", user);
|
||||
Register (entries, user, "0", line, options, (char *) 0, (char *) 0);
|
||||
Register (entries, user, "0", line, options, tag, (char *) 0, (char *) 0);
|
||||
return (0);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Administration
|
||||
*
|
||||
@ -14,18 +14,14 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)admin.c 1.17 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)admin.c 1.20 94/09/30 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static Dtype admin_dirproc (char *dir, char *repos, char *update_dir);
|
||||
static int admin_fileproc (char *file, char *update_dir,
|
||||
static Dtype admin_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||
static int admin_fileproc PROTO((char *file, char *update_dir,
|
||||
char *repository, List *entries,
|
||||
List *srcfiles);
|
||||
#else
|
||||
static int admin_fileproc ();
|
||||
static Dtype admin_dirproc ();
|
||||
#endif /* __STDC__ */
|
||||
List *srcfiles));
|
||||
|
||||
static char *admin_usage[] =
|
||||
{
|
||||
@ -60,7 +56,7 @@ admin (argc, argv)
|
||||
/* start the recursion processor */
|
||||
err = start_recursion (admin_fileproc, (int (*) ()) NULL, admin_dirproc,
|
||||
(int (*) ()) NULL, argc, argv, 0,
|
||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
||||
W_LOCAL, 0, 1, (char *) NULL, 1, 0);
|
||||
return (err);
|
||||
}
|
||||
|
||||
|
@ -3,28 +3,25 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)classify.c 1.11 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)classify.c 1.17 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static void sticky_ck (char *file, int aflag, Vers_TS * vers, List * entries);
|
||||
#else
|
||||
static void sticky_ck ();
|
||||
#endif /* __STDC__ */
|
||||
static void sticky_ck PROTO((char *file, int aflag, Vers_TS * vers, List * entries));
|
||||
|
||||
/*
|
||||
* Classify the state of a file
|
||||
*/
|
||||
Ctype
|
||||
Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
entries, srcfiles, versp)
|
||||
entries, srcfiles, versp, update_dir, pipeout)
|
||||
char *file;
|
||||
char *tag;
|
||||
char *date;
|
||||
@ -35,9 +32,18 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
List *entries;
|
||||
List *srcfiles;
|
||||
Vers_TS **versp;
|
||||
char *update_dir;
|
||||
int pipeout;
|
||||
{
|
||||
Vers_TS *vers;
|
||||
Ctype ret;
|
||||
char *fullname;
|
||||
|
||||
fullname = xmalloc (strlen (update_dir) + strlen (file) + 10);
|
||||
if (update_dir[0] == '\0')
|
||||
strcpy (fullname, file);
|
||||
else
|
||||
sprintf (fullname, "%s/%s", update_dir, file);
|
||||
|
||||
/* get all kinds of good data about the file */
|
||||
vers = Version_TS (repository, options, tag, date, file,
|
||||
@ -54,7 +60,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
/* there is no user file */
|
||||
if (!force_tag_match || !(vers->tag || vers->date))
|
||||
if (!really_quiet)
|
||||
error (0, 0, "nothing known about %s", file);
|
||||
error (0, 0, "nothing known about %s", fullname);
|
||||
ret = T_UNKNOWN;
|
||||
}
|
||||
else
|
||||
@ -63,7 +69,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
if (!force_tag_match || !(vers->tag || vers->date))
|
||||
if (!really_quiet)
|
||||
error (0, 0, "use `cvs add' to create an entry for %s",
|
||||
file);
|
||||
fullname);
|
||||
ret = T_UNKNOWN;
|
||||
}
|
||||
}
|
||||
@ -78,16 +84,26 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pipeout)
|
||||
{
|
||||
/*
|
||||
* The user file doesn't necessarily have anything
|
||||
* to do with this.
|
||||
*/
|
||||
ret = T_CHECKOUT;
|
||||
}
|
||||
/*
|
||||
* There is a user file; print a warning and add it to the
|
||||
* conflict list, only if it is indeed different from what we
|
||||
* plan to extract
|
||||
*/
|
||||
if (No_Difference (file, vers, entries))
|
||||
else if (No_Difference (file, vers, entries,
|
||||
repository, update_dir))
|
||||
{
|
||||
/* the files were different so it is a conflict */
|
||||
if (!really_quiet)
|
||||
error (0, 0, "move away %s; it is in the way", file);
|
||||
error (0, 0, "move away %s; it is in the way",
|
||||
fullname);
|
||||
ret = T_CONFLICT;
|
||||
}
|
||||
else
|
||||
@ -107,7 +123,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
* entry
|
||||
*/
|
||||
if (!really_quiet)
|
||||
error (0, 0, "warning: new-born %s has disappeared", file);
|
||||
error (0, 0, "warning: new-born %s has disappeared", fullname);
|
||||
ret = T_REMOVE_ENTRY;
|
||||
}
|
||||
else
|
||||
@ -126,7 +142,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
if (!really_quiet)
|
||||
error (0, 0,
|
||||
"conflict: %s created independently by second party",
|
||||
file);
|
||||
fullname);
|
||||
ret = T_CONFLICT;
|
||||
}
|
||||
}
|
||||
@ -169,7 +185,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
if (!really_quiet)
|
||||
error (0, 0,
|
||||
"conflict: removed %s was modified by second party",
|
||||
file);
|
||||
fullname);
|
||||
ret = T_CONFLICT;
|
||||
}
|
||||
}
|
||||
@ -177,7 +193,8 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
{
|
||||
/* The user file shouldn't be there */
|
||||
if (!really_quiet)
|
||||
error (0, 0, "%s should be removed and is still there", file);
|
||||
error (0, 0, "%s should be removed and is still there",
|
||||
fullname);
|
||||
ret = T_REMOVED;
|
||||
}
|
||||
}
|
||||
@ -193,7 +210,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
/* There is no user file, so just remove the entry */
|
||||
if (!really_quiet)
|
||||
error (0, 0, "warning: %s is not (any longer) pertinent",
|
||||
file);
|
||||
fullname);
|
||||
ret = T_REMOVE_ENTRY;
|
||||
}
|
||||
else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
|
||||
@ -204,7 +221,8 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
* the entry list
|
||||
*/
|
||||
if (!really_quiet)
|
||||
error (0, 0, "%s is no longer in the repository", file);
|
||||
error (0, 0, "%s is no longer in the repository",
|
||||
fullname);
|
||||
ret = T_REMOVE_ENTRY;
|
||||
}
|
||||
else
|
||||
@ -213,13 +231,14 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
* The user file has been modified and since it is no longer
|
||||
* in the repository, a conflict is raised
|
||||
*/
|
||||
if (No_Difference (file, vers, entries))
|
||||
if (No_Difference (file, vers, entries,
|
||||
repository, update_dir))
|
||||
{
|
||||
/* they are different -> conflict */
|
||||
if (!really_quiet)
|
||||
error (0, 0,
|
||||
"conflict: %s is modified but no longer in the repository",
|
||||
file);
|
||||
fullname);
|
||||
ret = T_CONFLICT;
|
||||
}
|
||||
else
|
||||
@ -228,7 +247,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
if (!really_quiet)
|
||||
error (0, 0,
|
||||
"warning: %s is not (any longer) pertinent",
|
||||
file);
|
||||
fullname);
|
||||
ret = T_REMOVE_ENTRY;
|
||||
}
|
||||
}
|
||||
@ -246,7 +265,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
*/
|
||||
if (strcmp (command_name, "update") == 0)
|
||||
if (!really_quiet)
|
||||
error (0, 0, "warning: %s was lost", file);
|
||||
error (0, 0, "warning: %s was lost", fullname);
|
||||
ret = T_CHECKOUT;
|
||||
}
|
||||
else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
|
||||
@ -274,7 +293,8 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
* The user file appears to have been modified, but we call
|
||||
* No_Difference to verify that it really has been modified
|
||||
*/
|
||||
if (No_Difference (file, vers, entries))
|
||||
if (No_Difference (file, vers, entries,
|
||||
repository, update_dir))
|
||||
{
|
||||
|
||||
/*
|
||||
@ -323,7 +343,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
|
||||
if (strcmp (command_name, "update") == 0)
|
||||
if (!really_quiet)
|
||||
error (0, 0, "warning: %s was lost", file);
|
||||
error (0, 0, "warning: %s was lost", fullname);
|
||||
ret = T_CHECKOUT;
|
||||
}
|
||||
else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
|
||||
@ -336,7 +356,8 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (No_Difference (file, vers, entries))
|
||||
if (No_Difference (file, vers, entries,
|
||||
repository, update_dir))
|
||||
/* really modified, needs to merge */
|
||||
ret = T_NEEDS_MERGE;
|
||||
else
|
||||
@ -352,6 +373,8 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||
else
|
||||
freevers_ts (&vers);
|
||||
|
||||
free (fullname);
|
||||
|
||||
/* return the status of the file */
|
||||
return (ret);
|
||||
}
|
||||
@ -374,7 +397,7 @@ sticky_ck (file, aflag, vers, entries)
|
||||
((entdate && !vers->date) || (!entdate && vers->date)))
|
||||
{
|
||||
Register (entries, file, vers->vn_user, vers->ts_rcs,
|
||||
vers->options, vers->tag, vers->date);
|
||||
vers->options, vers->tag, vers->date, vers->ts_conflict);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Commit Files
|
||||
*
|
||||
@ -17,68 +17,46 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)commit.c 1.84 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)commit.c 1.101 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static Dtype check_direntproc (char *dir, char *repos, char *update_dir);
|
||||
static int check_fileproc (char *file, char *update_dir, char *repository,
|
||||
List * entries, List * srcfiles);
|
||||
static int check_filesdoneproc (int err, char *repos, char *update_dir);
|
||||
static int checkaddfile (char *file, char *repository, char *tag);
|
||||
static Dtype commit_direntproc (char *dir, char *repos, char *update_dir);
|
||||
static int commit_dirleaveproc (char *dir, int err, char *update_dir);
|
||||
static int commit_fileproc (char *file, char *update_dir, char *repository,
|
||||
List * entries, List * srcfiles);
|
||||
static int commit_filesdoneproc (int err, char *repository, char *update_dir);
|
||||
static int finaladd (char *file, char *revision, char *tag, char *repository,
|
||||
List *entries);
|
||||
static int findmaxrev (Node * p);
|
||||
static int fsortcmp (Node * p, Node * q);
|
||||
static int lock_RCS (char *user, char *rcs, char *rev, char *repository);
|
||||
static int lock_filesdoneproc (int err, char *repository, char *update_dir);
|
||||
static int lockrcsfile (char *file, char *repository, char *rev);
|
||||
static int precommit_list_proc (Node * p);
|
||||
static int precommit_proc (char *repository, char *filter);
|
||||
static int remove_file (char *file, char *repository, char *tag,
|
||||
List *entries);
|
||||
static void fix_rcs_modes (char *rcs, char *user);
|
||||
static void fixaddfile (char *file, char *repository);
|
||||
static void fixbranch (char *file, char *repository, char *branch);
|
||||
static void unlockrcs (char *file, char *repository);
|
||||
static void ci_delproc (Node *p);
|
||||
static void locate_rcs (char *file, char *repository, char *rcs);
|
||||
#else
|
||||
static int fsortcmp ();
|
||||
static int lock_filesdoneproc ();
|
||||
static int check_fileproc ();
|
||||
static Dtype check_direntproc ();
|
||||
static int precommit_list_proc ();
|
||||
static int precommit_proc ();
|
||||
static int check_filesdoneproc ();
|
||||
static int commit_fileproc ();
|
||||
static int commit_filesdoneproc ();
|
||||
static Dtype commit_direntproc ();
|
||||
static int commit_dirleaveproc ();
|
||||
static int findmaxrev ();
|
||||
static int remove_file ();
|
||||
static int finaladd ();
|
||||
static void unlockrcs ();
|
||||
static void fixaddfile ();
|
||||
static void fixbranch ();
|
||||
static int checkaddfile ();
|
||||
static int lockrcsfile ();
|
||||
static int lock_RCS ();
|
||||
static void fix_rcs_modes ();
|
||||
static void ci_delproc ();
|
||||
static void locate_rcs ();
|
||||
#endif /* __STDC__ */
|
||||
static Dtype check_direntproc PROTO((char *dir, char *repos, char *update_dir));
|
||||
static int check_fileproc PROTO((char *file, char *update_dir, char *repository,
|
||||
List * entries, List * srcfiles));
|
||||
static int check_filesdoneproc PROTO((int err, char *repos, char *update_dir));
|
||||
static int checkaddfile PROTO((char *file, char *repository, char *tag,
|
||||
List *srcfiles));
|
||||
static Dtype commit_direntproc PROTO((char *dir, char *repos, char *update_dir));
|
||||
static int commit_dirleaveproc PROTO((char *dir, int err, char *update_dir));
|
||||
static int commit_fileproc PROTO((char *file, char *update_dir, char *repository,
|
||||
List * entries, List * srcfiles));
|
||||
static int commit_filesdoneproc PROTO((int err, char *repository, char *update_dir));
|
||||
static int finaladd PROTO((char *file, char *revision, char *tag, char *options,
|
||||
char *repository, List *entries));
|
||||
static int findmaxrev PROTO((Node * p, void *closure));
|
||||
static int fsortcmp PROTO((Node * p, Node * q));
|
||||
static int lock_RCS PROTO((char *user, char *rcs, char *rev, char *repository));
|
||||
static int lock_filesdoneproc PROTO((int err, char *repository, char *update_dir));
|
||||
static int lockrcsfile PROTO((char *file, char *repository, char *rev));
|
||||
static int precommit_list_proc PROTO((Node * p, void *closure));
|
||||
static int precommit_proc PROTO((char *repository, char *filter));
|
||||
static int remove_file PROTO((char *file, char *repository, char *tag,
|
||||
char *message, List *entries, List *srcfiles));
|
||||
static void fix_rcs_modes PROTO((char *rcs, char *user));
|
||||
static void fixaddfile PROTO((char *file, char *repository));
|
||||
static void fixbranch PROTO((char *file, char *repository, char *branch));
|
||||
static void unlockrcs PROTO((char *file, char *repository));
|
||||
static void ci_delproc PROTO((Node *p));
|
||||
static void masterlist_delproc PROTO((Node *p));
|
||||
static void locate_rcs PROTO((char *file, char *repository, char *rcs));
|
||||
|
||||
struct commit_info
|
||||
{
|
||||
Ctype status; /* as returned from Classify_File() */
|
||||
char *rev; /* a numeric rev, if we know it */
|
||||
char *tag; /* any sticky tag, or -r option */
|
||||
char *options; /* Any sticky -k option */
|
||||
};
|
||||
struct master_lists
|
||||
{
|
||||
@ -86,6 +64,7 @@ struct master_lists
|
||||
List *cilist; /* list with commit_info structs */
|
||||
};
|
||||
|
||||
static int force_ci;
|
||||
static int got_message;
|
||||
static int run_module_prog = 1;
|
||||
static int aflag;
|
||||
@ -98,11 +77,12 @@ static char *message;
|
||||
|
||||
static char *commit_usage[] =
|
||||
{
|
||||
"Usage: %s %s [-nRl] [-m msg | -f logfile] [-r rev] files...\n",
|
||||
"Usage: %s %s [-nRlf] [-m msg | -F logfile] [-r rev] files...\n",
|
||||
"\t-n\tDo not run the module program (if any).\n",
|
||||
"\t-R\tProcess directories recursively.\n",
|
||||
"\t-l\tLocal directory only (not recursive).\n",
|
||||
"\t-f file\tRead the log message from file.\n",
|
||||
"\t-f\tForce the file to be committed; disables recursion.\n",
|
||||
"\t-F file\tRead the log message from file.\n",
|
||||
"\t-m msg\tLog message.\n",
|
||||
"\t-r rev\tCommit to this branch or trunk revision.\n",
|
||||
NULL
|
||||
@ -136,10 +116,8 @@ commit (argc, argv)
|
||||
}
|
||||
#endif /* CVS_BADROOT */
|
||||
|
||||
message = xmalloc (MAXMESGLEN + 1);
|
||||
message[0] = '\0'; /* Null message by default */
|
||||
optind = 1;
|
||||
while ((c = gnu_getopt (argc, argv, "nlRm:f:r:")) != -1)
|
||||
while ((c = getopt (argc, argv, "nlRm:fF:r:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -152,14 +130,13 @@ commit (argc, argv)
|
||||
#else
|
||||
use_editor = FALSE;
|
||||
#endif
|
||||
if (strlen (optarg) >= (size_t) MAXMESGLEN)
|
||||
if (message)
|
||||
{
|
||||
error (0, 0, "warning: message too long; truncated!");
|
||||
(void) strncpy (message, optarg, MAXMESGLEN);
|
||||
message[MAXMESGLEN] = '\0';
|
||||
free (message);
|
||||
message = NULL;
|
||||
}
|
||||
else
|
||||
(void) strcpy (message, optarg);
|
||||
|
||||
message = xstrdup(optarg);
|
||||
break;
|
||||
case 'r':
|
||||
if (tag)
|
||||
@ -173,6 +150,10 @@ commit (argc, argv)
|
||||
local = 0;
|
||||
break;
|
||||
case 'f':
|
||||
force_ci = 1;
|
||||
local = 1; /* also disable recursion */
|
||||
break;
|
||||
case 'F':
|
||||
#ifdef FORCE_USE_EDITOR
|
||||
use_editor = TRUE;
|
||||
#else
|
||||
@ -198,19 +179,26 @@ commit (argc, argv)
|
||||
tag[strlen (tag) - 1] = '\0';
|
||||
}
|
||||
|
||||
/* some checks related to the "-f logfile" option */
|
||||
/* some checks related to the "-F logfile" option */
|
||||
if (logfile)
|
||||
{
|
||||
int n, logfd;
|
||||
struct stat statbuf;
|
||||
|
||||
if (*message)
|
||||
if (message)
|
||||
error (1, 0, "cannot specify both a message and a log file");
|
||||
|
||||
if ((logfd = open (logfile, O_RDONLY)) < 0 ||
|
||||
(n = read (logfd, message, MAXMESGLEN)) < 0)
|
||||
{
|
||||
if ((logfd = open (logfile, O_RDONLY)) < 0)
|
||||
error (1, errno, "cannot open log file %s", logfile);
|
||||
|
||||
if (fstat(logfd, &statbuf) < 0)
|
||||
error (1, errno, "cannot find size of log file %s", logfile);
|
||||
|
||||
message = xmalloc (statbuf.st_size + 1);
|
||||
|
||||
if ((n = read (logfd, message, statbuf.st_size + 1)) < 0)
|
||||
error (1, errno, "cannot read log message from %s", logfile);
|
||||
}
|
||||
|
||||
(void) close (logfd);
|
||||
message[n] = '\0';
|
||||
}
|
||||
@ -226,7 +214,8 @@ commit (argc, argv)
|
||||
locklist = getlist ();
|
||||
err = start_recursion ((int (*) ()) NULL, lock_filesdoneproc,
|
||||
(Dtype (*) ()) NULL, (int (*) ()) NULL, argc,
|
||||
argv, local, W_LOCAL, aflag, 0, (char *) NULL, 0);
|
||||
argv, local, W_LOCAL, aflag, 0, (char *) NULL, 0,
|
||||
0);
|
||||
sortlist (locklist, fsortcmp);
|
||||
if (Writer_Lock (locklist) != 0)
|
||||
error (1, 0, "lock failed - giving up");
|
||||
@ -241,7 +230,8 @@ commit (argc, argv)
|
||||
*/
|
||||
err = start_recursion (check_fileproc, check_filesdoneproc,
|
||||
check_direntproc, (int (*) ()) NULL, argc,
|
||||
argv, local, W_LOCAL, aflag, 0, (char *) NULL, 1);
|
||||
argv, local, W_LOCAL, aflag, 0, (char *) NULL, 1,
|
||||
0);
|
||||
if (err)
|
||||
{
|
||||
Lock_Cleanup ();
|
||||
@ -255,7 +245,7 @@ commit (argc, argv)
|
||||
err = start_recursion (commit_fileproc, commit_filesdoneproc,
|
||||
commit_direntproc, commit_dirleaveproc,
|
||||
argc, argv, local, W_LOCAL, aflag, 0,
|
||||
(char *) NULL, 1);
|
||||
(char *) NULL, 1, 0);
|
||||
|
||||
/*
|
||||
* Unlock all the dirs and clean up
|
||||
@ -291,6 +281,7 @@ lock_filesdoneproc (err, repository, update_dir)
|
||||
p = getnode ();
|
||||
p->type = LOCK;
|
||||
p->key = xstrdup (repository);
|
||||
/* FIXME-KRP: this error condition should not simply be passed by. */
|
||||
if (p->key == NULL || addnode (locklist, p) != 0)
|
||||
freenode (p);
|
||||
return (err);
|
||||
@ -330,15 +321,23 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
{
|
||||
status = Classify_File (file, (char *) NULL, (char *) NULL,
|
||||
(char *) NULL, 1, aflag, repository,
|
||||
entries, srcfiles, &vers);
|
||||
if (status == T_UPTODATE)
|
||||
entries, srcfiles, &vers, update_dir, 0);
|
||||
if (status == T_UPTODATE || status == T_MODIFIED ||
|
||||
status == T_ADDED)
|
||||
{
|
||||
Ctype xstatus;
|
||||
|
||||
freevers_ts (&vers);
|
||||
status = Classify_File (file, tag, (char *) NULL,
|
||||
xstatus = Classify_File (file, tag, (char *) NULL,
|
||||
(char *) NULL, 1, aflag, repository,
|
||||
entries, srcfiles, &vers);
|
||||
if (status == T_REMOVE_ENTRY)
|
||||
entries, srcfiles, &vers, update_dir,
|
||||
0);
|
||||
if (xstatus == T_REMOVE_ENTRY)
|
||||
status = T_MODIFIED;
|
||||
else if (status == T_MODIFIED && xstatus == T_CONFLICT)
|
||||
status = T_MODIFIED;
|
||||
else
|
||||
status = xstatus;
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -352,21 +351,22 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
xtag = xstrdup (tag);
|
||||
if ((numdots (xtag) & 1) != 0)
|
||||
{
|
||||
cp = rindex (xtag, '.');
|
||||
cp = strrchr (xtag, '.');
|
||||
*cp = '\0';
|
||||
}
|
||||
status = Classify_File (file, xtag, (char *) NULL,
|
||||
(char *) NULL, 1, aflag, repository,
|
||||
entries, srcfiles, &vers);
|
||||
entries, srcfiles, &vers, update_dir, 0);
|
||||
if ((status == T_REMOVE_ENTRY || status == T_CONFLICT)
|
||||
&& (cp = rindex (xtag, '.')) != NULL)
|
||||
&& (cp = strrchr (xtag, '.')) != NULL)
|
||||
{
|
||||
/* pluck one more dot off the revision */
|
||||
*cp = '\0';
|
||||
freevers_ts (&vers);
|
||||
status = Classify_File (file, xtag, (char *) NULL,
|
||||
(char *) NULL, 1, aflag, repository,
|
||||
entries, srcfiles, &vers);
|
||||
entries, srcfiles, &vers, update_dir,
|
||||
0);
|
||||
if (status == T_UPTODATE || status == T_REMOVE_ENTRY)
|
||||
status = T_MODIFIED;
|
||||
}
|
||||
@ -378,17 +378,30 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
}
|
||||
else
|
||||
status = Classify_File (file, tag, (char *) NULL, (char *) NULL,
|
||||
1, 0, repository, entries, srcfiles, &vers);
|
||||
1, 0, repository, entries, srcfiles, &vers,
|
||||
update_dir, 0);
|
||||
noexec = save_noexec;
|
||||
quiet = save_quiet;
|
||||
really_quiet = save_really_quiet;
|
||||
|
||||
/*
|
||||
* If the force-commit option is enabled, and the file in question
|
||||
* appears to be up-to-date, just make it look modified so that
|
||||
* it will be committed.
|
||||
*/
|
||||
if (force_ci && status == T_UPTODATE)
|
||||
status = T_MODIFIED;
|
||||
|
||||
switch (status)
|
||||
{
|
||||
case T_CHECKOUT:
|
||||
case T_NEEDS_MERGE:
|
||||
case T_CONFLICT:
|
||||
case T_REMOVE_ENTRY:
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0, "Up-to-date check failed for `%s'", file);
|
||||
else
|
||||
error (0, 0, "Up-to-date check failed for `%s/%s'",
|
||||
update_dir, file);
|
||||
error (0, 0, "Up-to-date check failed for `%s'", file);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
@ -403,32 +416,115 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
* - if status is T_REMOVED, can't have a numeric tag
|
||||
* - if status is T_ADDED, rcs file must not exist
|
||||
* - if status is T_ADDED, can't have a non-trunk numeric rev
|
||||
* - if status is T_MODIFIED and a Conflict marker exists, don't
|
||||
* allow the commit if timestamp is identical or if we find
|
||||
* an RCS_MERGE_PAT in the file.
|
||||
*/
|
||||
if (!tag || !isdigit (*tag))
|
||||
{
|
||||
if (vers->date)
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0,
|
||||
"cannot commit with sticky date for file `%s'",
|
||||
file);
|
||||
else
|
||||
error
|
||||
(0, 0,
|
||||
"cannot commit with sticky date for file `%s/%s'",
|
||||
update_dir, file);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
}
|
||||
if (status == T_MODIFIED && vers->tag &&
|
||||
!RCS_isbranch (file, vers->tag, srcfiles))
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0,
|
||||
"sticky tag `%s' for file `%s' is not a branch",
|
||||
vers->tag, file);
|
||||
else
|
||||
error
|
||||
(0, 0,
|
||||
"sticky tag `%s' for file `%s/%s' is not a branch",
|
||||
vers->tag, update_dir, file);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
if (status == T_MODIFIED && !force_ci && vers->ts_conflict)
|
||||
{
|
||||
char *filestamp;
|
||||
int retcode;
|
||||
|
||||
/*
|
||||
* We found a "conflict" marker.
|
||||
*
|
||||
* If the timestamp on the file is the same as the
|
||||
* timestamp stored in the Entries file, we block the commit.
|
||||
*/
|
||||
filestamp = time_stamp (file);
|
||||
retcode = strcmp (vers->ts_conflict, filestamp);
|
||||
free (filestamp);
|
||||
if (retcode == 0)
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0,
|
||||
"file `%s' had a conflict and has not been modified",
|
||||
file);
|
||||
else
|
||||
error (0, 0,
|
||||
"file `%s/%s' had a conflict and has not been modified",
|
||||
update_dir, file);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the timestamps differ, look for Conflict indicators
|
||||
* in the file to see if we should block the commit anyway
|
||||
*/
|
||||
run_setup ("%s -s", GREP);
|
||||
run_arg (RCS_MERGE_PAT);
|
||||
run_arg (file);
|
||||
retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
||||
|
||||
if (retcode == -1)
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (1, errno,
|
||||
"fork failed while examining conflict in `%s'",
|
||||
file);
|
||||
else
|
||||
error (1, errno,
|
||||
"fork failed while examining conflict in `%s/%s'",
|
||||
update_dir, file);
|
||||
}
|
||||
else if (retcode == 0)
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0,
|
||||
"file `%s' still contains conflict indicators",
|
||||
file);
|
||||
else
|
||||
error (0, 0,
|
||||
"file `%s/%s' still contains conflict indicators",
|
||||
update_dir, file);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
if (status == T_REMOVED && vers->tag && isdigit (*vers->tag))
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0,
|
||||
"cannot remove file `%s' which has a numeric sticky tag of `%s'",
|
||||
file, vers->tag);
|
||||
else
|
||||
error (0, 0,
|
||||
"cannot remove file `%s/%s' which has a numeric sticky tag of `%s'",
|
||||
update_dir, file, vers->tag);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
}
|
||||
@ -439,18 +535,28 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
locate_rcs (file, repository, rcs);
|
||||
if (isreadable (rcs))
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0,
|
||||
"cannot add file `%s' when RCS file `%s' already exists",
|
||||
file, rcs);
|
||||
else
|
||||
error (0, 0,
|
||||
"cannot add file `%s/%s' when RCS file `%s' already exists",
|
||||
update_dir, file, rcs);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
}
|
||||
if (vers->tag && isdigit (*vers->tag) &&
|
||||
numdots (vers->tag) > 1)
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0,
|
||||
"cannot add file `%s' with revision `%s'; must be on trunk",
|
||||
file, vers->tag);
|
||||
else
|
||||
error (0, 0,
|
||||
"cannot add file `%s/%s' with revision `%s'; must be on trunk",
|
||||
update_dir, file, vers->tag);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
}
|
||||
@ -480,6 +586,7 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
ml->ulist = ulist;
|
||||
ml->cilist = cilist;
|
||||
p->data = (char *) ml;
|
||||
p->delproc = masterlist_delproc;
|
||||
(void) addnode (mulist, p);
|
||||
}
|
||||
|
||||
@ -505,17 +612,21 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
else
|
||||
ci->rev = (char *) NULL;
|
||||
ci->tag = xstrdup (vers->tag);
|
||||
ci->options = xstrdup(vers->options);
|
||||
p->data = (char *) ci;
|
||||
(void) addnode (cilist, p);
|
||||
break;
|
||||
case T_UNKNOWN:
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, 0, "nothing known about `%s'", file);
|
||||
else
|
||||
error (0, 0, "nothing known about `%s/%s'", update_dir, file);
|
||||
freevers_ts (&vers);
|
||||
return (1);
|
||||
case T_UPTODATE:
|
||||
break;
|
||||
default:
|
||||
error (0, 0, "Unknown status 0x%x for `%s'", status, file);
|
||||
error (0, 0, "CVS internal error: unknown status %d", status);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -543,11 +654,15 @@ check_direntproc (dir, repos, update_dir)
|
||||
* Walklist proc to run pre-commit checks
|
||||
*/
|
||||
static int
|
||||
precommit_list_proc (p)
|
||||
precommit_list_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
if (p->data == (char *) T_ADDED || p->data == (char *) T_MODIFIED ||
|
||||
p->data == (char *) T_REMOVED)
|
||||
{
|
||||
if (p->data == (char *) T_ADDED || p->data == (char *) T_MODIFIED)
|
||||
run_arg (p->key);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -561,14 +676,28 @@ precommit_proc (repository, filter)
|
||||
char *filter;
|
||||
{
|
||||
/* see if the filter is there, only if it's a full path */
|
||||
if (filter[0] == '/' && !isfile (filter))
|
||||
if (filter[0] == '/')
|
||||
{
|
||||
error (0, errno, "cannot find pre-commit filter `%s'", filter);
|
||||
char *s, *cp;
|
||||
|
||||
s = xstrdup (filter);
|
||||
for (cp = s; *cp; cp++)
|
||||
if (isspace (*cp))
|
||||
{
|
||||
*cp = '\0';
|
||||
break;
|
||||
}
|
||||
if (!isfile (s))
|
||||
{
|
||||
error (0, errno, "cannot find pre-commit filter `%s'", s);
|
||||
free (s);
|
||||
return (1); /* so it fails! */
|
||||
}
|
||||
free (s);
|
||||
}
|
||||
|
||||
run_setup ("%s %s", filter, repository);
|
||||
(void) walklist (ulist, precommit_list_proc);
|
||||
(void) walklist (ulist, precommit_list_proc, NULL);
|
||||
return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
|
||||
}
|
||||
|
||||
@ -649,7 +778,7 @@ commit_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
if (use_editor && !got_message)
|
||||
{
|
||||
got_message = 1;
|
||||
do_editor (update_dir, message, repository, ulist);
|
||||
do_editor (update_dir, &message, repository, ulist);
|
||||
}
|
||||
|
||||
p = findnode (cilist, file);
|
||||
@ -662,15 +791,17 @@ commit_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
if (lockrcsfile (file, repository, ci->rev) != 0)
|
||||
{
|
||||
unlockrcs (file, repository);
|
||||
return (1);
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else if (ci->status == T_ADDED)
|
||||
{
|
||||
if (checkaddfile (file, repository, ci->tag) != 0)
|
||||
if (checkaddfile (file, repository, ci->tag, srcfiles) != 0)
|
||||
{
|
||||
fixaddfile (file, repository);
|
||||
return (1);
|
||||
err = 1;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
@ -685,7 +816,7 @@ commit_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
{
|
||||
/* find the max major rev number in this directory */
|
||||
maxrev = 0;
|
||||
(void) walklist (entries, findmaxrev);
|
||||
(void) walklist (entries, findmaxrev, NULL);
|
||||
if (maxrev == 0)
|
||||
maxrev = 1;
|
||||
xrev = xmalloc (20);
|
||||
@ -693,27 +824,34 @@ commit_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
}
|
||||
|
||||
/* XXX - an added file with symbolic -r should add tag as well */
|
||||
err = finaladd (file, ci->rev ? ci->rev : xrev, ci->tag,
|
||||
err = finaladd (file, ci->rev ? ci->rev : xrev, ci->tag, ci->options,
|
||||
repository, entries);
|
||||
if (xrev)
|
||||
free (xrev);
|
||||
return (err);
|
||||
}
|
||||
|
||||
if (ci->status == T_MODIFIED)
|
||||
else if (ci->status == T_MODIFIED)
|
||||
{
|
||||
locate_rcs (file, repository, rcs);
|
||||
err = Checkin ('M', file, repository, rcs, ci->rev, ci->tag,
|
||||
message, entries);
|
||||
ci->options, message, entries);
|
||||
if (err != 0)
|
||||
{
|
||||
unlockrcs (file, repository);
|
||||
fixbranch (file, repository, sbranch);
|
||||
}
|
||||
}
|
||||
else if (ci->status == T_REMOVED)
|
||||
err = remove_file (file, repository, ci->tag, message,
|
||||
entries, srcfiles);
|
||||
|
||||
if (ci->status == T_REMOVED)
|
||||
err = remove_file (file, repository, ci->tag, entries);
|
||||
out:
|
||||
if (err != 0)
|
||||
{
|
||||
/* on failure, remove the file from ulist */
|
||||
p = findnode (ulist, file);
|
||||
if (p)
|
||||
delnode (p);
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
@ -728,19 +866,16 @@ commit_filesdoneproc (err, repository, update_dir)
|
||||
char *repository;
|
||||
char *update_dir;
|
||||
{
|
||||
List *ulist, *cilist;
|
||||
char *xtag = (char *) NULL;
|
||||
Node *p;
|
||||
List *ulist;
|
||||
|
||||
p = findnode (mulist, update_dir);
|
||||
if (p != NULL)
|
||||
{
|
||||
ulist = ((struct master_lists *) p->data)->ulist;
|
||||
cilist = ((struct master_lists *) p->data)->cilist;
|
||||
}
|
||||
else
|
||||
if (p == NULL)
|
||||
return (err);
|
||||
|
||||
ulist = ((struct master_lists *) p->data)->ulist;
|
||||
|
||||
got_message = 0;
|
||||
|
||||
/* see if we need to specify a per-directory or -r option tag */
|
||||
@ -748,8 +883,6 @@ commit_filesdoneproc (err, repository, update_dir)
|
||||
ParseTag (&xtag, (char **) NULL);
|
||||
|
||||
Update_Logfile (repository, message, tag ? tag : xtag, (FILE *) 0, ulist);
|
||||
dellist (&ulist);
|
||||
dellist (&cilist);
|
||||
if (xtag)
|
||||
free (xtag);
|
||||
|
||||
@ -765,7 +898,7 @@ commit_filesdoneproc (err, repository, update_dir)
|
||||
{
|
||||
if (fgets (line, sizeof (line), fp) != NULL)
|
||||
{
|
||||
if ((cp = rindex (line, '\n')) != NULL)
|
||||
if ((cp = strrchr (line, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
repository = Name_Repository ((char *) NULL, update_dir);
|
||||
run_setup ("%s %s", line, repository);
|
||||
@ -817,7 +950,7 @@ commit_direntproc (dir, repos, update_dir)
|
||||
{
|
||||
got_message = 1;
|
||||
real_repos = Name_Repository (dir, update_dir);
|
||||
do_editor (update_dir, message, real_repos, ulist);
|
||||
do_editor (update_dir, &message, real_repos, ulist);
|
||||
free (real_repos);
|
||||
}
|
||||
return (R_PROCESS);
|
||||
@ -844,15 +977,16 @@ commit_dirleaveproc (dir, err, update_dir)
|
||||
* find the maximum major rev number in an entries file
|
||||
*/
|
||||
static int
|
||||
findmaxrev (p)
|
||||
findmaxrev (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
char *cp;
|
||||
int thisrev;
|
||||
Entnode *entdata;
|
||||
|
||||
entdata = (Entnode *) p->data;
|
||||
cp = index (entdata->version, '.');
|
||||
cp = strchr (entdata->version, '.');
|
||||
if (cp != NULL)
|
||||
*cp = '\0';
|
||||
thisrev = atoi (entdata->version);
|
||||
@ -870,18 +1004,23 @@ findmaxrev (p)
|
||||
* link to keep it relative after we move it into the attic.
|
||||
*/
|
||||
static int
|
||||
remove_file (file, repository, tag, entries)
|
||||
remove_file (file, repository, tag, message, entries, srcfiles)
|
||||
char *file;
|
||||
char *repository;
|
||||
char *tag;
|
||||
char *message;
|
||||
List *entries;
|
||||
List *srcfiles;
|
||||
{
|
||||
int omask;
|
||||
mode_t omask;
|
||||
int retcode;
|
||||
char rcs[PATH_MAX];
|
||||
char tmp[PATH_MAX];
|
||||
char *tmp;
|
||||
|
||||
retcode = 0;
|
||||
|
||||
locate_rcs (file, repository, rcs);
|
||||
|
||||
if (tag)
|
||||
{
|
||||
/* a symbolic tag is specified; just remove the tag from the file */
|
||||
@ -894,17 +1033,25 @@ remove_file (file, repository, tag, entries)
|
||||
"failed to remove tag `%s' from `%s'", tag, rcs);
|
||||
return (1);
|
||||
}
|
||||
Scratch_Entry (entries, file);
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* no symbolic tag specified; really move it into the Attic */
|
||||
/* this was the head; really move it into the Attic */
|
||||
tmp = xmalloc(strlen(repository) +
|
||||
sizeof('/') +
|
||||
sizeof(CVSATTIC) +
|
||||
sizeof('/') +
|
||||
strlen(file) +
|
||||
sizeof(RCSEXT) + 1);
|
||||
(void) sprintf (tmp, "%s/%s", repository, CVSATTIC);
|
||||
omask = umask (2);
|
||||
(void) mkdir (tmp, 0777);
|
||||
(void) umask (omask);
|
||||
(void) sprintf (tmp, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
|
||||
|
||||
|
||||
if ((strcmp (rcs, tmp) == 0 || rename (rcs, tmp) != -1) ||
|
||||
(!isreadable (rcs) && isreadable (tmp)))
|
||||
{
|
||||
@ -919,10 +1066,11 @@ remove_file (file, repository, tag, entries)
|
||||
* Do the actual checkin for added files
|
||||
*/
|
||||
static int
|
||||
finaladd (file, rev, tag, repository, entries)
|
||||
finaladd (file, rev, tag, options, repository, entries)
|
||||
char *file;
|
||||
char *rev;
|
||||
char *tag;
|
||||
char *options;
|
||||
char *repository;
|
||||
List *entries;
|
||||
{
|
||||
@ -931,7 +1079,7 @@ finaladd (file, rev, tag, repository, entries)
|
||||
char rcs[PATH_MAX];
|
||||
|
||||
locate_rcs (file, repository, rcs);
|
||||
ret = Checkin ('A', file, repository, rcs, rev, tag,
|
||||
ret = Checkin ('A', file, repository, rcs, rev, tag, options,
|
||||
message, entries);
|
||||
if (ret == 0)
|
||||
{
|
||||
@ -1015,24 +1163,27 @@ fixbranch (file, repository, branch)
|
||||
* with a tag, put the file in the Attic and point the symbolic tag
|
||||
* at the committed revision.
|
||||
*/
|
||||
|
||||
static int
|
||||
checkaddfile (file, repository, tag)
|
||||
checkaddfile (file, repository, tag, srcfiles)
|
||||
char *file;
|
||||
char *repository;
|
||||
char *tag;
|
||||
List *srcfiles;
|
||||
{
|
||||
FILE *fp;
|
||||
char *cp;
|
||||
char rcs[PATH_MAX];
|
||||
char fname[PATH_MAX];
|
||||
int omask;
|
||||
mode_t omask;
|
||||
int retcode = 0;
|
||||
|
||||
if (tag)
|
||||
{
|
||||
(void) sprintf(rcs, "%s/%s", repository, CVSATTIC);
|
||||
omask = umask (2);
|
||||
(void) mkdir (rcs, 0777);
|
||||
if (mkdir (rcs, 0777) != 0 && errno != EEXIST)
|
||||
error (1, errno, "cannot make directory `%s'", rcs);;
|
||||
(void) umask (omask);
|
||||
(void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
|
||||
}
|
||||
@ -1045,7 +1196,7 @@ checkaddfile (file, repository, tag)
|
||||
fp = open_file (fname, "r");
|
||||
while (fgets (fname, sizeof (fname), fp) != NULL)
|
||||
{
|
||||
if ((cp = rindex (fname, '\n')) != NULL)
|
||||
if ((cp = strrchr (fname, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
if (*fname)
|
||||
run_arg (fname);
|
||||
@ -1058,6 +1209,7 @@ checkaddfile (file, repository, tag)
|
||||
"could not create %s", rcs);
|
||||
return (1);
|
||||
}
|
||||
|
||||
fix_rcs_modes (rcs, file);
|
||||
return (0);
|
||||
}
|
||||
@ -1207,9 +1359,26 @@ ci_delproc (p)
|
||||
free (ci->rev);
|
||||
if (ci->tag)
|
||||
free (ci->tag);
|
||||
if (ci->options)
|
||||
free (ci->options);
|
||||
free (ci);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the commit_info structure in p.
|
||||
*/
|
||||
static void
|
||||
masterlist_delproc (p)
|
||||
Node *p;
|
||||
{
|
||||
struct master_lists *ml;
|
||||
|
||||
ml = (struct master_lists *) p->data;
|
||||
dellist (&ml->ulist);
|
||||
dellist (&ml->cilist);
|
||||
free (ml);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an RCS file in the repository.
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Create Administration.
|
||||
*
|
||||
@ -14,7 +14,8 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)create_adm.c 1.24 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)create_adm.c 1.28 94/09/23 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
void
|
||||
@ -31,9 +32,6 @@ Create_Admin (dir, repository, tag, date)
|
||||
if (noexec)
|
||||
return;
|
||||
|
||||
if (!isdir (repository))
|
||||
error (1, 0, "there is no repository %s", repository);
|
||||
|
||||
if (dir != NULL)
|
||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM);
|
||||
else
|
||||
@ -58,6 +56,11 @@ Create_Admin (dir, repository, tag, date)
|
||||
(void) strcpy (tmp, CVSADM);
|
||||
make_directory (tmp);
|
||||
|
||||
#ifdef CVSADM_ROOT
|
||||
/* record the current cvs root for later use */
|
||||
|
||||
Create_Root (dir, CVSroot);
|
||||
#endif /* CVSADM_ROOT */
|
||||
if (dir != NULL)
|
||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
|
||||
else
|
||||
|
@ -2,7 +2,7 @@
|
||||
.ds Rv \\$3
|
||||
.ds Dt \\$4
|
||||
..
|
||||
.Id cvs.1,v 1.12 1992/04/10 03:05:16 berliner Exp
|
||||
.Id $Id: cvs.1,v 1.16 1994/10/03 21:26:10 berliner Exp $
|
||||
.TH CVS 1 "\*(Dt"
|
||||
.\" Full space in nroff; half space in troff
|
||||
.de SP
|
||||
@ -181,8 +181,10 @@ Use
|
||||
.I editor
|
||||
to enter revision log information.
|
||||
Overrides the setting of the
|
||||
.SM CVSEDITOR
|
||||
and the
|
||||
.SM EDITOR
|
||||
environment variable.
|
||||
environment variables.
|
||||
.TP
|
||||
.B \-l
|
||||
Do not log the
|
||||
@ -206,7 +208,7 @@ activity. Particularly useful with
|
||||
to explore the potential impact of an unfamiliar command.
|
||||
.TP
|
||||
.B \-r
|
||||
Makes new working files files read-only.
|
||||
Makes new working files read-only.
|
||||
Same effect as if the
|
||||
.SM CVSREAD
|
||||
environment variable is set.
|
||||
@ -388,7 +390,7 @@ same date (unless you explicitly override it; see the description of
|
||||
the \fBupdate\fP command).
|
||||
.B \-D
|
||||
is available with the
|
||||
.BR checkout ", " diff, ", " history ", " export ", "
|
||||
.BR checkout ", " diff ", " history ", " export ", "
|
||||
.BR rdiff ", " rtag ", and "
|
||||
.B update
|
||||
commands.
|
||||
@ -437,7 +439,7 @@ options described in
|
||||
.BR rcs ( 1 )
|
||||
are available. The \fB\-k\fP option is available with the
|
||||
.BR add ", " checkout ", " diff ", "
|
||||
.RB rdiff ", and " update
|
||||
.BR rdiff ", and " update
|
||||
commands. Your \fIkflag\fP specification is ``sticky'' when you use
|
||||
it to create a private copy of a source file; that is, when you use
|
||||
this option with the \fBcheckout\fP or \fBupdate\fP commands,
|
||||
@ -911,6 +913,13 @@ changed; you can use the
|
||||
option to limit
|
||||
.B commit
|
||||
to the current directory only.
|
||||
Sometimes you may want to force a file to be committed even though it
|
||||
is unchanged; this is achieved with the
|
||||
.B \-f
|
||||
flag, which also has the effect of disabling recursion (you can turn
|
||||
it back on with
|
||||
.B \-R
|
||||
of course).
|
||||
.SP
|
||||
.B commit
|
||||
verifies that the selected files are up to date with the current revisions
|
||||
@ -931,7 +940,7 @@ source repository file.
|
||||
You can instead specify the log message on the command line with the
|
||||
.B \-m
|
||||
option, thus suppressing the editor invocation, or use the
|
||||
.B \-f
|
||||
.B \-F
|
||||
option to specify that the argument \fIfile\fP contains the log message.
|
||||
.SP
|
||||
The
|
||||
@ -960,7 +969,8 @@ number of dots) with the
|
||||
.B \-r
|
||||
option.
|
||||
To create a branch revision, one typically use the
|
||||
.B \-b option of the
|
||||
.B \-b
|
||||
option of the
|
||||
.BR rtag " or " tag
|
||||
commands.
|
||||
Then, either
|
||||
@ -1144,7 +1154,7 @@ Report on checked-out modules.
|
||||
.B \ \ \ \ \ \ \-T
|
||||
Report on all tags.
|
||||
.TP 1i
|
||||
\fB\ \ \ \ \ \ \-x\fP \fItyp\fP
|
||||
\fB\ \ \ \ \ \ \-x\fP \fItype\fP
|
||||
Extract a particular set of record types \fIX\fP from the \fBcvs\fP
|
||||
history. The types are indicated by single letters, which you may
|
||||
specify in combination.
|
||||
@ -1162,6 +1172,18 @@ added; and `R', when a file is removed.
|
||||
.B \ \ \ \ \ \ \-e
|
||||
Everything (all record types); equivalent to specifying
|
||||
.` "\-xMACFROGWUT".
|
||||
.TP 1i
|
||||
\fB\ \ \ \ \ \ \-z\fP \fIzone\fP
|
||||
Use time zone
|
||||
.I zone
|
||||
when outputting history records.
|
||||
The zone name
|
||||
.B LT
|
||||
stands for local time;
|
||||
numeric offsets stand for hours and minutes ahead of UTC.
|
||||
For example,
|
||||
.B +0530
|
||||
stands for 5 hours and 30 minutes ahead of (i.e. east of) UTC.
|
||||
.PP
|
||||
.RS .5i
|
||||
The options shown as \fB\-\fP\fIflags\fP constrain the report without
|
||||
@ -1260,8 +1282,8 @@ CVS* cvslog.*
|
||||
tags TAGS
|
||||
\&.make.state .nse_depinfo
|
||||
*~ #* .#* ,*
|
||||
*.old *.bak *.orig *.rej .del\-*
|
||||
*.a *.o *.Z *.elc *.ln core
|
||||
*.old *.bak *.BAK *.orig *.rej .del\-*
|
||||
*.a *.o *.so *.Z *.elc *.ln core
|
||||
.fi
|
||||
.ft P
|
||||
.in -1i
|
||||
@ -1295,7 +1317,12 @@ command options are available: \fB\-Q\fP, \fB\-q\fP, and \fB\-m\fP
|
||||
\fB\-m\fP, your editor is invoked (as with \fBcommit\fP) to allow you
|
||||
to enter one.
|
||||
.SP
|
||||
There are two additional special options.
|
||||
There are three additional special options.
|
||||
.SP
|
||||
Use
|
||||
.` "\-d"
|
||||
to specify that each file's time of last modification should be used
|
||||
for the checkin date and time.
|
||||
.SP
|
||||
Use
|
||||
.` "\-b \fIbranch\fP"
|
||||
@ -1481,7 +1508,7 @@ into the
|
||||
.` "Attic"
|
||||
directory (also within the source repository).
|
||||
.SP
|
||||
This command is recursive by default, scheduing all physically removed
|
||||
This command is recursive by default, scheduling all physically removed
|
||||
files that it finds for removal by the next
|
||||
.BR commit .
|
||||
Use the
|
||||
@ -1546,7 +1573,7 @@ option to have
|
||||
.B rtag
|
||||
look in the
|
||||
.` "Attic"
|
||||
for removed files that contin the specified tag.
|
||||
for removed files that contain the specified tag.
|
||||
The tag is removed from these files, which makes it convenient to re-use a
|
||||
symbolic tag as development continues (and files get removed from the
|
||||
up-coming distribution).
|
||||
@ -1796,8 +1823,8 @@ CVS* cvslog.*
|
||||
tags TAGS
|
||||
\&.make.state .nse_depinfo
|
||||
*~ #* .#* ,*
|
||||
*.old *.bak *.orig *.rej .del\-*
|
||||
*.a *.o *.Z *.elc *.ln core
|
||||
*.old *.bak *.BAK *.orig *.rej .del\-*
|
||||
*.a *.o *.so *.Z *.elc *.ln core
|
||||
.fi
|
||||
.ft P
|
||||
.in -1i
|
||||
@ -1881,7 +1908,7 @@ Records programs for piping
|
||||
log entries.
|
||||
.TP
|
||||
CVSROOT/rcsinfo,v
|
||||
Records pathnames to templates used dueing a
|
||||
Records pathnames to templates used during a
|
||||
.` "cvs commit"
|
||||
operation.
|
||||
.TP
|
||||
@ -1946,10 +1973,15 @@ and
|
||||
If not set, a compiled-in value is used; see the display from
|
||||
.` "cvs \-v".
|
||||
.TP
|
||||
.SM EDITOR
|
||||
.SM CVSEDITOR
|
||||
Specifies the program to use for recording log messages during
|
||||
.BR commit .
|
||||
If not set, the default is
|
||||
If not set, the
|
||||
.SM EDITOR
|
||||
environment variable is used instead.
|
||||
If
|
||||
.SM EDITOR
|
||||
is not set either, the default is
|
||||
.BR /usr/ucb/vi .
|
||||
.SH "AUTHORS"
|
||||
.TP
|
||||
|
@ -243,7 +243,7 @@ removed by this \fBcommit\fP invocation.
|
||||
.SP
|
||||
For `\|commitinfo\|', the rest of the line is a command-line template to
|
||||
execute.
|
||||
The template can include can include not only a program name, but whatever
|
||||
The template can include not only a program name, but whatever
|
||||
list of arguments you wish.
|
||||
The full path to the current source repository is appended to the template,
|
||||
followed by the file names of any files involved in the commit (added,
|
||||
@ -254,7 +254,7 @@ should be loaded into the log message template.
|
||||
.SP
|
||||
For `\|editinfo\|', the rest of the line is a command-line template to
|
||||
execute.
|
||||
The template can include can include not only a program name, but whatever
|
||||
The template can include not only a program name, but whatever
|
||||
list of arguments you wish.
|
||||
The full path to the current log message template file is appended to the
|
||||
template.
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Entries file to Files file
|
||||
*
|
||||
@ -14,16 +14,13 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)entries.c 1.37 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)entries.c 1.44 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static Node *AddEntryNode (List * list, char *name, char *version,
|
||||
static Node *AddEntryNode PROTO((List * list, char *name, char *version,
|
||||
char *timestamp, char *options, char *tag,
|
||||
char *date);
|
||||
#else
|
||||
static Node *AddEntryNode ();
|
||||
#endif /* __STDC__ */
|
||||
char *date, char *conflict));
|
||||
|
||||
static FILE *entfile;
|
||||
static char *entfilename; /* for error messages */
|
||||
@ -32,15 +29,24 @@ static char *entfilename; /* for error messages */
|
||||
* Write out the line associated with a node of an entries file
|
||||
*/
|
||||
static int
|
||||
write_ent_proc (node)
|
||||
write_ent_proc (node, closure)
|
||||
Node *node;
|
||||
void *closure;
|
||||
{
|
||||
Entnode *p;
|
||||
|
||||
p = (Entnode *) node->data;
|
||||
if (fprintf (entfile, "/%s/%s/%s/%s/", node->key, p->version,
|
||||
p->timestamp, p->options) == EOF)
|
||||
if (fprintf (entfile, "/%s/%s/%s", node->key, p->version,
|
||||
p->timestamp) == EOF)
|
||||
error (1, errno, "cannot write %s", entfilename);
|
||||
if (p->conflict)
|
||||
{
|
||||
if (fprintf (entfile, "+%s", p->conflict) == EOF)
|
||||
error (1, errno, "cannot write %s", entfilename);
|
||||
}
|
||||
if (fprintf (entfile, "/%s/", p->options) == EOF)
|
||||
error (1, errno, "cannot write %s", entfilename);
|
||||
|
||||
if (p->tag)
|
||||
{
|
||||
if (fprintf (entfile, "T%s\n", p->tag) == EOF)
|
||||
@ -67,7 +73,7 @@ write_entries (list)
|
||||
/* open the new one and walk the list writing entries */
|
||||
entfilename = CVSADM_ENTBAK;
|
||||
entfile = open_file (entfilename, "w+");
|
||||
(void) walklist (list, write_ent_proc);
|
||||
(void) walklist (list, write_ent_proc, NULL);
|
||||
if (fclose (entfile) == EOF)
|
||||
error (1, errno, "error closing %s", entfilename);
|
||||
|
||||
@ -102,7 +108,7 @@ Scratch_Entry (list, fname)
|
||||
* removing the old entry first, if necessary.
|
||||
*/
|
||||
void
|
||||
Register (list, fname, vn, ts, options, tag, date)
|
||||
Register (list, fname, vn, ts, options, tag, date, ts_conflict)
|
||||
List *list;
|
||||
char *fname;
|
||||
char *vn;
|
||||
@ -110,13 +116,19 @@ Register (list, fname, vn, ts, options, tag, date)
|
||||
char *options;
|
||||
char *tag;
|
||||
char *date;
|
||||
char *ts_conflict;
|
||||
{
|
||||
int should_write_file = !noexec;
|
||||
Node *node;
|
||||
|
||||
if (trace)
|
||||
(void) fprintf (stderr, "-> Register(%s, %s, %s, %s, %s %s)\n",
|
||||
fname, vn, ts, options, tag ? tag : "",
|
||||
date ? date : "");
|
||||
{
|
||||
(void) fprintf (stderr, "-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
|
||||
fname, vn, ts,
|
||||
ts_conflict ? "+" : "", ts_conflict ? ts_conflict : "",
|
||||
options, tag ? tag : "", date ? date : "");
|
||||
}
|
||||
|
||||
/* was it already there? */
|
||||
if ((node = findnode (list, fname)) != NULL)
|
||||
{
|
||||
@ -124,21 +136,24 @@ Register (list, fname, vn, ts, options, tag, date)
|
||||
delnode (node);
|
||||
|
||||
/* add the new one and re-write the file */
|
||||
(void) AddEntryNode (list, fname, vn, ts, options, tag, date);
|
||||
if (!noexec)
|
||||
(void) AddEntryNode (list, fname, vn, ts, options, tag,
|
||||
date, ts_conflict);
|
||||
|
||||
if (should_write_file)
|
||||
write_entries (list);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* add the new one */
|
||||
node = AddEntryNode (list, fname, vn, ts, options, tag, date);
|
||||
node = AddEntryNode (list, fname, vn, ts, options, tag,
|
||||
date, ts_conflict);
|
||||
|
||||
if (!noexec)
|
||||
if (should_write_file)
|
||||
{
|
||||
/* append it to the end */
|
||||
entfilename = CVSADM_ENT;
|
||||
entfile = open_file (entfilename, "a");
|
||||
(void) write_ent_proc (node);
|
||||
(void) write_ent_proc (node, NULL);
|
||||
if (fclose (entfile) == EOF)
|
||||
error (1, errno, "error closing %s", entfilename);
|
||||
}
|
||||
@ -174,11 +189,14 @@ ParseEntries (aflag)
|
||||
List *entries;
|
||||
char line[MAXLINELEN];
|
||||
char *cp, *user, *vn, *ts, *options;
|
||||
char *tag_or_date, *tag, *date;
|
||||
char *tag_or_date, *tag, *date, *ts_conflict;
|
||||
char *dirtag, *dirdate;
|
||||
int lineno = 0;
|
||||
int do_rewrite = 0;
|
||||
FILE *fpin;
|
||||
|
||||
vn = ts = options = tag = date = ts_conflict = 0;
|
||||
|
||||
/* get a fresh list... */
|
||||
entries = getlist ();
|
||||
|
||||
@ -192,7 +210,7 @@ ParseEntries (aflag)
|
||||
struct stickydirtag *sdtp;
|
||||
|
||||
sdtp = (struct stickydirtag *) xmalloc (sizeof (*sdtp));
|
||||
bzero ((char *) sdtp, sizeof (*sdtp));
|
||||
memset ((char *) sdtp, 0, sizeof (*sdtp));
|
||||
sdtp->aflag = aflag;
|
||||
sdtp->tag = xstrdup (dirtag);
|
||||
sdtp->date = xstrdup (dirdate);
|
||||
@ -214,23 +232,23 @@ ParseEntries (aflag)
|
||||
if (line[0] == '/')
|
||||
{
|
||||
user = line + 1;
|
||||
if ((cp = index (user, '/')) == NULL)
|
||||
if ((cp = strchr (user, '/')) == NULL)
|
||||
continue;
|
||||
*cp++ = '\0';
|
||||
vn = cp;
|
||||
if ((cp = index (vn, '/')) == NULL)
|
||||
if ((cp = strchr (vn, '/')) == NULL)
|
||||
continue;
|
||||
*cp++ = '\0';
|
||||
ts = cp;
|
||||
if ((cp = index (ts, '/')) == NULL)
|
||||
if ((cp = strchr (ts, '/')) == NULL)
|
||||
continue;
|
||||
*cp++ = '\0';
|
||||
options = cp;
|
||||
if ((cp = index (options, '/')) == NULL)
|
||||
if ((cp = strchr (options, '/')) == NULL)
|
||||
continue;
|
||||
*cp++ = '\0';
|
||||
tag_or_date = cp;
|
||||
if ((cp = index (tag_or_date, '\n')) == NULL)
|
||||
if ((cp = strchr (tag_or_date, '\n')) == NULL)
|
||||
continue;
|
||||
*cp = '\0';
|
||||
tag = (char *) NULL;
|
||||
@ -239,7 +257,40 @@ ParseEntries (aflag)
|
||||
tag = tag_or_date + 1;
|
||||
else if (*tag_or_date == 'D')
|
||||
date = tag_or_date + 1;
|
||||
(void) AddEntryNode (entries, user, vn, ts, options, tag, date);
|
||||
|
||||
if (ts_conflict = strchr (ts, '+'))
|
||||
*ts_conflict++ = '\0';
|
||||
|
||||
/*
|
||||
* XXX - Convert timestamp from old format to new format.
|
||||
*
|
||||
* If the timestamp doesn't match the file's current
|
||||
* mtime, we'd have to generate a string that doesn't
|
||||
* match anyways, so cheat and base it on the existing
|
||||
* string; it doesn't have to match the same mod time.
|
||||
*
|
||||
* For an unmodified file, write the correct timestamp.
|
||||
*/
|
||||
{
|
||||
struct stat sb;
|
||||
if (strlen (ts) > 30 && stat (user, &sb) == 0)
|
||||
{
|
||||
extern char *ctime ();
|
||||
char *c = ctime (&sb.st_mtime);
|
||||
|
||||
if (!strncmp (ts + 25, c, 24))
|
||||
ts = time_stamp (user);
|
||||
else
|
||||
{
|
||||
ts += 24;
|
||||
ts[0] = '*';
|
||||
}
|
||||
do_rewrite = 1;
|
||||
}
|
||||
}
|
||||
|
||||
(void) AddEntryNode (entries, user, vn, ts, options, tag,
|
||||
date, ts_conflict);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -254,6 +305,9 @@ ParseEntries (aflag)
|
||||
}
|
||||
}
|
||||
|
||||
if (do_rewrite && !noexec)
|
||||
write_entries (entries);
|
||||
|
||||
/* clean up and return */
|
||||
if (fpin)
|
||||
(void) fclose (fpin);
|
||||
@ -311,13 +365,13 @@ check_entries (dir)
|
||||
continue;
|
||||
}
|
||||
rev = line;
|
||||
if ((ts = index (line, '|')) == NULL)
|
||||
if ((ts = strchr (line, '|')) == NULL)
|
||||
continue;
|
||||
*ts++ = '\0';
|
||||
if ((user = rindex (ts, ' ')) == NULL)
|
||||
if ((user = strrchr (ts, ' ')) == NULL)
|
||||
continue;
|
||||
*user++ = '\0';
|
||||
if ((cp = index (user, '|')) == NULL)
|
||||
if ((cp = strchr (user, '|')) == NULL)
|
||||
continue;
|
||||
*cp = '\0';
|
||||
opt = "";
|
||||
@ -368,6 +422,8 @@ Entries_delproc (node)
|
||||
free (p->tag);
|
||||
if (p->date)
|
||||
free (p->date);
|
||||
if (p->conflict)
|
||||
free (p->conflict);
|
||||
free ((char *) p);
|
||||
}
|
||||
|
||||
@ -376,7 +432,7 @@ Entries_delproc (node)
|
||||
* list
|
||||
*/
|
||||
static Node *
|
||||
AddEntryNode (list, name, version, timestamp, options, tag, date)
|
||||
AddEntryNode (list, name, version, timestamp, options, tag, date, conflict)
|
||||
List *list;
|
||||
char *name;
|
||||
char *version;
|
||||
@ -384,6 +440,7 @@ AddEntryNode (list, name, version, timestamp, options, tag, date)
|
||||
char *options;
|
||||
char *tag;
|
||||
char *date;
|
||||
char *conflict;
|
||||
{
|
||||
Node *p;
|
||||
Entnode *entdata;
|
||||
@ -404,6 +461,7 @@ AddEntryNode (list, name, version, timestamp, options, tag, date)
|
||||
entdata->options = xstrdup (options);
|
||||
if (entdata->options == NULL)
|
||||
entdata->options = xstrdup ("");/* must be non-NULL */
|
||||
entdata->conflict = xstrdup (conflict);
|
||||
entdata->tag = xstrdup (tag);
|
||||
entdata->date = xstrdup (date);
|
||||
|
||||
@ -452,7 +510,8 @@ WriteTag (dir, tag, date)
|
||||
error (1, errno, "cannot close %s", tmp);
|
||||
}
|
||||
else
|
||||
(void) unlink_file (tmp);
|
||||
if (unlink_file (tmp) < 0 && errno != ENOENT)
|
||||
error (1, errno, "cannot remove %s", tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -476,7 +535,7 @@ ParseTag (tagp, datep)
|
||||
{
|
||||
if (fgets (line, sizeof (line), fp) != NULL)
|
||||
{
|
||||
if ((cp = rindex (line, '\n')) != NULL)
|
||||
if ((cp = strrchr (line, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
if (*line == 'T' && tagp)
|
||||
*tagp = xstrdup (line + 1);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Find Names
|
||||
*
|
||||
@ -19,16 +19,12 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)find_names.c 1.38 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)find_names.c 1.45 94/10/22 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static int find_dirs (char *dir, List * list, int checkadm);
|
||||
static int find_rcs (char *dir, List * list);
|
||||
#else
|
||||
static int find_rcs ();
|
||||
static int find_dirs ();
|
||||
#endif /* __STDC__ */
|
||||
static int find_dirs PROTO((char *dir, List * list, int checkadm));
|
||||
static int find_rcs PROTO((char *dir, List * list));
|
||||
|
||||
static List *filelist;
|
||||
|
||||
@ -36,8 +32,9 @@ static List *filelist;
|
||||
* add the key from entry on entries list to the files list
|
||||
*/
|
||||
static int
|
||||
add_entries_proc (node)
|
||||
add_entries_proc (node, closure)
|
||||
Node *node;
|
||||
void *closure;
|
||||
{
|
||||
Node *fnode;
|
||||
|
||||
@ -82,7 +79,7 @@ Find_Names (repository, which, aflag, optentries)
|
||||
if (entries != NULL)
|
||||
{
|
||||
/* walk the entries file adding elements to the files list */
|
||||
(void) walklist (entries, add_entries_proc);
|
||||
(void) walklist (entries, add_entries_proc, NULL);
|
||||
|
||||
/* if our caller wanted the entries list, return it; else free it */
|
||||
if (optentries != NULL)
|
||||
@ -167,28 +164,21 @@ find_rcs (dir, list)
|
||||
List *list;
|
||||
{
|
||||
Node *p;
|
||||
CONST char *regex_err;
|
||||
char line[50];
|
||||
struct direct *dp;
|
||||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
|
||||
/* set up to read the dir */
|
||||
if ((dirp = opendir (dir)) == NULL)
|
||||
return (1);
|
||||
|
||||
/* set up a regular expression to find the ,v files */
|
||||
(void) sprintf (line, ".*%s$", RCSEXT);
|
||||
if ((regex_err = re_comp (line)) != NULL)
|
||||
error (1, 0, "%s", regex_err);
|
||||
|
||||
/* read the dir, grabbing the ,v files */
|
||||
while ((dp = readdir (dirp)) != NULL)
|
||||
{
|
||||
if (re_exec (dp->d_name))
|
||||
if (fnmatch (RCSPAT, dp->d_name, 0) == 0)
|
||||
{
|
||||
char *comma;
|
||||
|
||||
comma = rindex (dp->d_name, ','); /* strip the ,v */
|
||||
comma = strrchr (dp->d_name, ','); /* strip the ,v */
|
||||
*comma = '\0';
|
||||
p = getnode ();
|
||||
p->type = FILES;
|
||||
@ -213,17 +203,10 @@ find_dirs (dir, list, checkadm)
|
||||
int checkadm;
|
||||
{
|
||||
Node *p;
|
||||
CONST char *regex_err;
|
||||
char tmp[PATH_MAX];
|
||||
char admdir[PATH_MAX];
|
||||
struct direct *dp;
|
||||
struct dirent *dp;
|
||||
DIR *dirp;
|
||||
|
||||
/* build a regex to blow off ,v files */
|
||||
(void) sprintf (tmp, ".*%s$", RCSEXT);
|
||||
if ((regex_err = re_comp (tmp)) != NULL)
|
||||
error (1, 0, "%s", regex_err);
|
||||
|
||||
/* set up to read the dir */
|
||||
if ((dirp = opendir (dir)) == NULL)
|
||||
return (1);
|
||||
@ -234,27 +217,51 @@ find_dirs (dir, list, checkadm)
|
||||
if (strcmp (dp->d_name, ".") == 0 ||
|
||||
strcmp (dp->d_name, "..") == 0 ||
|
||||
strcmp (dp->d_name, CVSATTIC) == 0 ||
|
||||
strcmp (dp->d_name, CVSLCK) == 0 ||
|
||||
re_exec (dp->d_name)) /* don't bother stating ,v files */
|
||||
strcmp (dp->d_name, CVSLCK) == 0)
|
||||
continue;
|
||||
|
||||
(void) sprintf (tmp, "%s/%s", dir, dp->d_name);
|
||||
if (isdir (tmp))
|
||||
#ifdef DT_DIR
|
||||
if (dp->d_type != DT_DIR)
|
||||
{
|
||||
if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
|
||||
continue;
|
||||
#endif
|
||||
/* don't bother stating ,v files */
|
||||
if (fnmatch (RCSPAT, dp->d_name, 0) == 0)
|
||||
continue;
|
||||
|
||||
sprintf (tmp, "%s/%s", dir, dp->d_name);
|
||||
if (!isdir (tmp))
|
||||
continue;
|
||||
|
||||
#ifdef DT_DIR
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check for administration directories (if needed) */
|
||||
if (checkadm)
|
||||
{
|
||||
/* blow off symbolic links to dirs in local dir */
|
||||
#ifdef DT_DIR
|
||||
if (dp->d_type != DT_DIR)
|
||||
{
|
||||
/* we're either unknown or a symlink at this point */
|
||||
if (dp->d_type == DT_LNK)
|
||||
continue;
|
||||
#endif
|
||||
if (islink (tmp))
|
||||
continue;
|
||||
#ifdef DT_DIR
|
||||
}
|
||||
#endif
|
||||
|
||||
/* check for new style */
|
||||
(void) sprintf (admdir, "%s/%s", tmp, CVSADM);
|
||||
if (!isdir (admdir))
|
||||
(void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM);
|
||||
if (!isdir (tmp))
|
||||
{
|
||||
/* and old style */
|
||||
(void) sprintf (admdir, "%s/%s", tmp, OCVSADM);
|
||||
if (!isdir (admdir))
|
||||
(void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, OCVSADM);
|
||||
if (!isdir (tmp))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -266,7 +273,6 @@ find_dirs (dir, list, checkadm)
|
||||
if (addnode (list, p) != 0)
|
||||
freenode (p);
|
||||
}
|
||||
}
|
||||
(void) closedir (dirp);
|
||||
return (0);
|
||||
}
|
||||
|
@ -179,7 +179,8 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)history.c 1.31 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)history.c 1.33 94/09/21 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
static struct hrec
|
||||
@ -197,33 +198,18 @@ static struct hrec
|
||||
} *hrec_head;
|
||||
|
||||
|
||||
#if __STDC__
|
||||
static char *fill_hrec (char *line, struct hrec * hr);
|
||||
static int accept_hrec (struct hrec * hr, struct hrec * lr);
|
||||
static int select_hrec (struct hrec * hr);
|
||||
static int sort_order (CONST PTR l, CONST PTR r);
|
||||
static int within (char *find, char *string);
|
||||
static time_t date_and_time (char *date_str);
|
||||
static void expand_modules (void);
|
||||
static void read_hrecs (char *fname);
|
||||
static void report_hrecs (void);
|
||||
static void save_file (char *dir, char *name, char *module);
|
||||
static void save_module (char *module);
|
||||
static void save_user (char *name);
|
||||
#else
|
||||
static int sort_order ();
|
||||
static time_t date_and_time ();
|
||||
static void save_user ();
|
||||
static void save_file ();
|
||||
static void save_module ();
|
||||
static void expand_modules ();
|
||||
static char *fill_hrec ();
|
||||
static void read_hrecs ();
|
||||
static int within ();
|
||||
static int select_hrec ();
|
||||
static void report_hrecs ();
|
||||
static int accept_hrec ();
|
||||
#endif /* __STDC__ */
|
||||
static char *fill_hrec PROTO((char *line, struct hrec * hr));
|
||||
static int accept_hrec PROTO((struct hrec * hr, struct hrec * lr));
|
||||
static int select_hrec PROTO((struct hrec * hr));
|
||||
static int sort_order PROTO((CONST PTR l, CONST PTR r));
|
||||
static int within PROTO((char *find, char *string));
|
||||
static time_t date_and_time PROTO((char *date_str));
|
||||
static void expand_modules PROTO((void));
|
||||
static void read_hrecs PROTO((char *fname));
|
||||
static void report_hrecs PROTO((void));
|
||||
static void save_file PROTO((char *dir, char *name, char *module));
|
||||
static void save_module PROTO((char *module));
|
||||
static void save_user PROTO((char *name));
|
||||
|
||||
#define ALL_REC_TYPES "TOFWUCGMAR"
|
||||
#define USER_INCREMENT 2
|
||||
@ -247,6 +233,14 @@ static short repos_sort;
|
||||
static short file_sort;
|
||||
static short module_sort;
|
||||
|
||||
#ifdef HAVE_RCS5
|
||||
static short tz_local;
|
||||
static time_t tz_seconds_east_of_GMT;
|
||||
static char *tz_name = "+0000";
|
||||
#else
|
||||
static char tz_name[] = "LT";
|
||||
#endif
|
||||
|
||||
static time_t since_date;
|
||||
static char since_rev[20]; /* Maxrev ~= 99.99.99.999 */
|
||||
static char since_tag[64];
|
||||
@ -301,6 +295,7 @@ static char *history_usg[] =
|
||||
" -r <rev/tag> Since rev or tag (looks inside RCS files!)\n",
|
||||
" -t <tag> Since tag record placed in history file (by anyone).\n",
|
||||
" -u <user> For user name (repeatable)\n",
|
||||
" -z <tz> Output for time zone <tz> (e.g. -z -0700)\n",
|
||||
NULL};
|
||||
|
||||
/* Sort routine for qsort:
|
||||
@ -385,7 +380,7 @@ history (argc, argv)
|
||||
usage (history_usg);
|
||||
|
||||
optind = 1;
|
||||
while ((c = gnu_getopt (argc, argv, "Tacelow?D:b:f:m:n:p:r:t:u:x:X:")) != -1)
|
||||
while ((c = getopt (argc, argv, "Tacelow?D:b:f:m:n:p:r:t:u:x:X:z:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -481,11 +476,47 @@ history (argc, argv)
|
||||
char *cp;
|
||||
|
||||
for (cp = optarg; *cp; cp++)
|
||||
if (!index (ALL_REC_TYPES, *cp))
|
||||
error (1, 0, "%c is not a valid report type", cp);
|
||||
if (!strchr (ALL_REC_TYPES, *cp))
|
||||
error (1, 0, "%c is not a valid report type", *cp);
|
||||
}
|
||||
(void) strcpy (rec_types, optarg);
|
||||
break;
|
||||
case 'z':
|
||||
#ifndef HAVE_RCS5
|
||||
error (0, 0, "-z not supported with RCS 4");
|
||||
#else
|
||||
tz_local =
|
||||
(optarg[0] == 'l' || optarg[0] == 'L')
|
||||
&& (optarg[1] == 't' || optarg[1] == 'T')
|
||||
&& !optarg[2];
|
||||
if (tz_local)
|
||||
tz_name = optarg;
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Convert a known time with the given timezone to time_t.
|
||||
* Use the epoch + 23 hours, so timezones east of GMT work.
|
||||
*/
|
||||
static char f[] = "1/1/1970 23:00 %s";
|
||||
char *buf = xmalloc (sizeof (f) - 2 + strlen (optarg));
|
||||
time_t t;
|
||||
sprintf (buf, f, optarg);
|
||||
t = get_date (buf, (struct timeb *) NULL);
|
||||
free (buf);
|
||||
if (t == (time_t) -1)
|
||||
error (0, 0, "%s is not a known time zone", optarg);
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Convert to seconds east of GMT, removing the
|
||||
* 23-hour offset mentioned above.
|
||||
*/
|
||||
tz_seconds_east_of_GMT = (time_t)23 * 60 * 60 - t;
|
||||
tz_name = optarg;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage (history_usg);
|
||||
@ -508,7 +539,7 @@ history (argc, argv)
|
||||
|
||||
if (tag_report)
|
||||
{
|
||||
if (!index (rec_types, 'T'))
|
||||
if (!strchr (rec_types, 'T'))
|
||||
(void) strcat (rec_types, "T");
|
||||
}
|
||||
else if (extract)
|
||||
@ -559,7 +590,7 @@ history (argc, argv)
|
||||
save_user (getcaller ());
|
||||
|
||||
/* If we're looking back to a Tag value, must consider "Tag" records */
|
||||
if (*since_tag && !index (rec_types, 'T'))
|
||||
if (*since_tag && !strchr (rec_types, 'T'))
|
||||
(void) strcat (rec_types, "T");
|
||||
|
||||
argc -= c;
|
||||
@ -637,7 +668,7 @@ history_write (type, update_dir, revs, name, repository)
|
||||
if (chdir (pw->pw_dir) < 0)
|
||||
error (1, errno, "can't chdir(%s)", pw->pw_dir);
|
||||
if (!getwd (homedir))
|
||||
error (1, errno, "can't getwd in:", pw->pw_dir);
|
||||
error (1, errno, "can't getwd in %s", pw->pw_dir);
|
||||
(void) chdir (workdir);
|
||||
|
||||
i = strlen (homedir);
|
||||
@ -837,16 +868,16 @@ fill_hrec (line, hr)
|
||||
int off;
|
||||
static int idx = 0;
|
||||
|
||||
bzero ((char *) hr, sizeof (*hr));
|
||||
memset ((char *) hr, 0, sizeof (*hr));
|
||||
while (isspace (*line))
|
||||
line++;
|
||||
if (!(rtn = index (line, '\n')))
|
||||
if (!(rtn = strchr (line, '\n')))
|
||||
return ("");
|
||||
*rtn++ = '\0';
|
||||
|
||||
hr->type = line++;
|
||||
(void) sscanf (line, "%x", &hr->date);
|
||||
while (*line && index ("0123456789abcdefABCDEF", *line))
|
||||
while (*line && strchr ("0123456789abcdefABCDEF", *line))
|
||||
line++;
|
||||
if (*line == '\0')
|
||||
return (rtn);
|
||||
@ -854,7 +885,7 @@ fill_hrec (line, hr)
|
||||
line++;
|
||||
NEXT_BAR (user);
|
||||
NEXT_BAR (dir);
|
||||
if ((cp = rindex (hr->dir, '*')) != NULL)
|
||||
if ((cp = strrchr (hr->dir, '*')) != NULL)
|
||||
{
|
||||
*cp++ = '\0';
|
||||
(void) sscanf (cp, "%x", &off);
|
||||
@ -865,7 +896,7 @@ fill_hrec (line, hr)
|
||||
NEXT_BAR (repos);
|
||||
NEXT_BAR (rev);
|
||||
hr->idx = idx++;
|
||||
if (index ("FOT", *(hr->type)))
|
||||
if (strchr ("FOT", *(hr->type)))
|
||||
hr->mod = line;
|
||||
|
||||
NEXT_BAR (file); /* This returns ptr to next line or final '\0' */
|
||||
@ -981,7 +1012,7 @@ within (find, string)
|
||||
|
||||
while (*string)
|
||||
{
|
||||
if (!(string = index (string, c)))
|
||||
if (!(string = strchr (string, c)))
|
||||
return (0);
|
||||
string++;
|
||||
if (!strncmp (find, string, len))
|
||||
@ -1104,9 +1135,9 @@ select_hrec (hr)
|
||||
* file_list is null, keep everything. Otherwise, keep only files on
|
||||
* file_list, matched appropriately.
|
||||
*/
|
||||
if (!index (rec_types, *(hr->type)))
|
||||
if (!strchr (rec_types, *(hr->type)))
|
||||
return (0);
|
||||
if (!index ("TFO", *(hr->type))) /* Don't bother with "file" if "TFO" */
|
||||
if (!strchr ("TFO", *(hr->type))) /* Don't bother with "file" if "TFO" */
|
||||
{
|
||||
if (file_list) /* If file_list is null, accept all */
|
||||
{
|
||||
@ -1132,7 +1163,7 @@ select_hrec (hr)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (index (cp, '/'))
|
||||
if (strchr (cp, '/'))
|
||||
{
|
||||
(void) sprintf (cp2 = cmpfile, "%s/%s",
|
||||
hr->repos, hr->file);
|
||||
@ -1215,7 +1246,7 @@ report_hrecs ()
|
||||
|
||||
ty = *(lr->type);
|
||||
(void) strcpy (repos, lr->repos);
|
||||
if ((cp = rindex (repos, '/')) != NULL)
|
||||
if ((cp = strrchr (repos, '/')) != NULL)
|
||||
{
|
||||
if (lr->mod && !strcmp (++cp, lr->mod))
|
||||
{
|
||||
@ -1253,12 +1284,21 @@ report_hrecs ()
|
||||
continue;
|
||||
|
||||
ty = *(lr->type);
|
||||
#ifdef HAVE_RCS5
|
||||
if (!tz_local)
|
||||
{
|
||||
time_t t = lr->date + tz_seconds_east_of_GMT;
|
||||
tm = gmtime (&t);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
tm = localtime (&(lr->date));
|
||||
(void) printf ("%c %02d/%02d %02d:%02d %-*s", ty, tm->tm_mon + 1,
|
||||
tm->tm_mday, tm->tm_hour, tm->tm_min, user_len, lr->user);
|
||||
(void) printf ("%c %02d/%02d %02d:%02d %s %-*s", ty, tm->tm_mon + 1,
|
||||
tm->tm_mday, tm->tm_hour, tm->tm_min, tz_name,
|
||||
user_len, lr->user);
|
||||
|
||||
(void) sprintf (workdir, "%s%s", lr->dir, lr->end);
|
||||
if ((cp = rindex (workdir, '/')) != NULL)
|
||||
if ((cp = strrchr (workdir, '/')) != NULL)
|
||||
{
|
||||
if (lr->mod && !strcmp (++cp, lr->mod))
|
||||
{
|
||||
@ -1266,7 +1306,7 @@ report_hrecs ()
|
||||
}
|
||||
}
|
||||
(void) strcpy (repos, lr->repos);
|
||||
if ((cp = rindex (repos, '/')) != NULL)
|
||||
if ((cp = strrchr (repos, '/')) != NULL)
|
||||
{
|
||||
if (lr->mod && !strcmp (++cp, lr->mod))
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Set Lock
|
||||
*
|
||||
@ -13,30 +13,20 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)lock.c 1.42 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)lock.c 1.50 94/09/30 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
extern char *ctime ();
|
||||
|
||||
#if __STDC__
|
||||
static int readers_exist (char *repository);
|
||||
static int set_lock (char *lockdir, int will_wait, char *repository);
|
||||
static void set_lockers_name (struct stat *statp);
|
||||
static int set_writelock_proc (Node * p);
|
||||
static int unlock_proc (Node * p);
|
||||
static int write_lock (char *repository);
|
||||
static void unlock (char *repository);
|
||||
static void lock_wait ();
|
||||
#else
|
||||
static int unlock_proc ();
|
||||
static void unlock ();
|
||||
static int set_writelock_proc ();
|
||||
static int write_lock ();
|
||||
static int readers_exist ();
|
||||
static int set_lock ();
|
||||
static void set_lockers_name ();
|
||||
static void lock_wait ();
|
||||
#endif /* __STDC__ */
|
||||
static int readers_exist PROTO((char *repository));
|
||||
static int set_lock PROTO((char *lockdir, int will_wait, char *repository));
|
||||
static void set_lockers_name PROTO((struct stat *statp));
|
||||
static int set_writelock_proc PROTO((Node * p, void *closure));
|
||||
static int unlock_proc PROTO((Node * p, void *closure));
|
||||
static int write_lock PROTO((char *repository));
|
||||
static void unlock PROTO((char *repository));
|
||||
static void lock_wait PROTO((char *repository));
|
||||
|
||||
static char lockers_name[20];
|
||||
static char *repository;
|
||||
@ -65,7 +55,7 @@ Lock_Cleanup ()
|
||||
/* clean up multiple locks (if any) */
|
||||
if (locklist != (List *) NULL)
|
||||
{
|
||||
(void) walklist (locklist, unlock_proc);
|
||||
(void) walklist (locklist, unlock_proc, NULL);
|
||||
locklist = (List *) NULL;
|
||||
}
|
||||
}
|
||||
@ -74,8 +64,9 @@ Lock_Cleanup ()
|
||||
* walklist proc for removing a list of locks
|
||||
*/
|
||||
static int
|
||||
unlock_proc (p)
|
||||
unlock_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
unlock (p->key);
|
||||
return (0);
|
||||
@ -94,13 +85,15 @@ unlock (repository)
|
||||
if (readlock[0] != '\0')
|
||||
{
|
||||
(void) sprintf (tmp, "%s/%s", repository, readlock);
|
||||
(void) unlink (tmp);
|
||||
if (unlink (tmp) < 0 && errno != ENOENT)
|
||||
error (0, errno, "failed to remove lock %s", tmp);
|
||||
}
|
||||
|
||||
if (writelock[0] != '\0')
|
||||
{
|
||||
(void) sprintf (tmp, "%s/%s", repository, writelock);
|
||||
(void) unlink (tmp);
|
||||
if (unlink (tmp) < 0 && errno != ENOENT)
|
||||
error (0, errno, "failed to remove lock %s", tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -117,6 +110,13 @@ unlock (repository)
|
||||
cleanup_lckdir = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since some systems don't define this...
|
||||
*/
|
||||
#ifndef MAXHOSTNAMELEN
|
||||
#define MAXHOSTNAMELEN 256
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Create a lock file for readers
|
||||
*/
|
||||
@ -127,10 +127,18 @@ Reader_Lock (xrepository)
|
||||
int err = 0;
|
||||
FILE *fp;
|
||||
char tmp[PATH_MAX];
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
#endif
|
||||
|
||||
if (noexec)
|
||||
return (0);
|
||||
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
memset(hostname, 0, sizeof(hostname));
|
||||
gethostname(hostname, sizeof(hostname) - 1);
|
||||
#endif
|
||||
|
||||
/* we only do one directory at a time for read locks! */
|
||||
if (repository != NULL)
|
||||
{
|
||||
@ -139,7 +147,13 @@ Reader_Lock (xrepository)
|
||||
}
|
||||
|
||||
if (readlock[0] == '\0')
|
||||
(void) sprintf (readlock, "%s.%d", CVSRFL, getpid ());
|
||||
(void) sprintf (readlock,
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
"%s.%s.%d", CVSRFL, hostname,
|
||||
#else
|
||||
"%s.%d", CVSRFL,
|
||||
#endif
|
||||
getpid ());
|
||||
|
||||
/* remember what we're locking (for lock_cleanup) */
|
||||
repository = xrepository;
|
||||
@ -152,16 +166,24 @@ Reader_Lock (xrepository)
|
||||
(void) SIG_register (SIGTERM, Lock_Cleanup);
|
||||
|
||||
/* make sure we can write the repository */
|
||||
(void) sprintf (tmp, "%s/%s.%d", xrepository, CVSTFL, getpid ());
|
||||
(void) sprintf (tmp,
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
"%s/%s.%s.%d", xrepository, CVSTFL, hostname,
|
||||
#else
|
||||
"%s/%s.%d", xrepository, CVSTFL,
|
||||
#endif
|
||||
getpid());
|
||||
if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
|
||||
{
|
||||
error (0, errno, "cannot create read lock in repository `%s'",
|
||||
xrepository);
|
||||
readlock[0] = '\0';
|
||||
(void) unlink (tmp);
|
||||
if (unlink (tmp) < 0 && errno != ENOENT)
|
||||
error (0, errno, "failed to remove lock %s", tmp);
|
||||
return (1);
|
||||
}
|
||||
(void) unlink (tmp);
|
||||
if (unlink (tmp) < 0)
|
||||
error (0, errno, "failed to remove lock %s", tmp);
|
||||
|
||||
/* get the lock dir for our own */
|
||||
(void) sprintf (tmp, "%s/%s", xrepository, CVSLCK);
|
||||
@ -218,7 +240,7 @@ Writer_Lock (list)
|
||||
locklist = list; /* init for Lock_Cleanup */
|
||||
(void) strcpy (lockers_name, "unknown");
|
||||
|
||||
(void) walklist (list, set_writelock_proc);
|
||||
(void) walklist (list, set_writelock_proc, NULL);
|
||||
|
||||
switch (lock_error)
|
||||
{
|
||||
@ -247,8 +269,9 @@ Writer_Lock (list)
|
||||
* walklist proc for setting write locks
|
||||
*/
|
||||
static int
|
||||
set_writelock_proc (p)
|
||||
set_writelock_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
/* if some lock was not OK, just skip this one */
|
||||
if (lock_error != L_OK)
|
||||
@ -271,9 +294,23 @@ write_lock (repository)
|
||||
int status;
|
||||
FILE *fp;
|
||||
char tmp[PATH_MAX];
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
memset(hostname, 0, sizeof(hostname));
|
||||
gethostname(hostname, sizeof(hostname) - 1);
|
||||
#endif
|
||||
|
||||
if (writelock[0] == '\0')
|
||||
(void) sprintf (writelock, "%s.%d", CVSWFL, getpid ());
|
||||
(void) sprintf (writelock,
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
"%s.%s.%d", CVSWFL, hostname,
|
||||
#else
|
||||
"%s.%d", CVSWFL,
|
||||
#endif
|
||||
getpid());
|
||||
|
||||
/* make sure we clean up on error */
|
||||
(void) SIG_register (SIGHUP, Lock_Cleanup);
|
||||
@ -283,15 +320,23 @@ write_lock (repository)
|
||||
(void) SIG_register (SIGTERM, Lock_Cleanup);
|
||||
|
||||
/* make sure we can write the repository */
|
||||
(void) sprintf (tmp, "%s/%s.%d", repository, CVSTFL, getpid ());
|
||||
(void) sprintf (tmp,
|
||||
#ifdef HAVE_LONG_FILE_NAMES
|
||||
"%s/%s.%s.%d", repository, CVSTFL, hostname,
|
||||
#else
|
||||
"%s/%s.%d", repository, CVSTFL,
|
||||
#endif
|
||||
getpid ());
|
||||
if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
|
||||
{
|
||||
error (0, errno, "cannot create write lock in repository `%s'",
|
||||
repository);
|
||||
(void) unlink (tmp);
|
||||
if (unlink (tmp) < 0 && errno != ENOENT)
|
||||
error (0, errno, "failed to remove lock %s", tmp);
|
||||
return (L_ERROR);
|
||||
}
|
||||
(void) unlink (tmp);
|
||||
if (unlink (tmp) < 0)
|
||||
error (0, errno, "failed to remove lock %s", tmp);
|
||||
|
||||
/* make sure the lock dir is ours (not necessarily unique to us!) */
|
||||
(void) sprintf (tmp, "%s/%s", repository, CVSLCK);
|
||||
@ -318,7 +363,9 @@ write_lock (repository)
|
||||
{
|
||||
int xerrno = errno;
|
||||
|
||||
(void) unlink (tmp);
|
||||
if (unlink (tmp) < 0 && errno != ENOENT)
|
||||
error (0, errno, "failed to remove lock %s", tmp);
|
||||
|
||||
/* free the lock dir if we created it */
|
||||
if (status == L_OK)
|
||||
{
|
||||
@ -349,9 +396,8 @@ readers_exist (repository)
|
||||
{
|
||||
char line[MAXLINELEN];
|
||||
DIR *dirp;
|
||||
struct direct *dp;
|
||||
struct dirent *dp;
|
||||
struct stat sb;
|
||||
CONST char *regex_err;
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CVS_FUDGELOCKS
|
||||
@ -361,43 +407,46 @@ readers_exist (repository)
|
||||
if ((dirp = opendir (repository)) == NULL)
|
||||
error (1, 0, "cannot open directory %s", repository);
|
||||
|
||||
(void) sprintf (line, "^%s.*", CVSRFL);
|
||||
if ((regex_err = re_comp (line)) != NULL)
|
||||
error (1, 0, "%s", regex_err);
|
||||
|
||||
errno = 0;
|
||||
while ((dp = readdir (dirp)) != NULL)
|
||||
{
|
||||
(void) sprintf (line, "%s/%s", repository, dp->d_name);
|
||||
if (re_exec (dp->d_name))
|
||||
if (fnmatch (CVSRFLPAT, dp->d_name, 0) == 0)
|
||||
{
|
||||
#ifdef CVS_FUDGELOCKS
|
||||
time_t now;
|
||||
|
||||
(void) time (&now);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If the create time of the file is more than CVSLCKAGE seconds
|
||||
* ago, try to clean-up the lock file, and if successful, re-open
|
||||
* the directory and try again.
|
||||
*/
|
||||
(void) sprintf (line, "%s/%s", repository, dp->d_name);
|
||||
if (stat (line, &sb) != -1)
|
||||
{
|
||||
#ifdef CVS_FUDGELOCKS
|
||||
/*
|
||||
* If the create time of the file is more than CVSLCKAGE
|
||||
* seconds ago, try to clean-up the lock file, and if
|
||||
* successful, re-open the directory and try again.
|
||||
*/
|
||||
if (now >= (sb.st_ctime + CVSLCKAGE) && unlink (line) != -1)
|
||||
{
|
||||
(void) closedir (dirp);
|
||||
if (closedir (dirp) < 0)
|
||||
error (0, errno,
|
||||
"error closing directory %s", repository);
|
||||
goto again;
|
||||
}
|
||||
#endif
|
||||
set_lockers_name (&sb);
|
||||
}
|
||||
#else
|
||||
if (stat (line, &sb) != -1)
|
||||
set_lockers_name (&sb);
|
||||
#endif
|
||||
|
||||
ret = 1;
|
||||
break;
|
||||
}
|
||||
errno = 0;
|
||||
}
|
||||
(void) closedir (dirp);
|
||||
if (errno != 0)
|
||||
error (0, errno, "error reading directory %s", repository);
|
||||
|
||||
if (closedir (dirp) < 0)
|
||||
error (0, errno, "error closing directory %s", repository);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Print Log Information
|
||||
*
|
||||
@ -15,17 +15,13 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)log.c 1.39 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)log.c 1.44 94/09/30 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static Dtype log_dirproc (char *dir, char *repository, char *update_dir);
|
||||
static int log_fileproc (char *file, char *update_dir, char *repository,
|
||||
List * entries, List * srcfiles);
|
||||
#else
|
||||
static int log_fileproc ();
|
||||
static Dtype log_dirproc ();
|
||||
#endif /* __STDC__ */
|
||||
static Dtype log_dirproc PROTO((char *dir, char *repository, char *update_dir));
|
||||
static int log_fileproc PROTO((char *file, char *update_dir, char *repository,
|
||||
List * entries, List * srcfiles));
|
||||
|
||||
static char options[PATH_MAX];
|
||||
|
||||
@ -76,7 +72,7 @@ cvslog (argc, argv)
|
||||
err = start_recursion (log_fileproc, (int (*) ()) NULL, log_dirproc,
|
||||
(int (*) ()) NULL, argc, argv, local,
|
||||
W_LOCAL | W_REPOS | W_ATTIC, 0, 1,
|
||||
(char *) NULL, 1);
|
||||
(char *) NULL, 1, 0);
|
||||
return (err);
|
||||
}
|
||||
|
||||
@ -99,8 +95,25 @@ log_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
p = findnode (srcfiles, file);
|
||||
if (p == NULL || (rcsfile = (RCSNode *) p->data) == NULL)
|
||||
{
|
||||
/* no rcs file. What *do* we know about this file? */
|
||||
p = findnode (entries, file);
|
||||
if (p != NULL)
|
||||
{
|
||||
Entnode *e;
|
||||
|
||||
e = (Entnode *) p->data;
|
||||
if (e->version[0] == '0' || e->version[1] == '\0')
|
||||
{
|
||||
if (!really_quiet)
|
||||
error (0, 0, "%s has been added, but not committed",
|
||||
file);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (!really_quiet)
|
||||
error (0, 0, "nothing known about %s", file);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
@ -3,36 +3,34 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*/
|
||||
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)logmsg.c 1.40 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)logmsg.c 1.48 94/09/29 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static int find_type (Node * p);
|
||||
static int fmt_proc (Node * p);
|
||||
static int logfile_write (char *repository, char *filter, char *title,
|
||||
/* this is slightly dangerous, since it could conflict with other systems'
|
||||
* own prototype.
|
||||
*/
|
||||
#if 0
|
||||
/* Which is why I'll nuke this */
|
||||
extern int gethostname PROTO((char *name, int len));
|
||||
#endif
|
||||
|
||||
static int find_type PROTO((Node * p, void *closure));
|
||||
static int fmt_proc PROTO((Node * p, void *closure));
|
||||
static int logfile_write PROTO((char *repository, char *filter, char *title,
|
||||
char *message, char *revision, FILE * logfp,
|
||||
List * changes);
|
||||
static int rcsinfo_proc (char *repository, char *template);
|
||||
static int title_proc (Node * p);
|
||||
static int update_logfile_proc (char *repository, char *filter);
|
||||
static void setup_tmpfile (FILE * xfp, char *xprefix, List * changes);
|
||||
static int editinfo_proc (char *repository, char *template);
|
||||
#else
|
||||
static void setup_tmpfile ();
|
||||
static int find_type ();
|
||||
static int fmt_proc ();
|
||||
static int rcsinfo_proc ();
|
||||
static int update_logfile_proc ();
|
||||
static int title_proc ();
|
||||
static int logfile_write ();
|
||||
static int editinfo_proc ();
|
||||
#endif /* __STDC__ */
|
||||
List * changes));
|
||||
static int rcsinfo_proc PROTO((char *repository, char *template));
|
||||
static int title_proc PROTO((Node * p, void *closure));
|
||||
static int update_logfile_proc PROTO((char *repository, char *filter));
|
||||
static void setup_tmpfile PROTO((FILE * xfp, char *xprefix, List * changes));
|
||||
static int editinfo_proc PROTO((char *repository, char *template));
|
||||
|
||||
static FILE *fp;
|
||||
static char *strlist;
|
||||
@ -42,8 +40,7 @@ static Ctype type;
|
||||
/*
|
||||
* Puts a standard header on the output which is either being prepared for an
|
||||
* editor session, or being sent to a logfile program. The modified, added,
|
||||
* and removed files are included (if any) and formatted to look pretty.
|
||||
*/
|
||||
* and removed files are included (if any) and formatted to look pretty. */
|
||||
static char *prefix;
|
||||
static int col;
|
||||
static void
|
||||
@ -57,30 +54,30 @@ setup_tmpfile (xfp, xprefix, changes)
|
||||
prefix = xprefix;
|
||||
|
||||
type = T_MODIFIED;
|
||||
if (walklist (changes, find_type) != 0)
|
||||
if (walklist (changes, find_type, NULL) != 0)
|
||||
{
|
||||
(void) fprintf (fp, "%sModified Files:\n", prefix);
|
||||
(void) fprintf (fp, "%s\t", prefix);
|
||||
col = 8;
|
||||
(void) walklist (changes, fmt_proc);
|
||||
(void) walklist (changes, fmt_proc, NULL);
|
||||
(void) fprintf (fp, "\n");
|
||||
}
|
||||
type = T_ADDED;
|
||||
if (walklist (changes, find_type) != 0)
|
||||
if (walklist (changes, find_type, NULL) != 0)
|
||||
{
|
||||
(void) fprintf (fp, "%sAdded Files:\n", prefix);
|
||||
(void) fprintf (fp, "%s\t", prefix);
|
||||
col = 8;
|
||||
(void) walklist (changes, fmt_proc);
|
||||
(void) walklist (changes, fmt_proc, NULL);
|
||||
(void) fprintf (fp, "\n");
|
||||
}
|
||||
type = T_REMOVED;
|
||||
if (walklist (changes, find_type) != 0)
|
||||
if (walklist (changes, find_type, NULL) != 0)
|
||||
{
|
||||
(void) fprintf (fp, "%sRemoved Files:\n", prefix);
|
||||
(void) fprintf (fp, "%s\t", prefix);
|
||||
col = 8;
|
||||
(void) walklist (changes, fmt_proc);
|
||||
(void) walklist (changes, fmt_proc, NULL);
|
||||
(void) fprintf (fp, "\n");
|
||||
}
|
||||
}
|
||||
@ -89,8 +86,9 @@ setup_tmpfile (xfp, xprefix, changes)
|
||||
* Looks for nodes of a specified type and returns 1 if found
|
||||
*/
|
||||
static int
|
||||
find_type (p)
|
||||
find_type (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
if (p->data == (char *) type)
|
||||
return (1);
|
||||
@ -104,8 +102,9 @@ find_type (p)
|
||||
* match the one we're looking for
|
||||
*/
|
||||
static int
|
||||
fmt_proc (p)
|
||||
fmt_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
if (p->data == (char *) type)
|
||||
{
|
||||
@ -131,39 +130,38 @@ fmt_proc (p)
|
||||
*
|
||||
*/
|
||||
void
|
||||
do_editor (dir, message, repository, changes)
|
||||
do_editor (dir, messagep, repository, changes)
|
||||
char *dir;
|
||||
char *message;
|
||||
char **messagep;
|
||||
char *repository;
|
||||
List *changes;
|
||||
{
|
||||
static int reuse_log_message = 0;
|
||||
char line[MAXLINELEN], fname[L_tmpnam+1];
|
||||
char *orig_message;
|
||||
struct stat pre_stbuf, post_stbuf;
|
||||
int retcode = 0;
|
||||
char *p;
|
||||
|
||||
if (noexec || reuse_log_message)
|
||||
return;
|
||||
|
||||
orig_message = xstrdup (message); /* save it for later */
|
||||
|
||||
/* Create a temporary file */
|
||||
(void) tmpnam (fname);
|
||||
again:
|
||||
if ((fp = fopen (fname, "w+")) == NULL)
|
||||
error (1, 0, "cannot create temporary file %s", fname);
|
||||
|
||||
/* set up the file so that the first line is blank if no msg specified */
|
||||
if (*orig_message)
|
||||
if (*messagep)
|
||||
{
|
||||
(void) fprintf (fp, "%s", orig_message);
|
||||
if (orig_message[strlen (orig_message) - 1] != '\n')
|
||||
(void) fprintf (fp, "%s", *messagep);
|
||||
|
||||
if ((*messagep)[strlen (*messagep) - 1] != '\n')
|
||||
(void) fprintf (fp, "\n");
|
||||
}
|
||||
else
|
||||
(void) fprintf (fp, "\n");
|
||||
|
||||
if (repository != NULL)
|
||||
/* tack templates on if necessary */
|
||||
(void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, 1);
|
||||
|
||||
@ -176,6 +174,7 @@ do_editor (dir, message, repository, changes)
|
||||
if (dir != NULL)
|
||||
(void) fprintf (fp, "%sCommitting in %s\n%s\n", CVSEDITPREFIX,
|
||||
dir, CVSEDITPREFIX);
|
||||
if (changes != NULL)
|
||||
setup_tmpfile (fp, CVSEDITPREFIX, changes);
|
||||
(void) fprintf (fp,
|
||||
"%s----------------------------------------------------------------------\n",
|
||||
@ -189,6 +188,7 @@ do_editor (dir, message, repository, changes)
|
||||
if (editinfo_editor)
|
||||
free (editinfo_editor);
|
||||
editinfo_editor = (char *) NULL;
|
||||
if (repository != NULL)
|
||||
(void) Parse_Info (CVSROOTADM_EDITINFO, repository, editinfo_proc, 0);
|
||||
|
||||
/* run the editor */
|
||||
@ -200,29 +200,47 @@ do_editor (dir, message, repository, changes)
|
||||
editinfo_editor ? "Logfile verification failed" :
|
||||
"warning: editor session failed");
|
||||
|
||||
/* put the entire message back into the message variable */
|
||||
/* put the entire message back into the *messagep variable */
|
||||
|
||||
fp = open_file (fname, "r");
|
||||
*message = '\0';
|
||||
|
||||
if (*messagep)
|
||||
free (*messagep);
|
||||
|
||||
if (stat (fname, &post_stbuf) != 0)
|
||||
error (1, errno, "cannot find size of temp file %s", fname);
|
||||
|
||||
if (post_stbuf.st_size == 0)
|
||||
*messagep = NULL;
|
||||
else
|
||||
{
|
||||
*messagep = (char *) xmalloc (post_stbuf.st_size);
|
||||
*messagep[0] = '\0';
|
||||
}
|
||||
|
||||
/* !!! XXX FIXME: fgets is broken. This should not have any line
|
||||
length limits. */
|
||||
|
||||
if (*messagep)
|
||||
{
|
||||
p = *messagep;
|
||||
while (fgets (line, sizeof (line), fp) != NULL)
|
||||
{
|
||||
if (strncmp (line, CVSEDITPREFIX, sizeof (CVSEDITPREFIX) - 1) == 0)
|
||||
continue;
|
||||
if (((int) strlen (message) + (int) strlen (line)) >= MAXMESGLEN)
|
||||
{
|
||||
error (0, 0, "warning: log message truncated!");
|
||||
break;
|
||||
(void) strcpy (p, line);
|
||||
p += strlen (line);
|
||||
}
|
||||
(void) strcat (message, line);
|
||||
}
|
||||
(void) fclose (fp);
|
||||
if ((stat (fname, &post_stbuf) == 0 &&
|
||||
pre_stbuf.st_mtime == post_stbuf.st_mtime) ||
|
||||
(*message == '\0' || strcmp (message, "\n") == 0))
|
||||
if (pre_stbuf.st_mtime == post_stbuf.st_mtime ||
|
||||
*messagep == NULL ||
|
||||
strcmp (*messagep, "\n") == 0)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
(void) printf ("\nLog message unchanged or not specified\n");
|
||||
(void) printf ("a)bort, c)continue, e)dit, !)reuse this message unchanged for remaining dirs\n");
|
||||
(void) printf ("a)bort, c)ontinue, e)dit, !)reuse this message unchanged for remaining dirs\n");
|
||||
(void) printf ("Action: (continue) ");
|
||||
(void) fflush (stdout);
|
||||
*line = '\0';
|
||||
@ -241,7 +259,6 @@ do_editor (dir, message, repository, changes)
|
||||
(void) printf ("Unknown input\n");
|
||||
}
|
||||
}
|
||||
free (orig_message);
|
||||
(void) unlink_file (fname);
|
||||
}
|
||||
|
||||
@ -303,6 +320,10 @@ Update_Logfile (repository, xmessage, xrevision, xlogfp, xchanges)
|
||||
{
|
||||
char *srepos;
|
||||
|
||||
/* nothing to do if the list is empty */
|
||||
if (xchanges == NULL || xchanges->list->next == xchanges->list)
|
||||
return;
|
||||
|
||||
/* set up static vars for update_logfile_proc */
|
||||
message = xmessage;
|
||||
revision = xrevision;
|
||||
@ -318,13 +339,13 @@ Update_Logfile (repository, xmessage, xrevision, xlogfp, xchanges)
|
||||
strlist[0] = '\0';
|
||||
|
||||
type = T_TITLE;
|
||||
(void) walklist (changes, title_proc);
|
||||
(void) walklist (changes, title_proc, NULL);
|
||||
type = T_ADDED;
|
||||
(void) walklist (changes, title_proc);
|
||||
(void) walklist (changes, title_proc, NULL);
|
||||
type = T_MODIFIED;
|
||||
(void) walklist (changes, title_proc);
|
||||
(void) walklist (changes, title_proc, NULL);
|
||||
type = T_REMOVED;
|
||||
(void) walklist (changes, title_proc);
|
||||
(void) walklist (changes, title_proc, NULL);
|
||||
title = xmalloc (strlen (srepos) + strlen (strlist) + 1 + 2); /* for 's */
|
||||
(void) sprintf (title, "'%s%s'", srepos, strlist);
|
||||
|
||||
@ -355,8 +376,9 @@ update_logfile_proc (repository, filter)
|
||||
* concatenate each name onto strlist
|
||||
*/
|
||||
static int
|
||||
title_proc (p)
|
||||
title_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
if (p->data == (char *) type)
|
||||
{
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License
|
||||
* as specified in the README file that comes with the CVS 1.3 kit.
|
||||
* as specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Modules
|
||||
*
|
||||
@ -23,7 +23,8 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)modules.c 1.57 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)modules.c 1.62 94/09/29 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
struct sortrec
|
||||
@ -34,13 +35,8 @@ struct sortrec
|
||||
char *comment;
|
||||
};
|
||||
|
||||
#if __STDC__
|
||||
static int sort_order (CONST PTR l, CONST PTR r);
|
||||
static void save_d (char *k, int ks, char *d, int ds);
|
||||
#else
|
||||
static int sort_order ();
|
||||
static void save_d ();
|
||||
#endif /* __STDC__ */
|
||||
static int sort_order PROTO((CONST PTR l, CONST PTR r));
|
||||
static void save_d PROTO((char *k, int ks, char *d, int ds));
|
||||
|
||||
|
||||
/*
|
||||
@ -117,6 +113,13 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
if (getwd (cwd) == NULL)
|
||||
error (1, 0, "cannot get current working directory: %s", cwd);
|
||||
|
||||
/* if this is a directory to ignore, add it to that list */
|
||||
if (mname[0] == '!' && mname[1] != '\0')
|
||||
{
|
||||
ign_dir_add (mname+1);
|
||||
return(err);
|
||||
}
|
||||
|
||||
/* strip extra stuff from the module name */
|
||||
strip_path (mname);
|
||||
|
||||
@ -142,12 +145,20 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
val.dptr[val.dsize] = '\0';
|
||||
|
||||
/* If the line ends in a comment, strip it off */
|
||||
if ((cp = index (val.dptr, '#')) != NULL)
|
||||
if ((cp = strchr (val.dptr, '#')) != NULL)
|
||||
{
|
||||
do
|
||||
*cp-- = '\0';
|
||||
while (isspace (*cp));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Always strip trailing spaces */
|
||||
cp = strchr (val.dptr, '\0');
|
||||
while (cp > val.dptr && isspace(*--cp))
|
||||
*cp = '\0';
|
||||
}
|
||||
|
||||
value = val.dptr;
|
||||
mwhere = xstrdup (mname);
|
||||
goto found;
|
||||
@ -161,7 +172,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
/* check to see if mname is a directory or file */
|
||||
|
||||
(void) sprintf (file, "%s/%s", CVSroot, mname);
|
||||
if ((acp = rindex (mname, '/')) != NULL)
|
||||
if ((acp = strrchr (mname, '/')) != NULL)
|
||||
{
|
||||
*acp = '\0';
|
||||
(void) sprintf (attic_file, "%s/%s/%s/%s%s", CVSroot, mname,
|
||||
@ -183,13 +194,13 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
if (isfile (file) || isfile (attic_file))
|
||||
{
|
||||
/* if mname was a file, we have to split it into "dir file" */
|
||||
if ((cp = rindex (mname, '/')) != NULL && cp != mname)
|
||||
if ((cp = strrchr (mname, '/')) != NULL && cp != mname)
|
||||
{
|
||||
char *slashp;
|
||||
|
||||
/* put the ' ' in a copy so we don't mess up the original */
|
||||
value = strcpy (xvalue, mname);
|
||||
slashp = rindex (value, '/');
|
||||
slashp = strrchr (value, '/');
|
||||
*slashp = ' ';
|
||||
}
|
||||
else
|
||||
@ -218,7 +229,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
}
|
||||
|
||||
/* look up everything to the first / as a module */
|
||||
if (mname[0] != '/' && (cp = index (mname, '/')) != NULL)
|
||||
if (mname[0] != '/' && (cp = strchr (mname, '/')) != NULL)
|
||||
{
|
||||
/* Make the slash the new end of the string temporarily */
|
||||
*cp = '\0';
|
||||
@ -240,7 +251,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
val.dptr[val.dsize] = '\0';
|
||||
|
||||
/* If the line ends in a comment, strip it off */
|
||||
if ((cp2 = index (val.dptr, '#')) != NULL)
|
||||
if ((cp2 = strchr (val.dptr, '#')) != NULL)
|
||||
{
|
||||
do
|
||||
*cp2-- = '\0';
|
||||
@ -282,7 +293,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
value = zvalue;
|
||||
|
||||
/* search the value for the special delimiter and save for later */
|
||||
if ((cp = index (value, CVSMODULE_SPEC)) != NULL)
|
||||
if ((cp = strchr (value, CVSMODULE_SPEC)) != NULL)
|
||||
{
|
||||
*cp = '\0'; /* null out the special char */
|
||||
spec_opt = cp + 1; /* save the options for later */
|
||||
@ -326,6 +337,9 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
CVSROOTADM, CVSNULLREPOS);
|
||||
if (!isfile (nullrepos))
|
||||
(void) mkdir (nullrepos, 0777);
|
||||
if (!isdir (nullrepos))
|
||||
error (1, 0, "there is no repository %s", nullrepos);
|
||||
|
||||
Create_Admin (".", nullrepos, (char *) NULL, (char *) NULL);
|
||||
if (!noexec)
|
||||
{
|
||||
@ -363,7 +377,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
|
||||
/* parse the args */
|
||||
optind = 1;
|
||||
while ((c = gnu_getopt (modargc, modargv, CVSMODULE_OPTS)) != -1)
|
||||
while ((c = getopt (modargc, modargv, CVSMODULE_OPTS)) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -417,9 +431,16 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
int i;
|
||||
|
||||
for (i = 0; i < modargc; i++)
|
||||
{
|
||||
if (strcmp (mname, modargv[i]) == 0)
|
||||
error (0, 0,
|
||||
"module `%s' in modules file contains infinite loop",
|
||||
mname);
|
||||
else
|
||||
err += do_module (db, modargv[i], m_type, msg, callback_proc,
|
||||
where, shorten, local_specified,
|
||||
run_module_prog, extra_arg);
|
||||
}
|
||||
if (mwhere)
|
||||
free (mwhere);
|
||||
free (zvalue);
|
||||
@ -445,7 +466,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
||||
{
|
||||
char *next_opt;
|
||||
|
||||
cp = index (spec_opt, CVSMODULE_SPEC);
|
||||
cp = strchr (spec_opt, CVSMODULE_SPEC);
|
||||
if (cp != NULL)
|
||||
{
|
||||
/* save the beginning of the next arg */
|
||||
@ -648,7 +669,7 @@ save_d (k, ks, d, ds)
|
||||
s_rec->status = def_status;
|
||||
|
||||
/* Minor kluge, but general enough to maintain */
|
||||
for (cp = s_rec->rest; (cp2 = index (cp, '-')) != NULL; cp = ++cp2)
|
||||
for (cp = s_rec->rest; (cp2 = strchr (cp, '-')) != NULL; cp = ++cp2)
|
||||
{
|
||||
if (*(cp2 + 1) == 's' && *(cp2 + 2) == ' ')
|
||||
{
|
||||
@ -665,7 +686,7 @@ save_d (k, ks, d, ds)
|
||||
cp = s_rec->rest;
|
||||
|
||||
/* Find comment field, clean up on all three sides & compress blanks */
|
||||
if ((cp2 = cp = index (cp, '#')) != NULL)
|
||||
if ((cp2 = cp = strchr (cp, '#')) != NULL)
|
||||
{
|
||||
if (*--cp2 == ' ')
|
||||
*cp2 = '\0';
|
||||
@ -748,13 +769,13 @@ cat_module (status)
|
||||
|
||||
optind = 1;
|
||||
wid = 0;
|
||||
while ((c = gnu_getopt (argc, argv, CVSMODULE_OPTS)) != -1)
|
||||
while ((c = getopt (argc, argv, CVSMODULE_OPTS)) != -1)
|
||||
{
|
||||
if (!status)
|
||||
{
|
||||
if (c == 'a')
|
||||
if (c == 'a' || c == 'l')
|
||||
{
|
||||
(void) printf (" -a");
|
||||
(void) printf (" -%c", c);
|
||||
wid += 3; /* Could just set it to 3 */
|
||||
}
|
||||
else
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* No Difference
|
||||
*
|
||||
@ -17,14 +17,17 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)no_diff.c 1.35 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)no_diff.c 1.39 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
int
|
||||
No_Difference (file, vers, entries)
|
||||
No_Difference (file, vers, entries, repository, update_dir)
|
||||
char *file;
|
||||
Vers_TS *vers;
|
||||
List *entries;
|
||||
char *repository;
|
||||
char *update_dir;
|
||||
{
|
||||
Node *p;
|
||||
char tmp[L_tmpnam+1];
|
||||
@ -58,7 +61,7 @@ No_Difference (file, vers, entries)
|
||||
ts = time_stamp (file);
|
||||
Register (entries, file,
|
||||
vers->vn_user ? vers->vn_user : vers->vn_rcs, ts,
|
||||
options, vers->tag, vers->date);
|
||||
options, vers->tag, vers->date, (char *) 0);
|
||||
free (ts);
|
||||
|
||||
/* update the entdata pointer in the vers_ts structure */
|
||||
@ -72,14 +75,21 @@ No_Difference (file, vers, entries)
|
||||
}
|
||||
else
|
||||
{
|
||||
if (update_dir[0] == '\0')
|
||||
error (0, retcode == -1 ? errno : 0,
|
||||
"could not check out revision %s of %s", vers->vn_user, file);
|
||||
"could not check out revision %s of %s",
|
||||
vers->vn_user, file);
|
||||
else
|
||||
error (0, retcode == -1 ? errno : 0,
|
||||
"could not check out revision %s of %s/%s",
|
||||
vers->vn_user, update_dir, file);
|
||||
ret = -1; /* different since we couldn't tell */
|
||||
}
|
||||
|
||||
if (trace)
|
||||
(void) fprintf (stderr, "-> unlink(%s)\n", tmp);
|
||||
(void) unlink (tmp);
|
||||
if (unlink (tmp) < 0)
|
||||
error (0, errno, "could not remove %s", tmp);
|
||||
free (options);
|
||||
return (ret);
|
||||
}
|
||||
|
@ -3,13 +3,14 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*/
|
||||
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)parseinfo.c 1.16 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)parseinfo.c 1.18 94/09/23 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -87,7 +88,7 @@ Parse_Info (infofile, repository, callproc, all)
|
||||
value = cp;
|
||||
|
||||
/* strip the newline off the end of the value */
|
||||
if ((cp = rindex (value, '\n')) != NULL)
|
||||
if ((cp = strrchr (value, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
|
||||
/*
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* The routines contained in this file do all the rcs file parsing and
|
||||
* manipulation
|
||||
@ -11,36 +11,53 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)rcs.c 1.28 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)rcs.c 1.40 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static char *RCS_getbranch (RCSNode * rcs, char *tag, int force_tag_match);
|
||||
static char *RCS_getdatebranch (RCSNode * rcs, char *date, char *branch);
|
||||
static int getrcskey (FILE * fp, char **keyp, char **valp);
|
||||
static int parse_rcs_proc (Node * file);
|
||||
static int checkmagic_proc (Node *p);
|
||||
static void do_branches (List * list, char *val);
|
||||
static void do_symbols (List * list, char *val);
|
||||
static void null_delproc (Node * p);
|
||||
static void rcsnode_delproc (Node * p);
|
||||
static void rcsvers_delproc (Node * p);
|
||||
#else
|
||||
static int parse_rcs_proc ();
|
||||
static int checkmagic_proc ();
|
||||
static void rcsnode_delproc ();
|
||||
static void rcsvers_delproc ();
|
||||
static void null_delproc ();
|
||||
static int getrcskey ();
|
||||
static void do_symbols ();
|
||||
static void do_branches ();
|
||||
static char *RCS_getbranch ();
|
||||
static char *RCS_getdatebranch ();
|
||||
#endif /* __STDC__ */
|
||||
static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, char *rcsfile));
|
||||
static char *RCS_getdatebranch PROTO((RCSNode * rcs, char *date, char *branch));
|
||||
static int getrcskey PROTO((FILE * fp, char **keyp, char **valp));
|
||||
static int parse_rcs_proc PROTO((Node * file, void *closure));
|
||||
static int checkmagic_proc PROTO((Node *p, void *closure));
|
||||
static void do_branches PROTO((List * list, char *val));
|
||||
static void do_symbols PROTO((List * list, char *val));
|
||||
static void null_delproc PROTO((Node * p));
|
||||
static void rcsnode_delproc PROTO((Node * p));
|
||||
static void rcsvers_delproc PROTO((Node * p));
|
||||
|
||||
static List *rcslist;
|
||||
static char *repository;
|
||||
|
||||
/*
|
||||
* We don't want to use isspace() from the C library because:
|
||||
*
|
||||
* 1. The definition of "whitespace" in RCS files includes ASCII
|
||||
* backspace, but the C locale doesn't.
|
||||
* 2. isspace is an very expensive function call in some implementations
|
||||
* due to the addition of wide character support.
|
||||
*/
|
||||
static const char spacetab[] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, /* 0x00 - 0x0f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1f */
|
||||
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x20 - 0x2f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x30 - 0x3f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x40 - 0x4f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x50 - 0x5f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x8f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x80 - 0x8f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x90 - 0x9f */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xa0 - 0xaf */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xb0 - 0xbf */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */
|
||||
};
|
||||
|
||||
#define whitespace(c) (spacetab[c] != 0)
|
||||
|
||||
/*
|
||||
* Parse all the rcs files specified and return a list
|
||||
*/
|
||||
@ -54,7 +71,7 @@ RCS_parsefiles (files, xrepos)
|
||||
rcslist = getlist ();
|
||||
|
||||
/* walk the list parsing files */
|
||||
if (walklist (files, parse_rcs_proc) != 0)
|
||||
if (walklist (files, parse_rcs_proc, NULL) != 0)
|
||||
{
|
||||
/* free the list and return NULL on error */
|
||||
dellist (&rcslist);
|
||||
@ -69,10 +86,10 @@ RCS_parsefiles (files, xrepos)
|
||||
* Parse an rcs file into a node on the rcs list
|
||||
*/
|
||||
static int
|
||||
parse_rcs_proc (file)
|
||||
parse_rcs_proc (file, closure)
|
||||
Node *file;
|
||||
void *closure;
|
||||
{
|
||||
Node *p;
|
||||
RCSNode *rdata;
|
||||
|
||||
/* parse the rcs file into rdata */
|
||||
@ -80,17 +97,32 @@ parse_rcs_proc (file)
|
||||
|
||||
/* if we got a valid RCSNode back, put it on the list */
|
||||
if (rdata != (RCSNode *) NULL)
|
||||
{
|
||||
p = getnode ();
|
||||
p->key = xstrdup (file->key);
|
||||
p->delproc = rcsnode_delproc;
|
||||
p->type = RCSNODE;
|
||||
p->data = (char *) rdata;
|
||||
(void) addnode (rcslist, p);
|
||||
}
|
||||
RCS_addnode (file->key, rdata, rcslist);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add an RCSNode to a list of them.
|
||||
*/
|
||||
|
||||
void
|
||||
RCS_addnode (file, rcs, list)
|
||||
char *file;
|
||||
RCSNode *rcs;
|
||||
List *list;
|
||||
{
|
||||
Node *p;
|
||||
|
||||
p = getnode ();
|
||||
p->key = xstrdup (file);
|
||||
p->delproc = rcsnode_delproc;
|
||||
p->type = RCSNODE;
|
||||
p->data = (char *) rcs;
|
||||
(void) addnode (list, p);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Parse an rcsfile given a user file name and a repository
|
||||
*/
|
||||
@ -100,43 +132,46 @@ RCS_parse (file, repos)
|
||||
char *repos;
|
||||
{
|
||||
RCSNode *rcs;
|
||||
FILE *fp;
|
||||
char rcsfile[PATH_MAX];
|
||||
|
||||
(void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT);
|
||||
if (!isreadable (rcsfile))
|
||||
if ((fp = fopen (rcsfile, "r")) != NULL)
|
||||
{
|
||||
(void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC,
|
||||
file, RCSEXT);
|
||||
if (!isreadable (rcsfile))
|
||||
return (NULL);
|
||||
rcs = RCS_parsercsfile (rcsfile);
|
||||
rcs = RCS_parsercsfile_i(fp, rcsfile);
|
||||
if (rcs != NULL)
|
||||
rcs->flags |= VALID;
|
||||
|
||||
fclose (fp);
|
||||
return (rcs);
|
||||
}
|
||||
|
||||
(void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC, file, RCSEXT);
|
||||
if ((fp = fopen (rcsfile, "r")) != NULL)
|
||||
{
|
||||
rcs = RCS_parsercsfile_i(fp, rcsfile);
|
||||
if (rcs != NULL)
|
||||
{
|
||||
rcs->flags |= INATTIC;
|
||||
rcs->flags |= VALID;
|
||||
}
|
||||
return (rcs);
|
||||
}
|
||||
rcs = RCS_parsercsfile (rcsfile);
|
||||
if (rcs != NULL)
|
||||
rcs->flags |= VALID;
|
||||
|
||||
fclose (fp);
|
||||
return (rcs);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the real work of parsing an RCS file
|
||||
* Parse a specific rcsfile.
|
||||
*/
|
||||
RCSNode *
|
||||
RCS_parsercsfile (rcsfile)
|
||||
char *rcsfile;
|
||||
{
|
||||
Node *q, *r;
|
||||
RCSNode *rdata;
|
||||
RCSVers *vnode;
|
||||
int n;
|
||||
char *cp;
|
||||
char *key, *value;
|
||||
FILE *fp;
|
||||
RCSNode *rcs;
|
||||
|
||||
/* open the rcsfile */
|
||||
if ((fp = fopen (rcsfile, "r")) == NULL)
|
||||
@ -145,9 +180,30 @@ RCS_parsercsfile (rcsfile)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
rcs = RCS_parsercsfile_i (fp, rcsfile);
|
||||
|
||||
fclose (fp);
|
||||
return (rcs);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do the real work of parsing an RCS file
|
||||
*/
|
||||
static RCSNode *
|
||||
RCS_parsercsfile_i (fp, rcsfile)
|
||||
FILE *fp;
|
||||
char *rcsfile;
|
||||
{
|
||||
Node *q, *r;
|
||||
RCSNode *rdata;
|
||||
RCSVers *vnode;
|
||||
int n;
|
||||
char *cp;
|
||||
char *key, *value;
|
||||
|
||||
/* make a node */
|
||||
rdata = (RCSNode *) xmalloc (sizeof (RCSNode));
|
||||
bzero ((char *) rdata, sizeof (RCSNode));
|
||||
memset ((char *) rdata, 0, sizeof (RCSNode));
|
||||
rdata->refcount = 1;
|
||||
rdata->path = xstrdup (rcsfile);
|
||||
rdata->versions = getlist ();
|
||||
@ -161,14 +217,24 @@ RCS_parsercsfile (rcsfile)
|
||||
{
|
||||
/* get the next key/value pair */
|
||||
|
||||
/* if key is NULL here, then the file is missing some headers */
|
||||
/* if key is NULL here, then the file is missing some headers
|
||||
or we had trouble reading the file. */
|
||||
if (getrcskey (fp, &key, &value) == -1 || key == NULL)
|
||||
{
|
||||
|
||||
if (!really_quiet)
|
||||
{
|
||||
if (ferror(fp))
|
||||
{
|
||||
error (1, 0, "error reading `%s'", rcsfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, 0, "`%s' does not appear to be a valid rcs file",
|
||||
rcsfile);
|
||||
}
|
||||
}
|
||||
freercsnode (&rdata);
|
||||
(void) fclose (fp);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -184,7 +250,7 @@ RCS_parsercsfile (rcsfile)
|
||||
if ((numdots (rdata->branch) & 1) != 0)
|
||||
{
|
||||
/* turn it into a branch if it's a revision */
|
||||
cp = rindex (rdata->branch, '.');
|
||||
cp = strrchr (rdata->branch, '.');
|
||||
*cp = '\0';
|
||||
}
|
||||
continue;
|
||||
@ -193,9 +259,7 @@ RCS_parsercsfile (rcsfile)
|
||||
{
|
||||
if (value != NULL)
|
||||
{
|
||||
/* if there are tags, set up the tag list */
|
||||
rdata->symbols = getlist ();
|
||||
do_symbols (rdata->symbols, value);
|
||||
rdata->symbols_data = xstrdup(value);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -225,7 +289,7 @@ RCS_parsercsfile (rcsfile)
|
||||
|
||||
/* grab the value of the date from value */
|
||||
valp = value + strlen (RCSDATE);/* skip the "date" keyword */
|
||||
while (isspace (*valp)) /* take space off front of value */
|
||||
while (whitespace (*valp)) /* take space off front of value */
|
||||
valp++;
|
||||
(void) strcpy (date, valp);
|
||||
|
||||
@ -237,7 +301,7 @@ RCS_parsercsfile (rcsfile)
|
||||
q->delproc = rcsvers_delproc;
|
||||
r->delproc = null_delproc;
|
||||
q->data = r->data = xmalloc (sizeof (RCSVers));
|
||||
bzero (q->data, sizeof (RCSVers));
|
||||
memset (q->data, 0, sizeof (RCSVers));
|
||||
vnode = (RCSVers *) q->data;
|
||||
|
||||
/* fill in the version before we forget it */
|
||||
@ -290,7 +354,6 @@ RCS_parsercsfile (rcsfile)
|
||||
break;
|
||||
}
|
||||
|
||||
(void) fclose (fp);
|
||||
return (rdata);
|
||||
}
|
||||
|
||||
@ -325,6 +388,8 @@ freercsnode (rnodep)
|
||||
dellist (&(*rnodep)->dates);
|
||||
if ((*rnodep)->symbols != (List *) NULL)
|
||||
dellist (&(*rnodep)->symbols);
|
||||
if ((*rnodep)->symbols_data != (char *) NULL)
|
||||
free ((*rnodep)->symbols_data);
|
||||
if ((*rnodep)->head != (char *) NULL)
|
||||
free ((*rnodep)->head);
|
||||
if ((*rnodep)->branch != (char *) NULL)
|
||||
@ -405,14 +470,14 @@ getrcskey (fp, keyp, valp)
|
||||
*valp = (char *) NULL;
|
||||
return (-1);
|
||||
}
|
||||
if (!isspace (c))
|
||||
if (!whitespace (c))
|
||||
break;
|
||||
}
|
||||
|
||||
/* fill in key */
|
||||
cur = key;
|
||||
max = key + keysize;
|
||||
while (!isspace (c) && c != ';')
|
||||
while (!whitespace (c) && c != ';')
|
||||
{
|
||||
if (cur < max)
|
||||
*cur++ = c;
|
||||
@ -432,6 +497,14 @@ getrcskey (fp, keyp, valp)
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
if (cur >= max)
|
||||
{
|
||||
key = xrealloc (key, keysize + ALLOCINCR);
|
||||
cur = key + keysize;
|
||||
keysize += ALLOCINCR;
|
||||
max = key + keysize;
|
||||
}
|
||||
|
||||
*cur = '\0';
|
||||
|
||||
/* if we got "desc", we are done with the file */
|
||||
@ -538,10 +611,10 @@ getrcskey (fp, keyp, valp)
|
||||
*/
|
||||
|
||||
/* whitespace with white set means compress it out */
|
||||
if (white && isspace (c))
|
||||
if (white && whitespace (c))
|
||||
continue;
|
||||
|
||||
if (isspace (c))
|
||||
if (whitespace (c))
|
||||
{
|
||||
/* make c a space and set white */
|
||||
white = 1;
|
||||
@ -568,7 +641,16 @@ getrcskey (fp, keyp, valp)
|
||||
|
||||
/* terminate the string */
|
||||
if (cur)
|
||||
{
|
||||
if (cur >= max)
|
||||
{
|
||||
value = xrealloc (value, valsize + ALLOCINCR);
|
||||
cur = value + valsize;
|
||||
valsize += ALLOCINCR;
|
||||
max = value + valsize;
|
||||
}
|
||||
*cur = '\0';
|
||||
}
|
||||
|
||||
/* if the string is empty, make it null */
|
||||
if (value && *value != '\0')
|
||||
@ -594,7 +676,7 @@ do_symbols (list, val)
|
||||
for (;;)
|
||||
{
|
||||
/* skip leading whitespace */
|
||||
while (isspace (*cp))
|
||||
while (whitespace (*cp))
|
||||
cp++;
|
||||
|
||||
/* if we got to the end, we are done */
|
||||
@ -603,10 +685,10 @@ do_symbols (list, val)
|
||||
|
||||
/* split it up into tag and rev */
|
||||
tag = cp;
|
||||
cp = index (cp, ':');
|
||||
cp = strchr (cp, ':');
|
||||
*cp++ = '\0';
|
||||
rev = cp;
|
||||
while (!isspace (*cp) && *cp != '\0')
|
||||
while (!whitespace (*cp) && *cp != '\0')
|
||||
cp++;
|
||||
if (*cp != '\0')
|
||||
*cp++ = '\0';
|
||||
@ -634,7 +716,7 @@ do_branches (list, val)
|
||||
for (;;)
|
||||
{
|
||||
/* skip leading whitespace */
|
||||
while (isspace (*cp))
|
||||
while (whitespace (*cp))
|
||||
cp++;
|
||||
|
||||
/* if we got to the end, we are done */
|
||||
@ -643,7 +725,7 @@ do_branches (list, val)
|
||||
|
||||
/* find the end of this branch */
|
||||
branch = cp;
|
||||
while (!isspace (*cp) && *cp != '\0')
|
||||
while (!whitespace (*cp) && *cp != '\0')
|
||||
cp++;
|
||||
if (*cp != '\0')
|
||||
*cp++ = '\0';
|
||||
@ -686,7 +768,7 @@ RCS_getversion (rcs, tag, date, force_tag_match)
|
||||
if (tagrev == NULL)
|
||||
return ((char *) NULL);
|
||||
|
||||
if ((cp = rindex (tagrev, '.')) != NULL)
|
||||
if ((cp = strrchr (tagrev, '.')) != NULL)
|
||||
*cp = '\0';
|
||||
rev = RCS_getdatebranch (rcs, date, tagrev);
|
||||
free (tagrev);
|
||||
@ -733,8 +815,9 @@ RCS_gettag (rcs, tag, force_tag_match)
|
||||
/* If we got a symbolic tag, resolve it to a numeric */
|
||||
if (rcs == NULL)
|
||||
p = NULL;
|
||||
else
|
||||
p = findnode (rcs->symbols, tag);
|
||||
else {
|
||||
p = findnode (RCS_symbols(rcs), tag);
|
||||
}
|
||||
if (p != NULL)
|
||||
{
|
||||
int dots;
|
||||
@ -750,7 +833,7 @@ RCS_gettag (rcs, tag, force_tag_match)
|
||||
dots = numdots (tag);
|
||||
if (dots > 2 && (dots & 1) != 0)
|
||||
{
|
||||
branch = rindex (tag, '.');
|
||||
branch = strrchr (tag, '.');
|
||||
cp = branch++ - 1;
|
||||
while (*cp != '.')
|
||||
cp--;
|
||||
@ -874,7 +957,7 @@ RCS_magicrev (rcs, rev)
|
||||
(void) sprintf (xrev, "%s.%d.%d", rev, RCS_MAGIC_BRANCH, rev_num);
|
||||
|
||||
/* walk the symbols list to see if a magic one already exists */
|
||||
if (walklist (rcs->symbols, checkmagic_proc) != 0)
|
||||
if (walklist (RCS_symbols(rcs), checkmagic_proc, NULL) != 0)
|
||||
continue;
|
||||
|
||||
/* we found a free magic branch. Claim it as ours */
|
||||
@ -887,8 +970,9 @@ RCS_magicrev (rcs, rev)
|
||||
* Returns 0 if the symbol does not match, 1 if it does.
|
||||
*/
|
||||
static int
|
||||
checkmagic_proc (p)
|
||||
checkmagic_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
if (strcmp (check_rev, p->data) == 0)
|
||||
return (1);
|
||||
@ -897,9 +981,9 @@ checkmagic_proc (p)
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns non-zero if the specified revision number or symbolic tag
|
||||
* resolves to a "branch" within the rcs file. We do take into account
|
||||
* any magic branches as well.
|
||||
* Given a list of RCSNodes, returns non-zero if the specified
|
||||
* revision number or symbolic tag resolves to a "branch" within the
|
||||
* rcs file.
|
||||
*/
|
||||
int
|
||||
RCS_isbranch (file, rev, srcfiles)
|
||||
@ -907,7 +991,6 @@ RCS_isbranch (file, rev, srcfiles)
|
||||
char *rev;
|
||||
List *srcfiles;
|
||||
{
|
||||
int dots;
|
||||
Node *p;
|
||||
RCSNode *rcs;
|
||||
|
||||
@ -922,7 +1005,27 @@ RCS_isbranch (file, rev, srcfiles)
|
||||
|
||||
/* now, look for a match in the symbols list */
|
||||
rcs = (RCSNode *) p->data;
|
||||
p = findnode (rcs->symbols, rev);
|
||||
return (RCS_nodeisbranch (rev, rcs));
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an RCSNode, returns non-zero if the specified revision number
|
||||
* or symbolic tag resolves to a "branch" within the rcs file. We do
|
||||
* take into account any magic branches as well.
|
||||
*/
|
||||
int
|
||||
RCS_nodeisbranch (rev, rcs)
|
||||
char *rev;
|
||||
RCSNode *rcs;
|
||||
{
|
||||
int dots;
|
||||
Node *p;
|
||||
|
||||
/* numeric revisions are easy -- even number of dots is a branch */
|
||||
if (isdigit (*rev))
|
||||
return ((numdots (rev) & 1) == 0);
|
||||
|
||||
p = findnode (RCS_symbols(rcs), rev);
|
||||
if (p == NULL)
|
||||
return (0);
|
||||
dots = numdots (p->data);
|
||||
@ -933,7 +1036,7 @@ RCS_isbranch (file, rev, srcfiles)
|
||||
if (dots > 2)
|
||||
{
|
||||
char *magic;
|
||||
char *branch = rindex (p->data, '.');
|
||||
char *branch = strrchr (p->data, '.');
|
||||
char *cp = branch - 1;
|
||||
while (*cp != '.')
|
||||
cp--;
|
||||
@ -972,7 +1075,7 @@ RCS_whatbranch (file, rev, srcfiles)
|
||||
|
||||
/* now, look for a match in the symbols list */
|
||||
rcs = (RCSNode *) p->data;
|
||||
p = findnode (rcs->symbols, rev);
|
||||
p = findnode (RCS_symbols(rcs), rev);
|
||||
if (p == NULL)
|
||||
return ((char *) NULL);
|
||||
dots = numdots (p->data);
|
||||
@ -983,7 +1086,7 @@ RCS_whatbranch (file, rev, srcfiles)
|
||||
if (dots > 2)
|
||||
{
|
||||
char *magic;
|
||||
char *branch = rindex (p->data, '.');
|
||||
char *branch = strrchr (p->data, '.');
|
||||
char *cp = branch++ - 1;
|
||||
while (*cp != '.')
|
||||
cp--;
|
||||
@ -1008,7 +1111,7 @@ RCS_whatbranch (file, rev, srcfiles)
|
||||
* Get the head of the specified branch. If the branch does not exist,
|
||||
* return NULL or RCS_head depending on force_tag_match
|
||||
*/
|
||||
static char *
|
||||
char *
|
||||
RCS_getbranch (rcs, tag, force_tag_match)
|
||||
RCSNode *rcs;
|
||||
char *tag;
|
||||
@ -1025,7 +1128,7 @@ RCS_getbranch (rcs, tag, force_tag_match)
|
||||
return ((char *) NULL);
|
||||
|
||||
/* find out if the tag contains a dot, or is on the trunk */
|
||||
cp = rindex (tag, '.');
|
||||
cp = strrchr (tag, '.');
|
||||
|
||||
/* trunk processing is the special case */
|
||||
if (cp == NULL)
|
||||
@ -1237,7 +1340,7 @@ RCS_getdatebranch (rcs, date, branch)
|
||||
|
||||
/* look up the first revision on the branch */
|
||||
xrev = xstrdup (branch);
|
||||
cp = rindex (xrev, '.');
|
||||
cp = strrchr (xrev, '.');
|
||||
if (cp == NULL)
|
||||
{
|
||||
free (xrev);
|
||||
@ -1374,6 +1477,20 @@ RCS_getrevtime (rcs, rev, date, fudge)
|
||||
return (revdate);
|
||||
}
|
||||
|
||||
List *
|
||||
RCS_symbols(rcs)
|
||||
RCSNode *rcs;
|
||||
{
|
||||
if (rcs->symbols_data) {
|
||||
rcs->symbols = getlist ();
|
||||
do_symbols (rcs->symbols, rcs->symbols_data);
|
||||
free(rcs->symbols_data);
|
||||
rcs->symbols_data = NULL;
|
||||
}
|
||||
|
||||
return rcs->symbols;
|
||||
}
|
||||
|
||||
/*
|
||||
* The argument ARG is the getopt remainder of the -k option specified on the
|
||||
* command line. This function returns malloc'ed space that can be used
|
||||
@ -1439,7 +1556,7 @@ RCS_check_tag (tag)
|
||||
if (!isgraph (*cp))
|
||||
error (1, 0, "tag `%s' has non-visible graphic characters",
|
||||
tag);
|
||||
if (index (invalid, *cp))
|
||||
if (strchr (invalid, *cp))
|
||||
error (1, 0, "tag `%s' must not contain the characters `%s'",
|
||||
tag, invalid);
|
||||
}
|
||||
@ -1447,3 +1564,4 @@ RCS_check_tag (tag)
|
||||
else
|
||||
error (1, 0, "tag `%s' must start with a letter", tag);
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,11 @@
|
||||
/* @(#)rcs.h 1.14 92/03/31 */
|
||||
/* $CVSid: @(#)rcs.h 1.18 94/09/23 $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* RCS source control definitions needed by rcs.c and friends
|
||||
*/
|
||||
@ -19,6 +19,7 @@
|
||||
#define RCS_RCSMERGE "rcsmerge"
|
||||
#define RCS_MERGE_PAT "^>>>>>>> " /* runs "grep" with this pattern */
|
||||
#define RCSEXT ",v"
|
||||
#define RCSPAT "*,v"
|
||||
#define RCSHEAD "head"
|
||||
#define RCSBRANCH "branch"
|
||||
#define RCSSYMBOLS "symbols"
|
||||
@ -39,6 +40,7 @@ struct rcsnode
|
||||
char *path;
|
||||
char *head;
|
||||
char *branch;
|
||||
char *symbols_data;
|
||||
List *symbols;
|
||||
List *versions;
|
||||
List *dates;
|
||||
@ -66,37 +68,23 @@ typedef struct rcsversnode RCSVers;
|
||||
/*
|
||||
* exported interfaces
|
||||
*/
|
||||
#if __STDC__
|
||||
List *RCS_parsefiles (List * files, char *xrepos);
|
||||
RCSNode *RCS_parse (char *file, char *repos);
|
||||
RCSNode *RCS_parsercsfile (char *rcsfile);
|
||||
char *RCS_check_kflag (char *arg);
|
||||
char *RCS_getdate (RCSNode * rcs, char *date, int force_tag_match);
|
||||
char *RCS_gettag (RCSNode * rcs, char *tag, int force_tag_match);
|
||||
char *RCS_getversion (RCSNode * rcs, char *tag, char *date,
|
||||
int force_tag_match);
|
||||
char *RCS_magicrev (RCSNode *rcs, char *rev);
|
||||
int RCS_isbranch (char *file, char *rev, List *srcfiles);
|
||||
char *RCS_whatbranch (char *file, char *tag, List *srcfiles);
|
||||
char *RCS_head (RCSNode * rcs);
|
||||
int RCS_datecmp (char *date1, char *date2);
|
||||
time_t RCS_getrevtime (RCSNode * rcs, char *rev, char *date, int fudge);
|
||||
void RCS_check_tag (char *tag);
|
||||
void freercsnode (RCSNode ** rnodep);
|
||||
#else
|
||||
List *RCS_parsefiles ();
|
||||
RCSNode *RCS_parse ();
|
||||
char *RCS_head ();
|
||||
char *RCS_getversion ();
|
||||
char *RCS_magicrev ();
|
||||
int RCS_isbranch ();
|
||||
char *RCS_whatbranch ();
|
||||
char *RCS_gettag ();
|
||||
char *RCS_getdate ();
|
||||
char *RCS_check_kflag ();
|
||||
void RCS_check_tag ();
|
||||
time_t RCS_getrevtime ();
|
||||
RCSNode *RCS_parsercsfile ();
|
||||
int RCS_datecmp ();
|
||||
void freercsnode ();
|
||||
#endif /* __STDC__ */
|
||||
List *RCS_parsefiles PROTO((List * files, char *xrepos));
|
||||
RCSNode *RCS_parse PROTO((char *file, char *repos));
|
||||
RCSNode *RCS_parsercsfile PROTO((char *rcsfile));
|
||||
char *RCS_check_kflag PROTO((char *arg));
|
||||
char *RCS_getdate PROTO((RCSNode * rcs, char *date, int force_tag_match));
|
||||
char *RCS_gettag PROTO((RCSNode * rcs, char *tag, int force_tag_match));
|
||||
char *RCS_getversion PROTO((RCSNode * rcs, char *tag, char *date,
|
||||
int force_tag_match));
|
||||
char *RCS_magicrev PROTO((RCSNode *rcs, char *rev));
|
||||
int RCS_isbranch PROTO((char *file, char *rev, List *srcfiles));
|
||||
int RCS_nodeisbranch PROTO((char *rev, RCSNode *rcs));
|
||||
char *RCS_whatbranch PROTO((char *file, char *tag, List *srcfiles));
|
||||
char *RCS_head PROTO((RCSNode * rcs));
|
||||
int RCS_datecmp PROTO((char *date1, char *date2));
|
||||
time_t RCS_getrevtime PROTO((RCSNode * rcs, char *rev, char *date, int fudge));
|
||||
List *RCS_symbols PROTO((RCSNode *rcs));
|
||||
void RCS_check_tag PROTO((char *tag));
|
||||
void freercsnode PROTO((RCSNode ** rnodep));
|
||||
void RCS_addnode PROTO((char *file, RCSNode *rcs, List *list));
|
||||
char *RCS_getbranch PROTO((RCSNode * rcs, char *tag, int force_tag_match));
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* General recursion handler
|
||||
*
|
||||
@ -11,18 +11,15 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)recurse.c 1.22 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)recurse.c 1.31 94/09/30 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static int do_dir_proc (Node * p);
|
||||
static int do_file_proc (Node * p);
|
||||
static void addlist (List ** listp, char *key);
|
||||
#else
|
||||
static int do_file_proc ();
|
||||
static int do_dir_proc ();
|
||||
static void addlist ();
|
||||
#endif /* __STDC__ */
|
||||
static int do_dir_proc PROTO((Node * p, void *closure));
|
||||
static int do_file_proc PROTO((Node * p, void *closure));
|
||||
static void addlist PROTO((List ** listp, char *key));
|
||||
static int unroll_files_proc PROTO((Node *p, void *closure));
|
||||
static void addfile PROTO((List **listp, char *dir, char *file));
|
||||
|
||||
|
||||
/*
|
||||
@ -41,17 +38,35 @@ static char update_dir[PATH_MAX];
|
||||
static char *repository = NULL;
|
||||
static List *entries = NULL;
|
||||
static List *srcfiles = NULL;
|
||||
static List *filelist = NULL;
|
||||
static List *dirlist = NULL;
|
||||
|
||||
static List *filelist = NULL; /* holds list of files on which to operate */
|
||||
static List *dirlist = NULL; /* holds list of directories on which to operate */
|
||||
|
||||
struct recursion_frame {
|
||||
int (*fileproc)();
|
||||
int (*filesdoneproc) ();
|
||||
Dtype (*direntproc) ();
|
||||
int (*dirleaveproc) ();
|
||||
Dtype flags;
|
||||
int which;
|
||||
int aflag;
|
||||
int readlock;
|
||||
int dosrcs;
|
||||
};
|
||||
|
||||
/*
|
||||
* Called to start a recursive command Command line arguments are processed
|
||||
* if present, otherwise the local directory is processed.
|
||||
* Called to start a recursive command.
|
||||
*
|
||||
* Command line arguments dictate the directories and files on which
|
||||
* we operate. In the special case of no arguments, we default to
|
||||
* ".".
|
||||
*
|
||||
* The general algorythm is as follows.
|
||||
*/
|
||||
int
|
||||
start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
||||
argc, argv, local, which, aflag, readlock,
|
||||
update_preload, dosrcs)
|
||||
update_preload, dosrcs, wd_is_repos)
|
||||
int (*fileproc) ();
|
||||
int (*filesdoneproc) ();
|
||||
Dtype (*direntproc) ();
|
||||
@ -64,9 +79,12 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
||||
int readlock;
|
||||
char *update_preload;
|
||||
int dosrcs;
|
||||
int wd_is_repos; /* Set if caller has already cd'd to the repository */
|
||||
{
|
||||
int i, err = 0;
|
||||
Dtype flags;
|
||||
List *files_by_dir = NULL;
|
||||
struct recursion_frame frame;
|
||||
|
||||
if (update_preload == NULL)
|
||||
update_dir[0] = '\0';
|
||||
@ -89,7 +107,8 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
||||
if (srcfiles)
|
||||
dellist (&srcfiles);
|
||||
if (filelist)
|
||||
dellist (&filelist);
|
||||
dellist (&filelist); /* FIXME-krp: no longer correct. */
|
||||
/* FIXME-krp: clean up files_by_dir */
|
||||
if (dirlist)
|
||||
dellist (&dirlist);
|
||||
|
||||
@ -111,139 +130,128 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
||||
err += do_recursion (fileproc, filesdoneproc, direntproc,
|
||||
dirleaveproc, flags, which, aflag,
|
||||
readlock, dosrcs);
|
||||
return(err);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
|
||||
/*
|
||||
* There were arguments, so we have to handle them by hand. To do
|
||||
* that, we set up the filelist and dirlist with the arguments and
|
||||
* call do_recursion. do_recursion recognizes the fact that the
|
||||
* lists are non-null when it starts and doesn't update them
|
||||
* lists are non-null when it starts and doesn't update them.
|
||||
*
|
||||
* explicitly named directories are stored in dirlist.
|
||||
* explicitly named files are stored in filelist.
|
||||
* other possibility is named entities whicha are not currently in
|
||||
* the working directory.
|
||||
*/
|
||||
|
||||
/* look for args with /-s in them */
|
||||
for (i = 0; i < argc; i++)
|
||||
if (index (argv[i], '/') != NULL)
|
||||
break;
|
||||
{
|
||||
/* if this argument is a directory, then add it to the list of
|
||||
directories. */
|
||||
|
||||
/* if we didn't find any hard one's, do it the easy way */
|
||||
if (i == argc)
|
||||
{
|
||||
/* set up the lists */
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
if (isdir(argv[i]))
|
||||
addlist (&dirlist, argv[i]);
|
||||
else
|
||||
{
|
||||
/* otherwise, split argument into directory and component names. */
|
||||
char *dir;
|
||||
char *comp;
|
||||
char tmp[PATH_MAX];
|
||||
char *file_to_try;
|
||||
|
||||
dir = xstrdup (argv[i]);
|
||||
if ((comp = strrchr (dir, '/')) == NULL)
|
||||
{
|
||||
/* no dir component. What we have is an implied "./" */
|
||||
comp = dir;
|
||||
dir = xstrdup(".");
|
||||
}
|
||||
else
|
||||
{
|
||||
char *p = comp;
|
||||
|
||||
*p++ = '\0';
|
||||
comp = xstrdup (p);
|
||||
}
|
||||
|
||||
/* if this argument exists as a file in the current
|
||||
working directory tree, then add it to the files list. */
|
||||
|
||||
if (wd_is_repos)
|
||||
{
|
||||
/* If doing rtag, we've done a chdir to the repository. */
|
||||
sprintf (tmp, "%s%s", argv[i], RCSEXT);
|
||||
file_to_try = tmp;
|
||||
}
|
||||
else
|
||||
file_to_try = argv[i];
|
||||
|
||||
if(isfile(file_to_try))
|
||||
addfile (&files_by_dir, dir, comp);
|
||||
else if (isdir (dir))
|
||||
{
|
||||
if (isdir (CVSADM) || isdir (OCVSADM))
|
||||
{
|
||||
/* otherwise, look for it in the repository. */
|
||||
char *save_update_dir;
|
||||
char *repos;
|
||||
char tmp[PATH_MAX];
|
||||
|
||||
repos = Name_Repository ((char *) NULL, update_dir);
|
||||
(void) sprintf (tmp, "%s/%s", repos, argv[i]);
|
||||
/* save & set (aka push) update_dir */
|
||||
save_update_dir = xstrdup (update_dir);
|
||||
|
||||
if (*update_dir != '\0')
|
||||
(void) strcat (update_dir, "/");
|
||||
|
||||
(void) strcat (update_dir, dir);
|
||||
|
||||
/* look for it in the repository. */
|
||||
repos = Name_Repository (dir, update_dir);
|
||||
(void) sprintf (tmp, "%s/%s", repos, comp);
|
||||
|
||||
if (isdir(tmp))
|
||||
addlist (&dirlist, argv[i]);
|
||||
else
|
||||
addlist (&filelist, argv[i]);
|
||||
free (repos);
|
||||
addfile (&files_by_dir, dir, comp);
|
||||
|
||||
(void) sprintf (update_dir, "%s", save_update_dir);
|
||||
free (save_update_dir);
|
||||
}
|
||||
else
|
||||
addlist (&filelist, argv[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* we aren't recursive if no directories were specified */
|
||||
if (dirlist == NULL)
|
||||
local = 1;
|
||||
|
||||
/* process the lists */
|
||||
err += do_recursion (fileproc, filesdoneproc, direntproc,
|
||||
dirleaveproc, flags, which, aflag,
|
||||
readlock, dosrcs);
|
||||
}
|
||||
/* otherwise - do it the hard way */
|
||||
else
|
||||
{
|
||||
char *cp;
|
||||
char *dir = (char *) NULL;
|
||||
char *comp = (char *) NULL;
|
||||
char *oldupdate = (char *) NULL;
|
||||
char savewd[PATH_MAX];
|
||||
|
||||
if (getwd (savewd) == NULL)
|
||||
error (1, 0, "could not get working directory: %s", savewd);
|
||||
|
||||
for (i = 0; i < argc; i++)
|
||||
{
|
||||
/* split the arg into the dir and component parts */
|
||||
dir = xstrdup (argv[i]);
|
||||
if ((cp = rindex (dir, '/')) != NULL)
|
||||
{
|
||||
*cp = '\0';
|
||||
comp = xstrdup (cp + 1);
|
||||
oldupdate = xstrdup (update_dir);
|
||||
if (update_dir[0] != '\0')
|
||||
(void) strcat (update_dir, "/");
|
||||
(void) strcat (update_dir, dir);
|
||||
addfile (&files_by_dir, dir, comp);
|
||||
}
|
||||
else
|
||||
{
|
||||
comp = xstrdup (dir);
|
||||
if (dir)
|
||||
error (1, 0, "no such directory `%s'", dir);
|
||||
|
||||
free (dir);
|
||||
dir = (char *) NULL;
|
||||
}
|
||||
|
||||
/* chdir to the appropriate place if necessary */
|
||||
if (dir && chdir (dir) < 0)
|
||||
error (1, errno, "could not chdir to %s", dir);
|
||||
|
||||
/* set up the list */
|
||||
if (isdir (comp))
|
||||
addlist (&dirlist, comp);
|
||||
else
|
||||
{
|
||||
if (isdir (CVSADM) || isdir (OCVSADM))
|
||||
{
|
||||
char *repos;
|
||||
char tmp[PATH_MAX];
|
||||
|
||||
repos = Name_Repository ((char *) NULL, update_dir);
|
||||
(void) sprintf (tmp, "%s/%s", repos, comp);
|
||||
if (isdir (tmp))
|
||||
addlist (&dirlist, comp);
|
||||
else
|
||||
addlist (&filelist, comp);
|
||||
free (repos);
|
||||
}
|
||||
else
|
||||
addlist (&filelist, comp);
|
||||
}
|
||||
|
||||
/* do the recursion */
|
||||
err += do_recursion (fileproc, filesdoneproc, direntproc,
|
||||
dirleaveproc, flags, which,
|
||||
aflag, readlock, dosrcs);
|
||||
|
||||
/* chdir back and fix update_dir if necessary */
|
||||
if (dir && chdir (savewd) < 0)
|
||||
error (1, errno, "could not chdir to %s", dir);
|
||||
if (oldupdate)
|
||||
{
|
||||
(void) strcpy (update_dir, oldupdate);
|
||||
free (oldupdate);
|
||||
}
|
||||
|
||||
}
|
||||
if (dir)
|
||||
free (dir);
|
||||
if (comp)
|
||||
free (comp);
|
||||
}
|
||||
}
|
||||
|
||||
/* At this point we have looped over all named arguments and built
|
||||
a coupla lists. Now we unroll the lists, setting up and
|
||||
calling do_recursion. */
|
||||
|
||||
frame.fileproc = fileproc;
|
||||
frame.filesdoneproc = filesdoneproc;
|
||||
frame.direntproc = direntproc;
|
||||
frame.dirleaveproc = dirleaveproc;
|
||||
frame.flags = flags;
|
||||
frame.which = which;
|
||||
frame.aflag = aflag;
|
||||
frame.readlock = readlock;
|
||||
frame.dosrcs = dosrcs;
|
||||
err += walklist (files_by_dir, unroll_files_proc, (void *) &frame);
|
||||
|
||||
/* then do_recursion on the dirlist. */
|
||||
if (dirlist != NULL)
|
||||
err += do_recursion (frame.fileproc, frame.filesdoneproc,
|
||||
frame.direntproc, frame.dirleaveproc,
|
||||
frame.flags, frame.which, frame.aflag,
|
||||
frame.readlock, frame.dosrcs);
|
||||
|
||||
|
||||
return (err);
|
||||
}
|
||||
|
||||
@ -360,7 +368,7 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
|
||||
srcfiles = (List *) NULL;
|
||||
|
||||
/* process the files */
|
||||
err += walklist (filelist, do_file_proc);
|
||||
err += walklist (filelist, do_file_proc, NULL);
|
||||
|
||||
/* unlock it */
|
||||
if (readlock)
|
||||
@ -378,7 +386,7 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
|
||||
|
||||
/* process the directories (if necessary) */
|
||||
if (dirlist != NULL)
|
||||
err += walklist (dirlist, do_dir_proc);
|
||||
err += walklist (dirlist, do_dir_proc, NULL);
|
||||
#ifdef notdef
|
||||
else if (dirleaveproc != NULL)
|
||||
err += dirleaveproc(".", err, ".");
|
||||
@ -399,8 +407,9 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
|
||||
* Process each of the files in the list with the callback proc
|
||||
*/
|
||||
static int
|
||||
do_file_proc (p)
|
||||
do_file_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
if (fileproc != NULL)
|
||||
return (fileproc (p->key, update_dir, repository, entries, srcfiles));
|
||||
@ -412,8 +421,9 @@ do_file_proc (p)
|
||||
* Process each of the directories in the list (recursing as we go)
|
||||
*/
|
||||
static int
|
||||
do_dir_proc (p)
|
||||
do_dir_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
char *dir = p->key;
|
||||
char savewd[PATH_MAX];
|
||||
@ -508,7 +518,7 @@ do_dir_proc (p)
|
||||
}
|
||||
|
||||
/* put back update_dir */
|
||||
if ((cp = rindex (update_dir, '/')) != NULL)
|
||||
if ((cp = strrchr (update_dir, '/')) != NULL)
|
||||
*cp = '\0';
|
||||
else
|
||||
update_dir[0] = '\0';
|
||||
@ -517,7 +527,7 @@ do_dir_proc (p)
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a node to a list allocating the list if necessary
|
||||
* Add a node to a list allocating the list if necessary.
|
||||
*/
|
||||
static void
|
||||
addlist (listp, key)
|
||||
@ -531,5 +541,87 @@ addlist (listp, key)
|
||||
p = getnode ();
|
||||
p->type = FILES;
|
||||
p->key = xstrdup (key);
|
||||
(void) addnode (*listp, p);
|
||||
if (addnode (*listp, p) != 0)
|
||||
freenode (p);
|
||||
}
|
||||
|
||||
static void
|
||||
addfile (listp, dir, file)
|
||||
List **listp;
|
||||
char *dir;
|
||||
char *file;
|
||||
{
|
||||
Node *n;
|
||||
|
||||
/* add this dir. */
|
||||
(void) addlist (listp, dir);
|
||||
|
||||
n = findnode (*listp, dir);
|
||||
if (n == NULL)
|
||||
{
|
||||
error (1, 0, "can't find recently added dir node `%s' in start_recursion.",
|
||||
dir);
|
||||
}
|
||||
|
||||
n->type = DIRS;
|
||||
addlist ((List **) &n->data, file);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
unroll_files_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
Node *n;
|
||||
struct recursion_frame *frame = (struct recursion_frame *) closure;
|
||||
int err = 0;
|
||||
List *save_dirlist;
|
||||
char savewd[PATH_MAX];
|
||||
char *save_update_dir = NULL;
|
||||
|
||||
/* if this dir was also an explicitly named argument, then skip
|
||||
it. We'll catch it later when we do dirs. */
|
||||
n = findnode (dirlist, p->key);
|
||||
if (n != NULL)
|
||||
return (0);
|
||||
|
||||
/* otherwise, call dorecusion for this list of files. */
|
||||
filelist = (List *) p->data;
|
||||
save_dirlist = dirlist;
|
||||
dirlist = NULL;
|
||||
|
||||
if (strcmp(p->key, ".") != 0)
|
||||
{
|
||||
if (getwd (savewd) == NULL)
|
||||
error (1, 0, "could not get working directory: %s", savewd);
|
||||
|
||||
if (chdir (p->key) < 0)
|
||||
error (1, errno, "could not chdir to %s", p->key);
|
||||
|
||||
save_update_dir = xstrdup (update_dir);
|
||||
|
||||
if (*update_dir != '\0')
|
||||
(void) strcat (update_dir, "/");
|
||||
|
||||
(void) strcat (update_dir, p->key);
|
||||
}
|
||||
|
||||
err += do_recursion (frame->fileproc, frame->filesdoneproc,
|
||||
frame->direntproc, frame->dirleaveproc,
|
||||
frame->flags, frame->which, frame->aflag,
|
||||
frame->readlock, frame->dosrcs);
|
||||
|
||||
if (save_update_dir != NULL)
|
||||
{
|
||||
(void) strcpy (update_dir, save_update_dir);
|
||||
free (save_update_dir);
|
||||
|
||||
if (chdir (savewd) < 0)
|
||||
error (1, errno, "could not chdir to %s", savewd);
|
||||
}
|
||||
|
||||
dirlist = save_dirlist;
|
||||
filelist = NULL;
|
||||
return(err);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Remove a File
|
||||
*
|
||||
@ -18,26 +18,24 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)remove.c 1.34 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)remove.c 1.39 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static int remove_fileproc (char *file, char *update_dir,
|
||||
static int remove_fileproc PROTO((char *file, char *update_dir,
|
||||
char *repository, List *entries,
|
||||
List *srcfiles);
|
||||
static Dtype remove_dirproc (char *dir, char *repos, char *update_dir);
|
||||
#else
|
||||
static Dtype remove_dirproc ();
|
||||
static int remove_fileproc ();
|
||||
#endif
|
||||
List *srcfiles));
|
||||
static Dtype remove_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||
|
||||
static int force;
|
||||
static int local;
|
||||
static int removed_files;
|
||||
static int auto_removed_files;
|
||||
static int existing_files;
|
||||
|
||||
static char *remove_usage[] =
|
||||
{
|
||||
"Usage: %s %s [-lR] [files...]\n",
|
||||
"Usage: %s %s [-flR] [files...]\n",
|
||||
"\t-f\tDelete the file before removing it.\n",
|
||||
"\t-l\tProcess this directory only (not recursive).\n",
|
||||
"\t-R\tProcess directories recursively.\n",
|
||||
NULL
|
||||
@ -54,10 +52,13 @@ cvsremove (argc, argv)
|
||||
usage (remove_usage);
|
||||
|
||||
optind = 1;
|
||||
while ((c = gnu_getopt (argc, argv, "lR")) != -1)
|
||||
while ((c = getopt (argc, argv, "flR")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'f':
|
||||
force = 1;
|
||||
break;
|
||||
case 'l':
|
||||
local = 1;
|
||||
break;
|
||||
@ -76,15 +77,18 @@ cvsremove (argc, argv)
|
||||
/* start the recursion processor */
|
||||
err = start_recursion (remove_fileproc, (int (*) ()) NULL, remove_dirproc,
|
||||
(int (*) ()) NULL, argc, argv, local,
|
||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
||||
W_LOCAL, 0, 1, (char *) NULL, 1, 0);
|
||||
|
||||
if (removed_files)
|
||||
error (0, 0, "use '%s commit' to remove %s permanently", program_name,
|
||||
(removed_files == 1) ? "this file" : "these files");
|
||||
else
|
||||
if (!auto_removed_files)
|
||||
error (0, 0, "no files removed; use `%s' to remove the file first",
|
||||
RM);
|
||||
|
||||
if (existing_files)
|
||||
error (0, 0,
|
||||
((existing_files == 1) ?
|
||||
"%d file exists; use `%s' to remove it first" :
|
||||
"%d files exist; use `%s' to remove them first"),
|
||||
existing_files, RM);
|
||||
|
||||
return (err);
|
||||
}
|
||||
@ -104,24 +108,28 @@ remove_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
char fname[PATH_MAX];
|
||||
Vers_TS *vers;
|
||||
|
||||
/*
|
||||
* If unlinking the file works, good. If not, the "unremoved"
|
||||
* error will indicate problems.
|
||||
*/
|
||||
if (force)
|
||||
(void) unlink (file);
|
||||
|
||||
vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
|
||||
file, 0, 0, entries, srcfiles);
|
||||
|
||||
if (vers->ts_user != NULL)
|
||||
{
|
||||
freevers_ts (&vers);
|
||||
return (0);
|
||||
existing_files++;
|
||||
if (!quiet)
|
||||
error (0, 0, "file `%s' still in working directory", file);
|
||||
}
|
||||
|
||||
if (vers->vn_user == NULL)
|
||||
else if (vers->vn_user == NULL)
|
||||
{
|
||||
if (!quiet)
|
||||
error (0, 0, "nothing known about %s", file);
|
||||
freevers_ts (&vers);
|
||||
return (0);
|
||||
error (0, 0, "nothing known about `%s'", file);
|
||||
}
|
||||
|
||||
if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
|
||||
else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
|
||||
{
|
||||
/*
|
||||
* It's a file that has been added, but not commited yet. So,
|
||||
@ -134,13 +142,12 @@ remove_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
(void) sprintf (fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
|
||||
(void) unlink_file (fname);
|
||||
if (!quiet)
|
||||
error (0, 0, "removed `%s'.", file);
|
||||
auto_removed_files++;
|
||||
error (0, 0, "removed `%s'", file);
|
||||
}
|
||||
else if (vers->vn_user[0] == '-')
|
||||
{
|
||||
freevers_ts (&vers);
|
||||
return (0);
|
||||
if (!quiet)
|
||||
error (0, 0, "file `%s' already scheduled for removal", file);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -148,13 +155,11 @@ remove_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
(void) strcpy (fname, "-");
|
||||
(void) strcat (fname, vers->vn_user);
|
||||
Register (entries, file, fname, vers->ts_rcs, vers->options,
|
||||
vers->tag, vers->date);
|
||||
vers->tag, vers->date, vers->ts_conflict);
|
||||
if (!quiet)
|
||||
{
|
||||
error (0, 0, "scheduling %s for removal", file);
|
||||
error (0, 0, "scheduling `%s' for removal", file);
|
||||
removed_files++;
|
||||
}
|
||||
}
|
||||
|
||||
freevers_ts (&vers);
|
||||
return (0);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Name of Repository
|
||||
*
|
||||
@ -13,7 +13,8 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)repos.c 1.28 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)repos.c 1.32 94/09/23 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
char *
|
||||
@ -112,7 +113,7 @@ Name_Repository (dir, update_dir)
|
||||
error (1, errno, "cannot read %s", CVSADM_REP);
|
||||
}
|
||||
(void) fclose (fpin);
|
||||
if ((cp = rindex (repos, '\n')) != NULL)
|
||||
if ((cp = strrchr (repos, '\n')) != NULL)
|
||||
*cp = '\0'; /* strip the newline */
|
||||
|
||||
/*
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Rtag
|
||||
*
|
||||
@ -14,24 +14,18 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)rtag.c 1.57 92/04/10";
|
||||
static char rcsid[] = "$CVSid: @(#)rtag.c 1.61 94/09/30 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static Dtype rtag_dirproc (char *dir, char *repos, char *update_dir);
|
||||
static int rtag_fileproc (char *file, char *update_dir,
|
||||
static Dtype rtag_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||
static int rtag_fileproc PROTO((char *file, char *update_dir,
|
||||
char *repository, List * entries,
|
||||
List * srcfiles);
|
||||
static int rtag_proc (int *pargc, char *argv[], char *xwhere,
|
||||
List * srcfiles));
|
||||
static int rtag_proc PROTO((int *pargc, char *argv[], char *xwhere,
|
||||
char *mwhere, char *mfile, int shorten,
|
||||
int local_specified, char *mname, char *msg);
|
||||
static int rtag_delete (RCSNode *rcsfile);
|
||||
#else
|
||||
static int rtag_proc ();
|
||||
static int rtag_fileproc ();
|
||||
static Dtype rtag_dirproc ();
|
||||
static int rtag_delete ();
|
||||
#endif /* __STDC__ */
|
||||
int local_specified, char *mname, char *msg));
|
||||
static int rtag_delete PROTO((RCSNode *rcsfile));
|
||||
|
||||
static char *symtag;
|
||||
static char *numtag;
|
||||
@ -41,10 +35,11 @@ static int branch_mode; /* make an automagic "branch" tag */
|
||||
static char *date;
|
||||
static int local; /* recursive by default */
|
||||
static int force_tag_match = 1; /* force by default */
|
||||
static int force_tag_move; /* don't move existing tags by default */
|
||||
|
||||
static char *rtag_usage[] =
|
||||
{
|
||||
"Usage: %s %s [-QaflRnq] [-b] [-d] [-r tag|-D date] tag modules...\n",
|
||||
"Usage: %s %s [-QaflRnqF] [-b] [-d] [-r tag|-D date] tag modules...\n",
|
||||
"\t-Q\tReally quiet.\n",
|
||||
"\t-a\tClear tag from removed files that would not otherwise be tagged.\n",
|
||||
"\t-f\tForce a head revision match if tag/date not found.\n",
|
||||
@ -55,6 +50,7 @@ static char *rtag_usage[] =
|
||||
"\t-d\tDelete the given Tag.\n",
|
||||
"\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
|
||||
"\t-[rD]\tExisting tag or Date.\n",
|
||||
"\t-F\tMove tag if it already exists\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -73,7 +69,7 @@ rtag (argc, argv)
|
||||
usage (rtag_usage);
|
||||
|
||||
optind = 1;
|
||||
while ((c = gnu_getopt (argc, argv, "anfQqlRdbr:D:")) != -1)
|
||||
while ((c = getopt (argc, argv, "FanfQqlRdbr:D:")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -112,6 +108,9 @@ rtag (argc, argv)
|
||||
free (date);
|
||||
date = Make_Date (optarg);
|
||||
break;
|
||||
case 'F':
|
||||
force_tag_move = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage (rtag_usage);
|
||||
@ -178,7 +177,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
|
||||
char path[PATH_MAX];
|
||||
|
||||
/* if the portion of the module is a path, put the dir part on repos */
|
||||
if ((cp = rindex (mfile, '/')) != NULL)
|
||||
if ((cp = strrchr (mfile, '/')) != NULL)
|
||||
{
|
||||
*cp = '\0';
|
||||
(void) strcat (repository, "/");
|
||||
@ -224,7 +223,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
|
||||
/* start the recursion processor */
|
||||
err = start_recursion (rtag_fileproc, (int (*) ()) NULL, rtag_dirproc,
|
||||
(int (*) ()) NULL, *pargc - 1, argv + 1, local,
|
||||
which, 0, 1, where, 1);
|
||||
which, 0, 1, where, 1, 1);
|
||||
|
||||
return (err);
|
||||
}
|
||||
@ -315,25 +314,45 @@ rtag_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
* "current" head revisions of a module -- which I have found to be a
|
||||
* typical tagging operation.
|
||||
*/
|
||||
rev = branch_mode ? RCS_magicrev (rcsfile, version) : version;
|
||||
oversion = RCS_getversion (rcsfile, symtag, (char *) 0, 1);
|
||||
if (oversion != NULL)
|
||||
{
|
||||
if (strcmp (version, oversion) == 0)
|
||||
int isbranch = RCS_isbranch (file, symtag, srcfiles);
|
||||
|
||||
/*
|
||||
* if versions the same and neither old or new are branches don't
|
||||
* have to do anything
|
||||
*/
|
||||
if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch)
|
||||
{
|
||||
free (version);
|
||||
free (oversion);
|
||||
free (version);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!force_tag_move) { /* we're NOT going to move the tag */
|
||||
if (update_dir[0])
|
||||
(void) printf ("W %s/%s", update_dir, file);
|
||||
else
|
||||
(void) printf ("W %s", file);
|
||||
|
||||
(void) printf (" : %s already exists on %s %s",
|
||||
symtag, isbranch ? "branch" : "version", oversion);
|
||||
(void) printf (" : NOT MOVING tag to %s %s\n",
|
||||
branch_mode ? "branch" : "version", rev);
|
||||
free (oversion);
|
||||
free (version);
|
||||
return (0);
|
||||
}
|
||||
free (oversion);
|
||||
}
|
||||
rev = branch_mode ? RCS_magicrev (rcsfile, version) : version;
|
||||
run_setup ("%s%s -q -N%s:%s", Rcsbin, RCS, symtag, rev);
|
||||
}
|
||||
run_arg (rcsfile->path);
|
||||
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
|
||||
{
|
||||
if (!quiet)
|
||||
error (0, retcode == -1 ? errno : 0,
|
||||
error (1, retcode == -1 ? errno : 0,
|
||||
"failed to set tag `%s' to revision `%s' in `%s'",
|
||||
symtag, rev, rcsfile->path);
|
||||
free (version);
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Status Information
|
||||
*/
|
||||
@ -11,23 +11,20 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)status.c 1.48 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)status.c 1.56 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static Dtype status_dirproc (char *dir, char *repos, char *update_dir);
|
||||
static int status_fileproc (char *file, char *update_dir,
|
||||
static Dtype status_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||
static int status_fileproc PROTO((char *file, char *update_dir,
|
||||
char *repository, List * entries,
|
||||
List * srcfiles);
|
||||
static int tag_list_proc (Node * p);
|
||||
#else
|
||||
static int tag_list_proc ();
|
||||
static int status_fileproc ();
|
||||
static Dtype status_dirproc ();
|
||||
#endif /* __STDC__ */
|
||||
List * srcfiles));
|
||||
static int tag_list_proc PROTO((Node * p, void *closure));
|
||||
|
||||
static int local = 0;
|
||||
static int long_format = 0;
|
||||
static char *xfile;
|
||||
static List *xsrcfiles;
|
||||
|
||||
static char *status_usage[] =
|
||||
{
|
||||
@ -50,7 +47,7 @@ status (argc, argv)
|
||||
usage (status_usage);
|
||||
|
||||
optind = 1;
|
||||
while ((c = gnu_getopt (argc, argv, "vlR")) != -1)
|
||||
while ((c = getopt (argc, argv, "vlR")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -75,7 +72,7 @@ status (argc, argv)
|
||||
/* start the recursion processor */
|
||||
err = start_recursion (status_fileproc, (int (*) ()) NULL, status_dirproc,
|
||||
(int (*) ()) NULL, argc, argv, local,
|
||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
||||
W_LOCAL, 0, 1, (char *) NULL, 1, 0);
|
||||
|
||||
return (err);
|
||||
}
|
||||
@ -97,7 +94,8 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
Vers_TS *vers;
|
||||
|
||||
status = Classify_File (file, (char *) NULL, (char *) NULL, (char *) NULL,
|
||||
1, 0, repository, entries, srcfiles, &vers);
|
||||
1, 0, repository, entries, srcfiles, &vers,
|
||||
update_dir, 0);
|
||||
switch (status)
|
||||
{
|
||||
case T_UNKNOWN:
|
||||
@ -116,6 +114,9 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
sstat = "Locally Removed";
|
||||
break;
|
||||
case T_MODIFIED:
|
||||
if (vers->ts_conflict)
|
||||
sstat = "Unresolved Conflict";
|
||||
else
|
||||
sstat = "Locally Modified";
|
||||
break;
|
||||
case T_REMOVE_ENTRY:
|
||||
@ -136,20 +137,20 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
if (vers->ts_user == NULL)
|
||||
(void) printf ("File: no file %s\t\tStatus: %s\n\n", file, sstat);
|
||||
else
|
||||
(void) printf ("File: %-17.17s\tStatus: %s\n\n", file, sstat);
|
||||
(void) printf ("File: %-17s\tStatus: %s\n\n", file, sstat);
|
||||
|
||||
if (vers->vn_user == NULL)
|
||||
(void) printf (" Version:\t\tNo entry for %s\n", file);
|
||||
(void) printf (" Working revision:\tNo entry for %s\n", file);
|
||||
else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
|
||||
(void) printf (" Version:\t\tNew file!\n");
|
||||
(void) printf (" Working revision:\tNew file!\n");
|
||||
else
|
||||
(void) printf (" Version:\t\t%s\t%s\n", vers->vn_user,
|
||||
&vers->ts_rcs[25]);
|
||||
(void) printf (" Working revision:\t%s\t%s\n", vers->vn_user,
|
||||
vers->ts_rcs);
|
||||
|
||||
if (vers->vn_rcs == NULL)
|
||||
(void) printf (" RCS Version:\tNo revision control file\n");
|
||||
(void) printf (" Repository revision:\tNo revision control file\n");
|
||||
else
|
||||
(void) printf (" RCS Version:\t%s\t%s\n", vers->vn_rcs,
|
||||
(void) printf (" Repository revision:\t%s\t%s\n", vers->vn_rcs,
|
||||
vers->srcfile->path);
|
||||
|
||||
if (vers->entdata)
|
||||
@ -168,18 +169,25 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
if (isdigit (edata->tag[0]))
|
||||
(void) printf (" Sticky Tag:\t\t%s\n", edata->tag);
|
||||
else
|
||||
{
|
||||
int isbranch = RCS_isbranch (file, edata->tag, srcfiles);
|
||||
|
||||
(void) printf (" Sticky Tag:\t\t%s (%s: %s)\n",
|
||||
edata->tag, numdots (vers->vn_rcs) % 2 ?
|
||||
"revision" : "branch", vers->vn_rcs);
|
||||
edata->tag,
|
||||
isbranch ? "branch" : "revision",
|
||||
isbranch ?
|
||||
RCS_whatbranch(file, edata->tag, srcfiles) :
|
||||
vers->vn_rcs);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
(void) printf (" Sticky Tag:\t\t(none)\n");
|
||||
|
||||
if (edata->date)
|
||||
(void) printf (" Sticky Date:\t%s\n", edata->date);
|
||||
(void) printf (" Sticky Date:\t\t%s\n", edata->date);
|
||||
else
|
||||
(void) printf (" Sticky Date:\t(none)\n");
|
||||
(void) printf (" Sticky Date:\t\t(none)\n");
|
||||
|
||||
if (edata->options && edata->options[0])
|
||||
(void) printf (" Sticky Options:\t%s\n", edata->options);
|
||||
@ -188,9 +196,15 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
|
||||
if (long_format && vers->srcfile)
|
||||
{
|
||||
List *symbols = RCS_symbols(vers->srcfile);
|
||||
|
||||
(void) printf ("\n Existing Tags:\n");
|
||||
if (vers->srcfile->symbols)
|
||||
(void) walklist (vers->srcfile->symbols, tag_list_proc);
|
||||
if (symbols)
|
||||
{
|
||||
xfile = file;
|
||||
xsrcfiles = srcfiles;
|
||||
(void) walklist (symbols, tag_list_proc, NULL);
|
||||
}
|
||||
else
|
||||
(void) printf ("\tNo Tags Exist\n");
|
||||
}
|
||||
@ -220,11 +234,15 @@ status_dirproc (dir, repos, update_dir)
|
||||
* Print out a tag and its type
|
||||
*/
|
||||
static int
|
||||
tag_list_proc (p)
|
||||
tag_list_proc (p, closure)
|
||||
Node *p;
|
||||
void *closure;
|
||||
{
|
||||
int isbranch = RCS_isbranch (xfile, p->key, xsrcfiles);
|
||||
|
||||
(void) printf ("\t%-25.25s\t(%s: %s)\n", p->key,
|
||||
numdots (p->data) % 2 ? "revision" : "branch",
|
||||
isbranch ? "branch" : "revision",
|
||||
isbranch ? RCS_whatbranch(xfile, p->key, xsrcfiles) :
|
||||
p->data);
|
||||
return (0);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Tag
|
||||
*
|
||||
@ -14,33 +14,31 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)tag.c 1.56 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)tag.c 1.60 94/09/30 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static Dtype tag_dirproc (char *dir, char *repos, char *update_dir);
|
||||
static int tag_fileproc (char *file, char *update_dir,
|
||||
static Dtype tag_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||
static int tag_fileproc PROTO((char *file, char *update_dir,
|
||||
char *repository, List * entries,
|
||||
List * srcfiles);
|
||||
#else
|
||||
static int tag_fileproc ();
|
||||
static Dtype tag_dirproc ();
|
||||
#endif /* __STDC__ */
|
||||
List * srcfiles));
|
||||
|
||||
static char *symtag;
|
||||
static int delete; /* adding a tag by default */
|
||||
static int branch_mode; /* make an automagic "branch" tag */
|
||||
static int local; /* recursive by default */
|
||||
static int force_tag_move; /* don't force tag to move by default */
|
||||
|
||||
static char *tag_usage[] =
|
||||
{
|
||||
"Usage: %s %s [-QlRq] [-b] [-d] tag [files...]\n",
|
||||
"Usage: %s %s [-QlRqF] [-b] [-d] tag [files...]\n",
|
||||
"\t-Q\tReally quiet.\n",
|
||||
"\t-l\tLocal directory only, not recursive.\n",
|
||||
"\t-R\tProcess directories recursively.\n",
|
||||
"\t-q\tSomewhat quiet.\n",
|
||||
"\t-d\tDelete the given Tag.\n",
|
||||
"\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
|
||||
"\t-F\tMove tag if it already exists\n",
|
||||
NULL
|
||||
};
|
||||
|
||||
@ -56,7 +54,7 @@ tag (argc, argv)
|
||||
usage (tag_usage);
|
||||
|
||||
optind = 1;
|
||||
while ((c = gnu_getopt (argc, argv, "QqlRdb")) != -1)
|
||||
while ((c = getopt (argc, argv, "FQqlRdb")) != -1)
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
@ -78,6 +76,9 @@ tag (argc, argv)
|
||||
case 'b':
|
||||
branch_mode = 1;
|
||||
break;
|
||||
case 'F':
|
||||
force_tag_move = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage (tag_usage);
|
||||
@ -100,7 +101,7 @@ tag (argc, argv)
|
||||
/* start the recursion processor */
|
||||
err = start_recursion (tag_fileproc, (int (*) ()) NULL, tag_dirproc,
|
||||
(int (*) ()) NULL, argc, argv, local,
|
||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
||||
W_LOCAL, 0, 1, (char *) NULL, 1, 0);
|
||||
return (err);
|
||||
}
|
||||
|
||||
@ -210,24 +211,45 @@ tag_fileproc (file, update_dir, repository, entries, srcfiles)
|
||||
* time when simply moving the tag to the "current" head revisions of a
|
||||
* module -- which I have found to be a typical tagging operation.
|
||||
*/
|
||||
rev = branch_mode ? RCS_magicrev (vers->srcfile, version) : version;
|
||||
oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1);
|
||||
if (oversion != NULL)
|
||||
{
|
||||
if (strcmp (version, oversion) == 0)
|
||||
int isbranch = RCS_isbranch (file, symtag, srcfiles);
|
||||
|
||||
/*
|
||||
* if versions the same and neither old or new are branches don't have
|
||||
* to do anything
|
||||
*/
|
||||
if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch)
|
||||
{
|
||||
free (oversion);
|
||||
freevers_ts (&vers);
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!force_tag_move) { /* we're NOT going to move the tag */
|
||||
if (update_dir[0])
|
||||
(void) printf ("W %s/%s", update_dir, file);
|
||||
else
|
||||
(void) printf ("W %s", file);
|
||||
|
||||
(void) printf (" : %s already exists on %s %s",
|
||||
symtag, isbranch ? "branch" : "version", oversion);
|
||||
(void) printf (" : NOT MOVING tag to %s %s\n",
|
||||
branch_mode ? "branch" : "version", rev);
|
||||
free (oversion);
|
||||
freevers_ts (&vers);
|
||||
return (0);
|
||||
}
|
||||
free (oversion);
|
||||
}
|
||||
rev = branch_mode ? RCS_magicrev (vers->srcfile, version) : version;
|
||||
|
||||
run_setup ("%s%s -q -N%s:%s", Rcsbin, RCS, symtag, rev);
|
||||
run_arg (vers->srcfile->path);
|
||||
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
|
||||
{
|
||||
if (!quiet)
|
||||
error (0, retcode == -1 ? errno : 0,
|
||||
error (1, retcode == -1 ? errno : 0,
|
||||
"failed to set tag %s to revision %s in %s",
|
||||
symtag, rev, vers->srcfile->path);
|
||||
freevers_ts (&vers);
|
||||
|
@ -3,16 +3,17 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*/
|
||||
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)vers_ts.c 1.36 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)vers_ts.c 1.45 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
extern char *ctime (); /* XXX - should use gmtime/asctime */
|
||||
#define ctime(X) do not use ctime, please
|
||||
|
||||
/*
|
||||
* Fill in and return a Vers_TS structure "user" is the name of the local
|
||||
@ -39,7 +40,7 @@ Version_TS (repository, options, tag, date, user, force_tag_match,
|
||||
|
||||
/* get a new Vers_TS struct */
|
||||
vers_ts = (Vers_TS *) xmalloc (sizeof (Vers_TS));
|
||||
bzero ((char *) vers_ts, sizeof (*vers_ts));
|
||||
memset ((char *) vers_ts, 0, sizeof (*vers_ts));
|
||||
|
||||
/*
|
||||
* look up the entries file entry and fill in the version and timestamp
|
||||
@ -63,6 +64,7 @@ Version_TS (repository, options, tag, date, user, force_tag_match,
|
||||
|
||||
vers_ts->vn_user = xstrdup (entdata->version);
|
||||
vers_ts->ts_rcs = xstrdup (entdata->timestamp);
|
||||
vers_ts->ts_conflict = xstrdup (entdata->conflict);
|
||||
if (!tag)
|
||||
{
|
||||
if (!(sdtp && sdtp->aflag))
|
||||
@ -124,8 +126,10 @@ Version_TS (repository, options, tag, date, user, force_tag_match,
|
||||
else
|
||||
rcsdata = NULL;
|
||||
}
|
||||
else
|
||||
else if (repository != NULL)
|
||||
rcsdata = RCS_parse (user, repository);
|
||||
else
|
||||
rcsdata = NULL;
|
||||
|
||||
if (rcsdata != NULL)
|
||||
{
|
||||
@ -152,16 +156,19 @@ Version_TS (repository, options, tag, date, user, force_tag_match,
|
||||
{
|
||||
struct utimbuf t;
|
||||
|
||||
memset ((char *) &t, 0, sizeof (t));
|
||||
if (vers_ts->vn_rcs &&
|
||||
(t.actime = t.modtime = RCS_getrevtime (rcsdata, vers_ts->vn_rcs,
|
||||
(char *) 0, 0)) != -1)
|
||||
(t.actime = t.modtime = RCS_getrevtime (rcsdata,
|
||||
vers_ts->vn_rcs, (char *) 0, 0)) != -1)
|
||||
(void) utime (user, &t);
|
||||
}
|
||||
}
|
||||
|
||||
/* get user file time-stamp in ts_user */
|
||||
if (entries != (List *) NULL)
|
||||
{
|
||||
vers_ts->ts_user = time_stamp (user);
|
||||
}
|
||||
|
||||
return (vers_ts);
|
||||
}
|
||||
@ -184,13 +191,10 @@ time_stamp (file)
|
||||
}
|
||||
else
|
||||
{
|
||||
ts = xmalloc (51); /* 51 = 2 ctime strings + NULL */
|
||||
cp = ctime (&sb.st_ctime); /* copy in the create time */
|
||||
cp[24] = ' ';
|
||||
ts = xmalloc (25);
|
||||
cp = asctime (gmtime (&sb.st_mtime)); /* copy in the modify time */
|
||||
cp[24] = 0;
|
||||
(void) strcpy (ts, cp);
|
||||
cp = ctime (&sb.st_mtime); /* copy in the modify time */
|
||||
cp[24] = '\0';
|
||||
(void) strcat (ts, cp);
|
||||
}
|
||||
|
||||
return (ts);
|
||||
@ -219,6 +223,8 @@ freevers_ts (versp)
|
||||
free ((*versp)->tag);
|
||||
if ((*versp)->date)
|
||||
free ((*versp)->date);
|
||||
if ((*versp)->ts_conflict)
|
||||
free ((*versp)->ts_conflict);
|
||||
free ((char *) *versp);
|
||||
*versp = (Vers_TS *) NULL;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# commitinfo,v 1.2 1992/03/31 04:19:47 berliner Exp
|
||||
# $Id: commitinfo,v 1.2 1992/03/31 04:19:47 berliner Exp $
|
||||
#
|
||||
# The "commitinfo" file is used to control pre-commit checks.
|
||||
# The filter on the right is invoked with the repository and a list
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# editinfo,v 1.1 1992/03/21 06:49:39 berliner Exp
|
||||
# $Id: editinfo,v 1.1 1992/03/21 06:49:39 berliner Exp $
|
||||
#
|
||||
# The "editinfo" file is used to allow verification of logging
|
||||
# information. It works best when a template (as specified in the
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# @(#)loginfo 1.5 92/03/31
|
||||
# $CVSid: @(#)loginfo 1.5 92/03/31 $
|
||||
#
|
||||
# The "loginfo" file is used to control where "cvs commit" log information
|
||||
# is sent. The first entry on a line is a regular expression which is tested
|
||||
|
@ -1,6 +1,6 @@
|
||||
#
|
||||
# CVS Modules file for Prisma sources
|
||||
# @(#)modules 1.5 92/03/31
|
||||
# $CVSid: @(#)modules 1.5 92/03/31 $
|
||||
#
|
||||
# Three different line formats are valid:
|
||||
# key -a aliases...
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# rcsinfo,v 1.3 1992/04/10 18:59:14 berliner Exp
|
||||
# $Id: rcsinfo,v 1.3 1992/04/10 18:59:14 berliner Exp $
|
||||
#
|
||||
# The "rcsinfo" file is used to control templates with which the editor
|
||||
# is invoked on commit and import.
|
||||
|
@ -30,7 +30,7 @@
|
||||
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
|
||||
#endif
|
||||
|
||||
#ifdef emacs
|
||||
#if defined(emacs) || defined(HAVE_CONFIG_H)
|
||||
#include "config.h"
|
||||
#ifdef static
|
||||
/* actually, only want this if static is defined as ""
|
||||
@ -43,7 +43,7 @@ lose
|
||||
-- must know STACK_DIRECTION at compile-time
|
||||
#endif /* STACK_DIRECTION undefined */
|
||||
#endif /* static */
|
||||
#endif /* emacs */
|
||||
#endif /* emacs || HAVE_CONFIG_H*/
|
||||
|
||||
#if __STDC__
|
||||
typedef void *pointer; /* generic pointer type */
|
||||
|
@ -17,6 +17,10 @@
|
||||
|
||||
/* Written by David MacKenzie <djm@ai.mit.edu> */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef STDC_HEADERS
|
||||
#include <string.h>
|
||||
|
@ -4,6 +4,10 @@
|
||||
last edit: 11-Feb-1987 D A Gwyn
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
@ -19,9 +19,13 @@
|
||||
/* Brian Berliner added support for CVS */
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)error.c 1.9 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)error.c 1.13 94/09/30 $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* turn on CVS support by default, since this is the CVS distribution */
|
||||
@ -35,7 +39,7 @@ void Lock_Cleanup();
|
||||
#endif /* __STDC__ */
|
||||
#endif /* CVS_SUPPORT */
|
||||
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
@ -47,7 +51,7 @@ void Lock_Cleanup();
|
||||
|
||||
#else
|
||||
|
||||
#ifndef DOPRNT_MISSING
|
||||
#ifdef HAVE_DOPRNT
|
||||
#define va_alist args
|
||||
#define va_dcl int args;
|
||||
#else
|
||||
@ -57,7 +61,7 @@ void Lock_Cleanup();
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#if STDC_HEADERS
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#else
|
||||
@ -68,19 +72,7 @@ void exit ();
|
||||
#endif /* __STDC__ */
|
||||
#endif
|
||||
|
||||
#ifdef STRERROR_MISSING
|
||||
static char *
|
||||
strerror (errnum)
|
||||
int errnum;
|
||||
{
|
||||
extern char *sys_errlist[];
|
||||
extern int sys_nerr;
|
||||
|
||||
if (errnum > 0 && errnum < sys_nerr)
|
||||
return sys_errlist[errnum];
|
||||
return "Unknown system error";
|
||||
}
|
||||
#endif /* STRERROR_MISSING */
|
||||
extern char *strerror ();
|
||||
|
||||
/* Print the program name and error message MESSAGE, which is a printf-style
|
||||
format string with optional args.
|
||||
@ -88,7 +80,7 @@ strerror (errnum)
|
||||
Exit with status STATUS if it is nonzero. */
|
||||
/* VARARGS */
|
||||
void
|
||||
#if !defined (VPRINTF_MISSING) && __STDC__
|
||||
#if defined (HAVE_VPRINTF) && __STDC__
|
||||
error (int status, int errnum, char *message, ...)
|
||||
#else
|
||||
error (status, errnum, message, va_alist)
|
||||
@ -102,7 +94,7 @@ error (status, errnum, message, va_alist)
|
||||
#ifdef CVS_SUPPORT
|
||||
extern char *command_name;
|
||||
#endif
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
va_list args;
|
||||
#endif
|
||||
|
||||
@ -117,12 +109,12 @@ error (status, errnum, message, va_alist)
|
||||
#else
|
||||
fprintf (stderr, "%s: ", program_name);
|
||||
#endif
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
VA_START (args, message);
|
||||
vfprintf (stderr, message, args);
|
||||
va_end (args);
|
||||
#else
|
||||
#ifndef DOPRNT_MISSING
|
||||
#ifdef HAVE_DOPRNT
|
||||
_doprnt (message, &args, stderr);
|
||||
#else
|
||||
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
@ -149,7 +141,7 @@ error (status, errnum, message, va_alist)
|
||||
Exit with status STATUS if it is nonzero. */
|
||||
/* VARARGS */
|
||||
void
|
||||
#if !defined (VPRINTF_MISSING) && __STDC__
|
||||
#if defined (HAVE_VPRINTF) && __STDC__
|
||||
fperror (FILE *fp, int status, int errnum, char *message, ...)
|
||||
#else
|
||||
fperror (fp, status, errnum, message, va_alist)
|
||||
@ -161,17 +153,17 @@ fperror (fp, status, errnum, message, va_alist)
|
||||
#endif
|
||||
{
|
||||
extern char *program_name;
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
va_list args;
|
||||
#endif
|
||||
|
||||
fprintf (fp, "%s: ", program_name);
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
VA_START (args, message);
|
||||
vfprintf (fp, message, args);
|
||||
va_end (args);
|
||||
#else
|
||||
#ifndef DOPRNT_MISSING
|
||||
#ifdef HAVE_DOPRNT
|
||||
_doprnt (message, &args, fp);
|
||||
#else
|
||||
fprintf (fp, message, a1, a2, a3, a4, a5, a6, a7, a8);
|
||||
|
@ -18,6 +18,10 @@ Cambridge, MA 02139, USA. */
|
||||
|
||||
/* Modified slightly by Brian Berliner <berliner@sun.com> for CVS use */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
/* IGNORE(@ */
|
||||
/* #include <ansidecl.h> */
|
||||
/* @) */
|
||||
@ -28,10 +32,6 @@ Cambridge, MA 02139, USA. */
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#if !__STDC__
|
||||
#define const
|
||||
#endif
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, nonzero if not. */
|
||||
int
|
||||
|
@ -1,6 +1,10 @@
|
||||
/* ftruncate emulations that work on some System V's.
|
||||
This file is in the public domain. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
|
@ -1,29 +1,98 @@
|
||||
%{
|
||||
/* 1.8
|
||||
** @(#)getdate.y 1.8 92/03/03
|
||||
**
|
||||
/*
|
||||
** Originally written by Steven M. Bellovin <smb@research.att.com> while
|
||||
** at the University of North Carolina at Chapel Hill. Later tweaked by
|
||||
** a couple of people on Usenet. Completely overhauled by Rich $alz
|
||||
** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
|
||||
** send any email to Rich.
|
||||
**
|
||||
** This grammar has eight shift/reduce conflicts.
|
||||
** This grammar has 10 shift/reduce conflicts.
|
||||
**
|
||||
** This code is in the public domain and has no copyright.
|
||||
*/
|
||||
/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
|
||||
/* SUPPRESS 288 on yyerrlab *//* Label unused */
|
||||
|
||||
#include "system.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#if defined (emacs) || defined (CONFIG_BROKETS)
|
||||
#include <config.h>
|
||||
#else
|
||||
#include "config.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Since the code of getdate.y is not included in the Emacs executable
|
||||
itself, there is no need to #define static in this file. Even if
|
||||
the code were included in the Emacs executable, it probably
|
||||
wouldn't do any harm to #undef it here; this will only cause
|
||||
problems if we try to write to a static variable, which I don't
|
||||
think this code needs to do. */
|
||||
#ifdef emacs
|
||||
#undef static
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
|
||||
#ifdef __GNUC__
|
||||
#undef alloca /* might get redefined below */
|
||||
/* The code at the top of get_date which figures out the offset of the
|
||||
current time zone checks various CPP symbols to see if special
|
||||
tricks are need, but defaults to using the gettimeofday system call.
|
||||
Include <sys/time.h> if that will be used. */
|
||||
|
||||
#if defined(vms)
|
||||
|
||||
#include <types.h>
|
||||
#include <time.h>
|
||||
|
||||
#else
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef TIME_WITH_SYS_TIME
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
#else
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <time.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef timezone
|
||||
#undef timezone /* needed for sgi */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SYS_TIMEB_H)
|
||||
#include <sys/timeb.h>
|
||||
#else
|
||||
/*
|
||||
** We use the obsolete `struct timeb' as part of our interface!
|
||||
** Since the system doesn't have it, we define it here;
|
||||
** our callers must do likewise.
|
||||
*/
|
||||
struct timeb {
|
||||
time_t time; /* Seconds since the epoch */
|
||||
unsigned short millitm; /* Field not used */
|
||||
short timezone; /* Minutes west of GMT */
|
||||
short dstflag; /* Field not used */
|
||||
};
|
||||
#endif /* defined(HAVE_SYS_TIMEB_H) */
|
||||
|
||||
#endif /* defined(vms) */
|
||||
|
||||
#if defined (STDC_HEADERS) || defined (USG)
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
/* Some old versions of bison generate parsers that use bcopy.
|
||||
That loses on systems that don't provide the function, so we have
|
||||
to redefine it here. */
|
||||
#if !defined (HAVE_BCOPY) && defined (HAVE_MEMCPY) && !defined (bcopy)
|
||||
#define bcopy(from, to, len) memcpy ((to), (from), (len))
|
||||
#endif
|
||||
|
||||
extern struct tm *gmtime();
|
||||
extern struct tm *localtime();
|
||||
|
||||
#define yyparse getdate_yyparse
|
||||
@ -31,9 +100,11 @@ extern struct tm *localtime();
|
||||
#define yyerror getdate_yyerror
|
||||
|
||||
#if !defined(lint) && !defined(SABER)
|
||||
static char RCS[] = "@(#)getdate.y 1.8 92/03/03";
|
||||
static char RCS[] = "$CVSid: @(#)getdate.y 1.11 94/09/21 $";
|
||||
#endif /* !defined(lint) && !defined(SABER) */
|
||||
|
||||
static int yylex ();
|
||||
static int yyerror ();
|
||||
|
||||
#define EPOCH 1970
|
||||
#define HOUR(x) ((time_t)(x) * 60)
|
||||
@ -202,6 +273,18 @@ date : tUNUMBER '/' tUNUMBER {
|
||||
yyDay = $3;
|
||||
yyYear = $5;
|
||||
}
|
||||
| tUNUMBER tSNUMBER tSNUMBER {
|
||||
/* ISO 8601 format. yyyy-mm-dd. */
|
||||
yyYear = $1;
|
||||
yyMonth = -$2;
|
||||
yyDay = -$3;
|
||||
}
|
||||
| tUNUMBER tMONTH tSNUMBER {
|
||||
/* e.g. 17-JUN-1992. */
|
||||
yyDay = $1;
|
||||
yyMonth = $2;
|
||||
yyYear = -$3;
|
||||
}
|
||||
| tMONTH tUNUMBER {
|
||||
yyMonth = $1;
|
||||
yyDay = $2;
|
||||
@ -263,14 +346,12 @@ number : tUNUMBER {
|
||||
yyYear = $1;
|
||||
else {
|
||||
if($1>10000) {
|
||||
time_t date_part;
|
||||
|
||||
date_part= $1/10000;
|
||||
yyHaveDate++;
|
||||
yyDay= (date_part)%100;
|
||||
yyMonth= (date_part/100)%100;
|
||||
yyYear = date_part/10000;
|
||||
yyDay= ($1)%100;
|
||||
yyMonth= ($1/100)%100;
|
||||
yyYear = $1/10000;
|
||||
}
|
||||
else {
|
||||
yyHaveTime++;
|
||||
if ($1 < 100) {
|
||||
yyHour = $1;
|
||||
@ -284,6 +365,7 @@ number : tUNUMBER {
|
||||
yyMeridian = MER24;
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
o_merid : /* NULL */ {
|
||||
@ -297,7 +379,7 @@ o_merid : /* NULL */ {
|
||||
%%
|
||||
|
||||
/* Month and day table. */
|
||||
static TABLE MonthDayTable[] = {
|
||||
static TABLE const MonthDayTable[] = {
|
||||
{ "january", tMONTH, 1 },
|
||||
{ "february", tMONTH, 2 },
|
||||
{ "march", tMONTH, 3 },
|
||||
@ -326,7 +408,7 @@ static TABLE MonthDayTable[] = {
|
||||
};
|
||||
|
||||
/* Time units table. */
|
||||
static TABLE UnitsTable[] = {
|
||||
static TABLE const UnitsTable[] = {
|
||||
{ "year", tMONTH_UNIT, 12 },
|
||||
{ "month", tMONTH_UNIT, 1 },
|
||||
{ "fortnight", tMINUTE_UNIT, 14 * 24 * 60 },
|
||||
@ -341,7 +423,7 @@ static TABLE UnitsTable[] = {
|
||||
};
|
||||
|
||||
/* Assorted relative-time words. */
|
||||
static TABLE OtherTable[] = {
|
||||
static TABLE const OtherTable[] = {
|
||||
{ "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
|
||||
{ "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
|
||||
{ "today", tMINUTE_UNIT, 0 },
|
||||
@ -367,7 +449,7 @@ static TABLE OtherTable[] = {
|
||||
|
||||
/* The timezone table. */
|
||||
/* Some of these are commented out because a time_t can't store a float. */
|
||||
static TABLE TimezoneTable[] = {
|
||||
static TABLE const TimezoneTable[] = {
|
||||
{ "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
|
||||
{ "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
|
||||
{ "utc", tZONE, HOUR( 0) },
|
||||
@ -451,7 +533,7 @@ static TABLE TimezoneTable[] = {
|
||||
};
|
||||
|
||||
/* Military timezone table. */
|
||||
static TABLE MilitaryTable[] = {
|
||||
static TABLE const MilitaryTable[] = {
|
||||
{ "a", tZONE, HOUR( 1) },
|
||||
{ "b", tZONE, HOUR( 2) },
|
||||
{ "c", tZONE, HOUR( 3) },
|
||||
@ -484,7 +566,7 @@ static TABLE MilitaryTable[] = {
|
||||
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
static int
|
||||
yyerror(s)
|
||||
char *s;
|
||||
{
|
||||
@ -514,6 +596,8 @@ ToSeconds(Hours, Minutes, Seconds, Meridian)
|
||||
if (Hours < 1 || Hours > 12)
|
||||
return -1;
|
||||
return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
@ -624,7 +708,7 @@ LookupWord(buff)
|
||||
{
|
||||
register char *p;
|
||||
register char *q;
|
||||
register TABLE *tp;
|
||||
register const TABLE *tp;
|
||||
int i;
|
||||
int abbrev;
|
||||
|
||||
@ -725,7 +809,7 @@ LookupWord(buff)
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
static int
|
||||
yylex()
|
||||
{
|
||||
register char c;
|
||||
@ -777,13 +861,36 @@ yylex()
|
||||
}
|
||||
}
|
||||
|
||||
#define TM_YEAR_ORIGIN 1900
|
||||
|
||||
/* Yield A - B, measured in seconds. */
|
||||
static long
|
||||
difftm (a, b)
|
||||
struct tm *a, *b;
|
||||
{
|
||||
int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
|
||||
int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
|
||||
int days = (
|
||||
/* difference in day of year */
|
||||
a->tm_yday - b->tm_yday
|
||||
/* + intervening leap days */
|
||||
+ ((ay >> 2) - (by >> 2))
|
||||
- (ay/100 - by/100)
|
||||
+ ((ay/100 >> 2) - (by/100 >> 2))
|
||||
/* + difference in years * 365 */
|
||||
+ (long)(ay-by) * 365
|
||||
);
|
||||
return (60*(60*(24*days + (a->tm_hour - b->tm_hour))
|
||||
+ (a->tm_min - b->tm_min))
|
||||
+ (a->tm_sec - b->tm_sec));
|
||||
}
|
||||
|
||||
time_t
|
||||
get_date(p, now)
|
||||
char *p;
|
||||
struct timeb *now;
|
||||
{
|
||||
struct tm *tm;
|
||||
struct tm *tm, gmt;
|
||||
struct timeb ftz;
|
||||
time_t Start;
|
||||
time_t tod;
|
||||
@ -791,34 +898,25 @@ get_date(p, now)
|
||||
yyInput = p;
|
||||
if (now == NULL) {
|
||||
now = &ftz;
|
||||
#if defined(FTIME_MISSING)
|
||||
(void)time(&ftz.time);
|
||||
/* Set the timezone global. */
|
||||
tzset();
|
||||
#if defined(HAVE_TIMEZONE)
|
||||
tm = localtime(&ftz.time);
|
||||
ftz.timezone = tm->tm_gmtoff / 60;
|
||||
#else
|
||||
#if defined(timezone)
|
||||
ftz.tzone = (int) timezone / 60;
|
||||
#else
|
||||
ftz.timezone = (int) timezone / 60;
|
||||
#endif /* defined(timezone) */
|
||||
#endif /* defined(HAVE_TIMEZONE) */
|
||||
#else
|
||||
(void)ftime(&ftz);
|
||||
#endif /* defined(FTIME_MISSING) */
|
||||
|
||||
if (! (tm = gmtime (&ftz.time)))
|
||||
return -1;
|
||||
gmt = *tm; /* Make a copy, in case localtime modifies *tm. */
|
||||
|
||||
if (! (tm = localtime (&ftz.time)))
|
||||
return -1;
|
||||
|
||||
ftz.timezone = difftm (&gmt, tm) / 60;
|
||||
if(tm->tm_isdst)
|
||||
ftz.timezone += 60;
|
||||
}
|
||||
|
||||
tm = localtime(&now->time);
|
||||
yyYear = tm->tm_year;
|
||||
yyMonth = tm->tm_mon + 1;
|
||||
yyDay = tm->tm_mday;
|
||||
#if defined(timezone)
|
||||
yyTimezone = now->tzone;
|
||||
#else
|
||||
yyTimezone = now->timezone;
|
||||
#endif /* defined(timezone) */
|
||||
yyDSTmode = DSTmaybe;
|
||||
yyHour = 0;
|
||||
yyMinutes = 0;
|
||||
@ -865,6 +963,7 @@ get_date(p, now)
|
||||
#if defined(TEST)
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
main(ac, av)
|
||||
int ac;
|
||||
char *av[];
|
||||
|
@ -1,10 +1,10 @@
|
||||
/* declarations for getopt
|
||||
Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
|
||||
/* Declarations for getopt.
|
||||
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||
|
||||
This program 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 2, or (at your option)
|
||||
any later version.
|
||||
This program 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 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -13,9 +13,16 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* @(#)getopt.h 1.6 92/03/31 */
|
||||
/* $CVSid: @(#)getopt.h 1.7 94/09/21 $ */
|
||||
|
||||
#ifndef _GETOPT_H
|
||||
#define _GETOPT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* For communication from `getopt' to the caller.
|
||||
When `getopt' finds an option that takes an argument,
|
||||
@ -44,16 +51,21 @@ extern int optind;
|
||||
|
||||
extern int opterr;
|
||||
|
||||
/* Set to an option character which was unrecognized. */
|
||||
|
||||
extern int optopt;
|
||||
|
||||
/* Describe the long-named options requested by the application.
|
||||
_GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an
|
||||
element containing a name which is zero.
|
||||
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||
of `struct option' terminated by an element containing a name which is
|
||||
zero.
|
||||
|
||||
The field `has_arg' is:
|
||||
0 if the option does not take an argument,
|
||||
1 if the option requires an argument,
|
||||
2 if the option takes an optional argument.
|
||||
no_argument (or 0) if the option does not take an argument,
|
||||
required_argument (or 1) if the option requires an argument,
|
||||
optional_argument (or 2) if the option takes an optional argument.
|
||||
|
||||
If the field `flag' is nonzero, it points to a variable that is set
|
||||
If the field `flag' is not NULL, it points to a variable that is set
|
||||
to the value given in the field `val' when the option is found, but
|
||||
left unchanged if the option is not found.
|
||||
|
||||
@ -66,37 +78,54 @@ extern int opterr;
|
||||
|
||||
struct option
|
||||
{
|
||||
#if __STDC__
|
||||
const char *name;
|
||||
#else
|
||||
char *name;
|
||||
#endif
|
||||
/* has_arg can't be an enum because some compilers complain about
|
||||
type mismatches in all the code that assumes it is an int. */
|
||||
int has_arg;
|
||||
int *flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
#if __STDC__
|
||||
extern const struct option *_getopt_long_options;
|
||||
#else
|
||||
extern struct option *_getopt_long_options;
|
||||
#endif
|
||||
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||
|
||||
/* If nonzero, '-' can introduce long-named options.
|
||||
Set by getopt_long_only. */
|
||||
|
||||
extern int _getopt_long_only;
|
||||
|
||||
/* The index in GETOPT_LONG_OPTIONS of the long-named option found.
|
||||
Only valid when a long-named option has been found by the most
|
||||
recent call to `getopt'. */
|
||||
|
||||
extern int option_index;
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
|
||||
#if __STDC__
|
||||
int gnu_getopt (int argc, char **argv, const char *shortopts);
|
||||
int gnu_getopt_long (int argc, char **argv, const char *shortopts,
|
||||
#if defined(__GNU_LIBRARY__)
|
||||
/* Many other libraries have conflicting prototypes for getopt, with
|
||||
differences in the consts, in stdlib.h. To avoid compilation
|
||||
errors, only prototype getopt for the GNU C library. */
|
||||
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||
#else /* not __GNU_LIBRARY__ */
|
||||
extern int getopt ();
|
||||
#endif /* not __GNU_LIBRARY__ */
|
||||
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
int gnu_getopt_long_only (int argc, char **argv, const char *shortopts,
|
||||
extern int getopt_long_only (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind);
|
||||
#else
|
||||
int gnu_getopt ();
|
||||
int gnu_getopt_long ();
|
||||
int gnu_getopt_long_only ();
|
||||
|
||||
/* Internal only. Users should not call this directly. */
|
||||
extern int _getopt_internal (int argc, char *const *argv,
|
||||
const char *shortopts,
|
||||
const struct option *longopts, int *longind,
|
||||
int long_only);
|
||||
#else /* not __STDC__ */
|
||||
extern int getopt ();
|
||||
extern int getopt_long ();
|
||||
extern int getopt_long_only ();
|
||||
|
||||
extern int _getopt_internal ();
|
||||
#endif /* not __STDC__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _GETOPT_H */
|
||||
|
@ -1,10 +1,11 @@
|
||||
/* Getopt for GNU.
|
||||
Copyright (C) 1987-1992 Free Software Foundation, Inc.
|
||||
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||
Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This program 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 2, or (at your option)
|
||||
any later version.
|
||||
This program 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 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
@ -13,67 +14,84 @@
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include "getopt.h"
|
||||
|
||||
#if !__STDC__
|
||||
#define const
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#if defined (emacs) || defined (CONFIG_BROKETS)
|
||||
/* We use <config.h> instead of "config.h" so that a compilation
|
||||
using -I. -I$srcdir will use ./config.h rather than $srcdir/config.h
|
||||
(which it would do because it found this file in $srcdir). */
|
||||
#include <config.h>
|
||||
#else
|
||||
#include "config.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
|
||||
#include <stdlib.h>
|
||||
#else /* STDC_HEADERS or __GNU_LIBRARY__ */
|
||||
char *getenv ();
|
||||
#endif /* STDC_HEADERS or __GNU_LIBRARY__ */
|
||||
#include "getopt.h"
|
||||
|
||||
#if !defined (NULL)
|
||||
#ifndef __STDC__
|
||||
/* This is a separate conditional since some stdc systems
|
||||
reject `defined (const)'. */
|
||||
#ifndef const
|
||||
#define const
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Comment out all this code if we are using the GNU C Library, and are not
|
||||
actually compiling the library itself. This code is part of the GNU C
|
||||
Library, but also included in many other GNU distributions. Compiling
|
||||
and linking in this code is a waste when using the GNU C library
|
||||
(especially if it is a shared library). Rather than having every GNU
|
||||
program understand `configure --with-gnu-libc' and omit the object files,
|
||||
it is simpler to just do this in the source for each such file. */
|
||||
|
||||
#if defined (_LIBC) || !defined (__GNU_LIBRARY__)
|
||||
|
||||
|
||||
/* This needs to come after some library #include
|
||||
to get __GNU_LIBRARY__ defined. */
|
||||
#ifdef __GNU_LIBRARY__
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
char *getenv ();
|
||||
#endif
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
int
|
||||
gnu_getopt_long (argc, argv, options, long_options, opt_index)
|
||||
getopt_long (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char **argv;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
int val;
|
||||
|
||||
/* For strict POSIX compatibility, we must turn off long options. */
|
||||
if (getenv ("POSIX_ME_HARDER") == 0)
|
||||
_getopt_long_options = long_options;
|
||||
val = gnu_getopt (argc, argv, options);
|
||||
if (val == 0 && opt_index != NULL)
|
||||
*opt_index = option_index;
|
||||
return val;
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||
}
|
||||
|
||||
/* Like getopt_long, but '-' as well as '+' can indicate a long option.
|
||||
If an option that starts with '-' doesn't match a long option,
|
||||
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||
If an option that starts with '-' (not '--') doesn't match a long option,
|
||||
but does match a short option, it is parsed as a short option
|
||||
instead. */
|
||||
|
||||
int
|
||||
gnu_getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||
int argc;
|
||||
char **argv;
|
||||
char *const *argv;
|
||||
const char *options;
|
||||
const struct option *long_options;
|
||||
int *opt_index;
|
||||
{
|
||||
int val;
|
||||
|
||||
_getopt_long_options = long_options;
|
||||
_getopt_long_only = 1;
|
||||
val = gnu_getopt (argc, argv, options);
|
||||
if (val == 0 && opt_index != NULL)
|
||||
*opt_index = option_index;
|
||||
return val;
|
||||
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
#include <stdio.h>
|
||||
@ -89,7 +107,6 @@ main (argc, argv)
|
||||
while (1)
|
||||
{
|
||||
int this_option_optind = optind ? optind : 1;
|
||||
char *name = '\0';
|
||||
int option_index = 0;
|
||||
static struct option long_options[] =
|
||||
{
|
||||
@ -110,7 +127,7 @@ main (argc, argv)
|
||||
switch (c)
|
||||
{
|
||||
case 0:
|
||||
printf ("option %s", (long_options[option_index]).name);
|
||||
printf ("option %s", long_options[option_index].name);
|
||||
if (optarg)
|
||||
printf (" with arg %s", optarg);
|
||||
printf ("\n");
|
||||
@ -144,6 +161,10 @@ main (argc, argv)
|
||||
printf ("option c with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
printf ("option d with value `%s'\n", optarg);
|
||||
break;
|
||||
|
||||
case '?':
|
||||
break;
|
||||
|
||||
|
@ -19,6 +19,10 @@
|
||||
of getwd() which is much faster than getcwd(). As a result, we use the
|
||||
system's getwd() if it is available */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "system.h"
|
||||
|
||||
/* Get the current working directory into PATHNAME */
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Polk's hash list manager. So cool.
|
||||
*/
|
||||
@ -10,31 +10,32 @@
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)hash.c 1.14 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)hash.c 1.19 94/09/23 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
/* global caches */
|
||||
static List *listcache = NULL;
|
||||
static Node *nodecache = NULL;
|
||||
|
||||
#if __STDC__
|
||||
static void freenode_mem (Node * p);
|
||||
#else
|
||||
static void freenode_mem ();
|
||||
#endif /* __STDC__ */
|
||||
static void freenode_mem PROTO((Node * p));
|
||||
|
||||
/* hash function */
|
||||
static int
|
||||
hashp (key)
|
||||
char *key;
|
||||
{
|
||||
register char *p;
|
||||
register int n = 0;
|
||||
unsigned int h = 0;
|
||||
unsigned int g;
|
||||
|
||||
for (p = key; *p; p++)
|
||||
n += *p;
|
||||
while (*key != 0)
|
||||
{
|
||||
h = (h << 4) + *key++;
|
||||
if ((g = h & 0xf0000000) != 0)
|
||||
h = (h ^ (g >> 24)) ^ g;
|
||||
}
|
||||
|
||||
return (n % HASHSIZE);
|
||||
return (h % HASHSIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -60,7 +61,7 @@ getlist ()
|
||||
{
|
||||
/* make a new list from scratch */
|
||||
list = (List *) xmalloc (sizeof (List));
|
||||
bzero ((char *) list, sizeof (List));
|
||||
memset ((char *) list, 0, sizeof (List));
|
||||
node = getnode ();
|
||||
list->list = node;
|
||||
node->type = HEADER;
|
||||
@ -130,7 +131,7 @@ getnode ()
|
||||
}
|
||||
|
||||
/* always make it clean */
|
||||
bzero ((char *) p, sizeof (Node));
|
||||
memset ((char *) p, 0, sizeof (Node));
|
||||
p->type = UNKNOWN;
|
||||
|
||||
return (p);
|
||||
@ -247,7 +248,8 @@ addnode (list, p)
|
||||
}
|
||||
|
||||
/*
|
||||
* look up an entry in hash list table
|
||||
* look up an entry in hash list table and return a pointer to the
|
||||
* node. Return NULL on error or not found.
|
||||
*/
|
||||
Node *
|
||||
findnode (list, key)
|
||||
@ -273,9 +275,10 @@ findnode (list, key)
|
||||
* walk a list with a specific proc
|
||||
*/
|
||||
int
|
||||
walklist (list, proc)
|
||||
walklist (list, proc, closure)
|
||||
List *list;
|
||||
int (*proc) ();
|
||||
void *closure;
|
||||
{
|
||||
Node *head, *p;
|
||||
int err = 0;
|
||||
@ -285,7 +288,7 @@ walklist (list, proc)
|
||||
|
||||
head = list->list;
|
||||
for (p = head->next; p != head; p = p->next)
|
||||
err += proc (p);
|
||||
err += proc (p, closure);
|
||||
return (err);
|
||||
}
|
||||
|
||||
@ -336,3 +339,61 @@ sortlist (list, comp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Debugging functions. Quite useful to call from within gdb. */
|
||||
|
||||
char *
|
||||
nodetypestring (type)
|
||||
Ntype type;
|
||||
{
|
||||
switch (type) {
|
||||
case UNKNOWN: return("UNKNOWN");
|
||||
case HEADER: return("HEADER");
|
||||
case ENTRIES: return("ENTRIES");
|
||||
case FILES: return("FILES");
|
||||
case LIST: return("LIST");
|
||||
case RCSNODE: return("RCSNODE");
|
||||
case RCSVERS: return("RCSVERS");
|
||||
case DIRS: return("DIRS");
|
||||
case UPDATE: return("UPDATE");
|
||||
case LOCK: return("LOCK");
|
||||
case NDBMNODE: return("NDBMNODE");
|
||||
}
|
||||
|
||||
return("<trash>");
|
||||
}
|
||||
|
||||
int
|
||||
printnode (node, closure)
|
||||
Node *node;
|
||||
void *closure;
|
||||
{
|
||||
if (node == NULL)
|
||||
{
|
||||
(void) printf("NULL node.\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
(void) printf("Node at 0x%p: type = %s, key = 0x%p = \"%s\", data = 0x%p, next = 0x%p, prev = 0x%p\n",
|
||||
node, nodetypestring(node->type), node->key, node->key, node->data, node->next, node->prev);
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
void
|
||||
printlist (list)
|
||||
List *list;
|
||||
{
|
||||
if (list == NULL)
|
||||
{
|
||||
(void) printf("NULL list.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
(void) printf("List at 0x%p: list = 0x%p, HASHSIZE = %d, next = 0x%p\n",
|
||||
list, list->list, HASHSIZE, list->next);
|
||||
|
||||
(void) walklist(list, printnode, NULL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
/* @(#)hash.h 1.18 92/03/31 */
|
||||
/* $CVSid: @(#)hash.h 1.23 94/10/07 $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -51,27 +51,16 @@ struct entnode
|
||||
char *options;
|
||||
char *tag;
|
||||
char *date;
|
||||
char *conflict;
|
||||
};
|
||||
typedef struct entnode Entnode;
|
||||
|
||||
#if __STDC__
|
||||
List *getlist (void);
|
||||
Node *findnode (List * list, char *key);
|
||||
Node *getnode (void);
|
||||
int addnode (List * list, Node * p);
|
||||
int walklist (List * list, int (*proc) ());
|
||||
void dellist (List ** listp);
|
||||
void delnode (Node * p);
|
||||
void freenode (Node * p);
|
||||
void sortlist (List * list, int (*comp) ());
|
||||
#else
|
||||
List *getlist ();
|
||||
Node *findnode ();
|
||||
Node *getnode ();
|
||||
int addnode ();
|
||||
int walklist ();
|
||||
void dellist ();
|
||||
void delnode ();
|
||||
void freenode ();
|
||||
void sortlist ();
|
||||
#endif /* __STDC__ */
|
||||
List *getlist PROTO((void));
|
||||
Node *findnode PROTO((List * list, char *key));
|
||||
Node *getnode PROTO((void));
|
||||
int addnode PROTO((List * list, Node * p));
|
||||
int walklist PROTO((List * list, int PROTO((*proc)) PROTO((Node *n, void *closure)), void *closure));
|
||||
void dellist PROTO((List ** listp));
|
||||
void delnode PROTO((Node * p));
|
||||
void freenode PROTO((Node * p));
|
||||
void sortlist PROTO((List * list, int PROTO((*comp))()));
|
||||
|
@ -15,6 +15,10 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) 1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* A simple ndbm-emulator for CVS. It parses a text file of the format:
|
||||
*
|
||||
@ -18,7 +18,8 @@
|
||||
#ifdef MY_NDBM
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)myndbm.c 1.5 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)myndbm.c 1.7 94/09/23 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
static void mydbm_load_file ();
|
||||
@ -138,7 +139,7 @@ mydbm_load_file (fp, list)
|
||||
|
||||
for (cont = 0; fgets (line, sizeof (line), fp) != NULL;)
|
||||
{
|
||||
if ((cp = rindex (line, '\n')) != NULL)
|
||||
if ((cp = strrchr (line, '\n')) != NULL)
|
||||
*cp = '\0'; /* strip the newline */
|
||||
|
||||
/*
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* @(#)myndbm.h 1.3 92/02/29 */
|
||||
/* $CVSid: @(#)myndbm.h 1.4 94/09/21 $ */
|
||||
|
||||
#ifdef MY_NDBM
|
||||
|
||||
@ -27,18 +27,10 @@ typedef struct
|
||||
#define dbm_firstkey mydbm_firstkey
|
||||
#define dbm_nextkey mydbm_nextkey
|
||||
|
||||
#if __STDC__
|
||||
DBM *mydbm_open (char *file, int flags, int mode);
|
||||
void mydbm_close (DBM * db);
|
||||
datum mydbm_fetch (DBM * db, datum key);
|
||||
datum mydbm_firstkey (DBM * db);
|
||||
datum mydbm_nextkey (DBM * db);
|
||||
#else
|
||||
DBM *mydbm_open ();
|
||||
void mydbm_close ();
|
||||
datum mydbm_fetch ();
|
||||
datum mydbm_firstkey ();
|
||||
datum mydbm_nextkey ();
|
||||
#endif /* __STDC__ */
|
||||
DBM *mydbm_open PROTO((char *file, int flags, int mode));
|
||||
void mydbm_close PROTO((DBM * db));
|
||||
datum mydbm_fetch PROTO((DBM * db, datum key));
|
||||
datum mydbm_firstkey PROTO((DBM * db));
|
||||
datum mydbm_nextkey PROTO((DBM * db));
|
||||
|
||||
#endif /* MY_NDBM */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,6 +15,10 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
|
@ -30,10 +30,14 @@
|
||||
* must not themselves make calls to the signal handling
|
||||
* facilities.
|
||||
*
|
||||
* @(#)sighandle.c 1.9 92/03/31
|
||||
* $CVSid: @(#)sighandle.c 1.13 94/10/07 $
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
@ -54,18 +58,14 @@ char *malloc();
|
||||
#undef POSIX /* Minix 1.6 doesn't support POSIX.1 sigaction yet */
|
||||
#endif
|
||||
|
||||
#ifndef SIGTYPE
|
||||
#define SIGTYPE void
|
||||
#endif
|
||||
|
||||
/* Define the highest signal number (usually) */
|
||||
#ifndef SIGMAX
|
||||
#define SIGMAX 32
|
||||
#define SIGMAX 64
|
||||
#endif
|
||||
|
||||
/* Define linked list of signal handlers structure */
|
||||
struct SIG_hlist {
|
||||
SIGTYPE (*handler)();
|
||||
RETSIGTYPE (*handler)();
|
||||
struct SIG_hlist *next;
|
||||
};
|
||||
|
||||
@ -84,7 +84,7 @@ static struct sigaction *SIG_defaults;
|
||||
#ifdef BSD_SIGNALS
|
||||
static struct sigvec *SIG_defaults;
|
||||
#else
|
||||
static SIGTYPE (**SIG_defaults)();
|
||||
static RETSIGTYPE (**SIG_defaults)();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -112,11 +112,7 @@ static int SIG_init()
|
||||
|
||||
#ifdef POSIX
|
||||
(void) sigfillset(&sigset_test);
|
||||
for (i = 1; sigismember(&sigset_test, i) == 1; i++)
|
||||
#ifdef BROKEN_SIGISMEMBER
|
||||
if ( i >= NSIG )
|
||||
break
|
||||
#endif
|
||||
for (i = 1; i < SIGMAX && sigismember(&sigset_test, i) == 1; i++)
|
||||
;
|
||||
if (i < SIGMAX)
|
||||
i = SIGMAX;
|
||||
@ -133,8 +129,8 @@ static int SIG_init()
|
||||
calloc(i, sizeof(struct sigvec));
|
||||
#else
|
||||
if (!SIG_defaults)
|
||||
SIG_defaults = (SIGTYPE (**)())
|
||||
calloc(i, sizeof(SIGTYPE (**)()));
|
||||
SIG_defaults = (RETSIGTYPE (**)())
|
||||
calloc(i, sizeof(RETSIGTYPE (**)()));
|
||||
#endif
|
||||
SIG_crSectMask = 0;
|
||||
#endif
|
||||
@ -149,7 +145,7 @@ static int SIG_init()
|
||||
* they were registered.
|
||||
*/
|
||||
|
||||
static SIGTYPE SIG_handle(sig)
|
||||
static RETSIGTYPE SIG_handle(sig)
|
||||
int sig;
|
||||
{
|
||||
struct SIG_hlist *this;
|
||||
@ -175,7 +171,7 @@ int sig;
|
||||
|
||||
int SIG_register(sig,fn)
|
||||
int sig;
|
||||
SIGTYPE (*fn)();
|
||||
RETSIGTYPE (*fn)();
|
||||
{
|
||||
int val;
|
||||
struct SIG_hlist *this;
|
||||
@ -236,7 +232,7 @@ SIGTYPE (*fn)();
|
||||
val = sigvec(sig, &vec, &SIG_defaults[sig]);
|
||||
#else
|
||||
if ((SIG_defaults[sig] = signal(sig, SIG_handle)) ==
|
||||
(SIGTYPE (*)()) -1)
|
||||
(RETSIGTYPE (*)()) -1)
|
||||
val = -1;
|
||||
#endif
|
||||
#endif
|
||||
@ -279,7 +275,7 @@ SIGTYPE (*fn)();
|
||||
|
||||
int SIG_deregister(sig,fn)
|
||||
int sig;
|
||||
SIGTYPE (*fn)();
|
||||
RETSIGTYPE (*fn)();
|
||||
{
|
||||
int val;
|
||||
struct SIG_hlist *this;
|
||||
@ -341,7 +337,7 @@ SIGTYPE (*fn)();
|
||||
#ifdef BSD_SIGNALS
|
||||
val = sigvec(sig, &SIG_defaults[sig], (struct sigvec *) NULL);
|
||||
#else
|
||||
if (signal(sig, SIG_defaults[sig]) == (SIGTYPE (*)()) -1)
|
||||
if (signal(sig, SIG_defaults[sig]) == (RETSIGTYPE (*)()) -1)
|
||||
val = -1;
|
||||
#endif
|
||||
#endif
|
||||
|
@ -15,6 +15,10 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifdef STDC_HEADERS
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -15,14 +15,20 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(USG)
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#ifndef index
|
||||
#define index strchr
|
||||
#endif
|
||||
#else
|
||||
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
|
||||
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||
#else /* not STDC_HJEADERS and not HAVE_STRING_H */
|
||||
#include <strings.h>
|
||||
#endif
|
||||
/* memory.h and strings.h conflict on some systems. */
|
||||
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
@ -43,7 +49,7 @@ strip_path (path)
|
||||
int stripped = 0;
|
||||
char *cp, *slash;
|
||||
|
||||
for (cp = path; (slash = index(cp, '/')) != NULL; cp = slash)
|
||||
for (cp = path; (slash = strchr(cp, '/')) != NULL; cp = slash)
|
||||
{
|
||||
*slash = '\0';
|
||||
if ((!*cp && (cp != path || stripped)) ||
|
||||
|
@ -15,12 +15,21 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#if defined(STDC_HEADERS) || defined(USG)
|
||||
#include <string.h>
|
||||
#else
|
||||
#include <strings.h>
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
#include <string.h>
|
||||
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
|
||||
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||
#else /* not STDC_HJEADERS and not HAVE_STRING_H */
|
||||
#include <strings.h>
|
||||
/* memory.h and strings.h conflict on some systems. */
|
||||
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
|
||||
/* Remove trailing slashes from PATH. */
|
||||
|
||||
void
|
||||
|
@ -3,19 +3,24 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* Various useful functions for the CVS support code.
|
||||
*/
|
||||
|
||||
#include "cvs.h"
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$CVSid: @(#)subr.c 1.64 94/10/07 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#ifdef _MINIX
|
||||
#undef POSIX /* Minix 1.6 doesn't support POSIX.1 sigaction yet */
|
||||
#endif
|
||||
|
||||
#ifndef VPRINTF_MISSING
|
||||
#if __STDC__
|
||||
#ifdef HAVE_VPRINTF
|
||||
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
|
||||
#include <stdarg.h>
|
||||
#define VA_START(args, lastarg) va_start(args, lastarg)
|
||||
#else
|
||||
@ -27,17 +32,24 @@
|
||||
#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
|
||||
#endif
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)subr.c 1.52 92/03/31";
|
||||
/*
|
||||
* I don't know of a convenient way to test this at configure time, or else
|
||||
* I'd certainly do it there.
|
||||
*/
|
||||
#if defined(NeXT)
|
||||
#define LOSING_TMPNAM_FUNCTION
|
||||
#ifndef _POSIX_SOURCE
|
||||
/*
|
||||
* NeXT doesn't define these without _POSIX_SOURCE,
|
||||
* but that changes a lot of things.
|
||||
*/
|
||||
#define WEXITSTATUS(x) ((x).w_retcode)
|
||||
#define WTERMSIG(x) ((x).w_termsig)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if __STDC__
|
||||
static void run_add_arg (char *s);
|
||||
static void run_init_prog (void);
|
||||
#else
|
||||
static void run_add_arg ();
|
||||
static void run_init_prog ();
|
||||
#endif /* __STDC__ */
|
||||
static void run_add_arg PROTO((char *s));
|
||||
static void run_init_prog PROTO((void));
|
||||
|
||||
extern char *getlogin ();
|
||||
extern char *strtok ();
|
||||
@ -74,7 +86,7 @@ copy_file (from, to)
|
||||
if (read (fdin, buf, (int) sb.st_size) != (int) sb.st_size)
|
||||
error (1, errno, "cannot read file %s for copying", from);
|
||||
if (write (fdout, buf, (int) sb.st_size) != (int) sb.st_size
|
||||
#ifndef FSYNC_MISSING
|
||||
#ifdef HAVE_FSYNC
|
||||
|| fsync (fdout) == -1
|
||||
#endif
|
||||
)
|
||||
@ -88,11 +100,15 @@ copy_file (from, to)
|
||||
error (1, errno, "cannot close %s", to);
|
||||
|
||||
/* now, set the times for the copied file to match those of the original */
|
||||
memset ((char *) &t, 0, sizeof (t));
|
||||
t.actime = sb.st_atime;
|
||||
t.modtime = sb.st_mtime;
|
||||
(void) utime (to, &t);
|
||||
}
|
||||
|
||||
/* FIXME-krp: these functions would benefit from caching the char * &
|
||||
stat buf. */
|
||||
|
||||
/*
|
||||
* Returns non-zero if the argument file is a directory, or is a symbolic
|
||||
* link which points to a directory.
|
||||
@ -202,25 +218,8 @@ make_directory (name)
|
||||
{
|
||||
struct stat buf;
|
||||
|
||||
if (stat (name, &buf) == 0)
|
||||
{
|
||||
if (S_ISDIR (buf.st_mode))
|
||||
{
|
||||
if (access (name, (R_OK | W_OK | X_OK)) == 0)
|
||||
{
|
||||
error (0, 0, "Directory %s already exists", name);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
error (0, 0,
|
||||
"Directory %s already exists but is protected from you",
|
||||
name);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (stat (name, &buf) == 0 && (!S_ISDIR (buf.st_mode)))
|
||||
error (0, 0, "%s already exists but is not a directory", name);
|
||||
}
|
||||
if (!noexec && mkdir (name, 0777) < 0)
|
||||
error (1, errno, "cannot make directory %s", name);
|
||||
}
|
||||
@ -245,7 +244,7 @@ make_directories (name)
|
||||
error (0, errno, "cannot make path to %s", name);
|
||||
return;
|
||||
}
|
||||
if ((cp = rindex (name, '/')) == NULL)
|
||||
if ((cp = strrchr (name, '/')) == NULL)
|
||||
return;
|
||||
*cp = '\0';
|
||||
make_directories (name);
|
||||
@ -260,14 +259,12 @@ make_directories (name)
|
||||
*/
|
||||
char *
|
||||
xmalloc (bytes)
|
||||
int bytes;
|
||||
size_t bytes;
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (bytes <= 0)
|
||||
error (1, 0, "bad malloc size %d", bytes);
|
||||
if ((cp = malloc ((unsigned) bytes)) == NULL)
|
||||
error (1, 0, "malloc failed");
|
||||
if ((cp = malloc (bytes)) == NULL)
|
||||
error (1, 0, "can not allocate %lu bytes", (unsigned long) bytes);
|
||||
return (cp);
|
||||
}
|
||||
|
||||
@ -279,17 +276,17 @@ xmalloc (bytes)
|
||||
char *
|
||||
xrealloc (ptr, bytes)
|
||||
char *ptr;
|
||||
int bytes;
|
||||
size_t bytes;
|
||||
{
|
||||
char *cp;
|
||||
|
||||
if (!ptr)
|
||||
return (xmalloc (bytes));
|
||||
cp = malloc (bytes);
|
||||
else
|
||||
cp = realloc (ptr, bytes);
|
||||
|
||||
if (bytes <= 0)
|
||||
error (1, 0, "bad realloc size %d", bytes);
|
||||
if ((cp = realloc (ptr, (unsigned) bytes)) == NULL)
|
||||
error (1, 0, "realloc failed");
|
||||
if (cp == NULL)
|
||||
error (1, 0, "can not reallocate %lu bytes", (unsigned long) bytes);
|
||||
return (cp);
|
||||
}
|
||||
|
||||
@ -320,7 +317,7 @@ xchmod (fname, writable)
|
||||
int writable;
|
||||
{
|
||||
struct stat sb;
|
||||
int mode, oumask;
|
||||
mode_t mode, oumask;
|
||||
|
||||
if (stat (fname, &sb) < 0)
|
||||
{
|
||||
@ -399,9 +396,12 @@ unlink_file (f)
|
||||
* Compare "file1" to "file2". Return non-zero if they don't compare exactly.
|
||||
*
|
||||
* mallocs a buffer large enough to hold the entire file and does two reads to
|
||||
* load the buffer and calls bcmp to do the cmp. This is reasonable, since
|
||||
* load the buffer and calls memcmp to do the cmp. This is reasonable, since
|
||||
* source files are typically not too large.
|
||||
*/
|
||||
|
||||
/* richfix: this *could* exploit mmap. */
|
||||
|
||||
int
|
||||
xcmp (file1, file2)
|
||||
char *file1;
|
||||
@ -430,10 +430,10 @@ xcmp (file1, file2)
|
||||
buf1 = xmalloc ((int) size);
|
||||
buf2 = xmalloc ((int) size);
|
||||
if (read (fd1, buf1, (int) size) != (int) size)
|
||||
error (1, errno, "cannot read file %s cor comparing", file1);
|
||||
error (1, errno, "cannot read file %s for comparing", file1);
|
||||
if (read (fd2, buf2, (int) size) != (int) size)
|
||||
error (1, errno, "cannot read file %s for comparing", file2);
|
||||
ret = bcmp (buf1, buf2, (int) size);
|
||||
ret = memcmp(buf1, buf2, (int) size);
|
||||
free (buf1);
|
||||
free (buf2);
|
||||
}
|
||||
@ -512,10 +512,10 @@ getcaller ()
|
||||
static char uidname[20];
|
||||
struct passwd *pw;
|
||||
char *name;
|
||||
int uid;
|
||||
uid_t uid;
|
||||
|
||||
uid = getuid ();
|
||||
if (uid == 0)
|
||||
if (uid == (uid_t) 0)
|
||||
{
|
||||
/* super-user; try getlogin() to distinguish */
|
||||
if (((name = getenv("LOGNAME")) || (name = getenv("USER")) ||
|
||||
@ -524,7 +524,7 @@ getcaller ()
|
||||
}
|
||||
if ((pw = (struct passwd *) getpwuid (uid)) == NULL)
|
||||
{
|
||||
(void) sprintf (uidname, "uid%d", uid);
|
||||
(void) sprintf (uidname, "uid%d", (unsigned long) uid);
|
||||
return (uidname);
|
||||
}
|
||||
return (pw->pw_name);
|
||||
@ -549,7 +549,7 @@ static int run_argc;
|
||||
static int run_argc_allocated;
|
||||
|
||||
/* VARARGS */
|
||||
#if !defined (VPRINTF_MISSING) && __STDC__
|
||||
#if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
|
||||
void
|
||||
run_setup (char *fmt,...)
|
||||
#else
|
||||
@ -560,7 +560,7 @@ run_setup (fmt, va_alist)
|
||||
|
||||
#endif
|
||||
{
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
va_list args;
|
||||
|
||||
#endif
|
||||
@ -581,7 +581,7 @@ run_setup (fmt, va_alist)
|
||||
run_argc = 0;
|
||||
|
||||
/* process the varargs into run_prog */
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
VA_START (args, fmt);
|
||||
(void) vsprintf (run_prog, fmt, args);
|
||||
va_end (args);
|
||||
@ -602,7 +602,7 @@ run_arg (s)
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
#if !defined (VPRINTF_MISSING) && __STDC__
|
||||
#if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
|
||||
void
|
||||
run_args (char *fmt,...)
|
||||
#else
|
||||
@ -613,7 +613,7 @@ run_args (fmt, va_alist)
|
||||
|
||||
#endif
|
||||
{
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
va_list args;
|
||||
|
||||
#endif
|
||||
@ -621,7 +621,7 @@ run_args (fmt, va_alist)
|
||||
run_init_prog ();
|
||||
|
||||
/* process the varargs into run_prog */
|
||||
#ifndef VPRINTF_MISSING
|
||||
#ifdef HAVE_VPRINTF
|
||||
VA_START (args, fmt);
|
||||
(void) vsprintf (run_prog, fmt, args);
|
||||
va_end (args);
|
||||
@ -668,7 +668,12 @@ run_exec (stin, stout, sterr, flags)
|
||||
{
|
||||
int shin, shout, sherr;
|
||||
int mode_out, mode_err;
|
||||
int status = -1;
|
||||
#if defined(NeXT) && !defined(_POSIX_SOURCE)
|
||||
union wait status;
|
||||
#else
|
||||
int status;
|
||||
#endif
|
||||
int rc = -1;
|
||||
int rerrno = 0;
|
||||
int pid, w;
|
||||
|
||||
@ -682,7 +687,7 @@ run_exec (stin, stout, sterr, flags)
|
||||
struct sigvec vec, ivec, qvec;
|
||||
|
||||
#else
|
||||
SIGTYPE (*istat) (), (*qstat) ();
|
||||
RETSIGTYPE (*istat) (), (*qstat) ();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -733,11 +738,15 @@ run_exec (stin, stout, sterr, flags)
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we don't flush this twice, once in the subprocess. */
|
||||
fflush (stdout);
|
||||
fflush (stderr);
|
||||
|
||||
/* The output files, if any, are now created. Do the fork and dups */
|
||||
#ifdef VFORK_MISSING
|
||||
pid = fork ();
|
||||
#else
|
||||
#ifdef HAVE_VFORK
|
||||
pid = vfork ();
|
||||
#else
|
||||
pid = fork ();
|
||||
#endif
|
||||
if (pid == 0)
|
||||
{
|
||||
@ -761,6 +770,7 @@ run_exec (stin, stout, sterr, flags)
|
||||
|
||||
/* dup'ing is done. try to run it now */
|
||||
(void) execvp (run_argv[0], run_argv);
|
||||
error (0, errno, "cannot exec %s", run_argv[0]);
|
||||
_exit (127);
|
||||
}
|
||||
else if (pid == -1)
|
||||
@ -790,7 +800,7 @@ run_exec (stin, stout, sterr, flags)
|
||||
#ifdef BSD_SIGNALS
|
||||
if (flags & RUN_SIGIGNORE)
|
||||
{
|
||||
bzero ((char *) &vec, sizeof (vec));
|
||||
memset ((char *) &vec, 0, sizeof (vec));
|
||||
vec.sv_handler = SIG_IGN;
|
||||
(void) sigvec (SIGINT, &vec, &ivec);
|
||||
(void) sigvec (SIGQUIT, &vec, &qvec);
|
||||
@ -816,19 +826,19 @@ run_exec (stin, stout, sterr, flags)
|
||||
#endif
|
||||
if (w == -1)
|
||||
{
|
||||
status = -1;
|
||||
rc = -1;
|
||||
rerrno = errno;
|
||||
}
|
||||
else if (WIFEXITED (status))
|
||||
status = WEXITSTATUS (status);
|
||||
rc = WEXITSTATUS (status);
|
||||
else if (WIFSIGNALED (status))
|
||||
{
|
||||
if (WTERMSIG (status) == SIGPIPE)
|
||||
error (1, 0, "broken pipe");
|
||||
status = 2;
|
||||
rc = 2;
|
||||
}
|
||||
else
|
||||
status = 1;
|
||||
rc = 1;
|
||||
|
||||
/* restore the signals */
|
||||
#ifdef POSIX
|
||||
@ -868,7 +878,7 @@ run_exec (stin, stout, sterr, flags)
|
||||
out0:
|
||||
if (rerrno)
|
||||
errno = rerrno;
|
||||
return (status);
|
||||
return (rc);
|
||||
}
|
||||
|
||||
void
|
||||
@ -910,3 +920,130 @@ get_date (date, now)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Given two revisions, find their greatest common ancestor. If the
|
||||
two input revisions exist, then rcs guarantees that the gca will
|
||||
exist. */
|
||||
|
||||
char *
|
||||
gca (rev1, rev2)
|
||||
char *rev1;
|
||||
char *rev2;
|
||||
{
|
||||
int dots;
|
||||
char gca[PATH_MAX];
|
||||
char *p[2];
|
||||
int j[2];
|
||||
|
||||
if (rev1 == NULL || rev2 == NULL)
|
||||
{
|
||||
error (0, 0, "sanity failure in gca");
|
||||
abort();
|
||||
}
|
||||
|
||||
/* walk the strings, reading the common parts. */
|
||||
gca[0] = '\0';
|
||||
p[0] = rev1;
|
||||
p[1] = rev2;
|
||||
do
|
||||
{
|
||||
int i;
|
||||
char c[2];
|
||||
char *s[2];
|
||||
|
||||
for (i = 0; i < 2; ++i)
|
||||
{
|
||||
/* swap out the dot */
|
||||
s[i] = strchr (p[i], '.');
|
||||
if (s[i] != NULL) {
|
||||
c[i] = *s[i];
|
||||
}
|
||||
|
||||
/* read an int */
|
||||
j[i] = atoi (p[i]);
|
||||
|
||||
/* swap back the dot... */
|
||||
if (s[i] != NULL) {
|
||||
*s[i] = c[i];
|
||||
p[i] = s[i] + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* or mark us at the end */
|
||||
p[i] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* use the lowest. */
|
||||
(void) sprintf (gca + strlen (gca), "%d.",
|
||||
j[0] < j[1] ? j[0] : j[1]);
|
||||
|
||||
} while (j[0] == j[1]
|
||||
&& p[0] != NULL
|
||||
&& p[1] != NULL);
|
||||
|
||||
/* back up over that last dot. */
|
||||
gca[strlen(gca) - 1] = '\0';
|
||||
|
||||
/* numbers differ, or we ran out of strings. we're done with the
|
||||
common parts. */
|
||||
|
||||
dots = numdots (gca);
|
||||
if (dots == 0)
|
||||
{
|
||||
/* revisions differ in trunk major number. */
|
||||
|
||||
char *q;
|
||||
char *s;
|
||||
|
||||
s = (j[0] < j[1]) ? p[0] : p[1];
|
||||
|
||||
if (s == NULL)
|
||||
{
|
||||
/* we only got one number. this is strange. */
|
||||
error (0, 0, "bad revisions %s or %s", rev1, rev2);
|
||||
abort();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* we have a minor number. use it. */
|
||||
q = gca + strlen (gca);
|
||||
|
||||
*q++ = '.';
|
||||
for ( ; *s != '.' && *s != '\0'; )
|
||||
*q++ = *s++;
|
||||
|
||||
*q = '\0';
|
||||
}
|
||||
}
|
||||
else if ((dots & 1) == 0)
|
||||
{
|
||||
/* if we have an even number of dots, then we have a branch.
|
||||
remove the last number in order to make it a revision. */
|
||||
|
||||
char *s;
|
||||
|
||||
s = strrchr(gca, '.');
|
||||
*s = '\0';
|
||||
}
|
||||
|
||||
return (xstrdup (gca));
|
||||
}
|
||||
|
||||
#ifdef LOSING_TMPNAM_FUNCTION
|
||||
char *tmpnam(char *s)
|
||||
{
|
||||
static char value[L_tmpnam+1];
|
||||
|
||||
if (s){
|
||||
strcpy(s,"/tmp/cvsXXXXXX");
|
||||
mktemp(s);
|
||||
return s;
|
||||
}else{
|
||||
strcpy(value,"/tmp/cvsXXXXXX");
|
||||
mktemp(s);
|
||||
return value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -15,7 +15,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* @(#)system.h 1.14 92/04/10 */
|
||||
/* $CVSid: @(#)system.h 1.18 94/09/25 $ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -52,16 +52,13 @@
|
||||
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
|
||||
#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
|
||||
#endif
|
||||
#if defined(MKFIFO_MISSING)
|
||||
#if !defined(HAVE_MKFIFO)
|
||||
#define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0))
|
||||
#endif
|
||||
|
||||
#ifdef POSIX
|
||||
#if defined(POSIX) || defined(HAVE_UNISTD_H)
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX pathconf ("/", _PC_PATH_MAX)
|
||||
#endif
|
||||
#else
|
||||
off_t lseek ();
|
||||
#endif
|
||||
@ -72,7 +69,7 @@ off_t lseek ();
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifdef TIMEB_H_MISSING
|
||||
#ifndef HAVE_SYS_TIMEB_H
|
||||
struct timeb {
|
||||
time_t time; /* Seconds since the epoch */
|
||||
unsigned short millitm; /* Field not used */
|
||||
@ -87,29 +84,66 @@ struct timeb {
|
||||
#include <sys/timeb.h>
|
||||
#endif
|
||||
|
||||
#if defined(FTIME_MISSING) && !defined(HAVE_TIMEZONE)
|
||||
#if !defined(HAVE_FTIME) && !defined(HAVE_TIMEZONE)
|
||||
#if !defined(timezone)
|
||||
extern char *timezone();
|
||||
extern long timezone;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef POSIX
|
||||
|
||||
/*
|
||||
** MAXPATHLEN and PATH_MAX
|
||||
**
|
||||
** On most systems MAXPATHLEN is defined in sys/param.h to be 1024. Of
|
||||
** those that this is not true, again most define PATH_MAX in limits.h
|
||||
** or sys/limits.h which usually gets included by limits.h. On the few
|
||||
** remaining systems that neither statement is true, _POSIX_PATH_MAX
|
||||
** is defined.
|
||||
**
|
||||
** So:
|
||||
** 1. If PATH_MAX is defined just use it.
|
||||
** 2. If MAXPATHLEN is defined but not PATH_MAX, then define
|
||||
** PATH_MAX in terms of MAXPATHLEN.
|
||||
** 3. If neither is defined, include limits.h and check for
|
||||
** PATH_MAX again.
|
||||
** 4. If PATH_MAX is still not defined but _POSIX_PATH_MAX is,
|
||||
** then define PATH_MAX in terms of _POSIX_PATH_MAX.
|
||||
** 5. And if even _POSIX_PATH_MAX doesn't exist just put in
|
||||
** a reasonable value.
|
||||
**
|
||||
** This works on:
|
||||
** Sun Sparc 10 SunOS 4.1.3 & Solaris 1.2
|
||||
** HP 9000/700 HP/UX 8.07 & HP/UX 9.01
|
||||
** Tektronix XD88/10 UTekV 3.2e
|
||||
** IBM RS6000 AIX 3.2
|
||||
** Dec Alpha OSF 1 ????
|
||||
** Intel 386 BSDI BSD/386
|
||||
** Apollo Domain 10.4
|
||||
** NEC SVR4
|
||||
*/
|
||||
|
||||
/* On MOST systems this will get you MAXPATHLEN */
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_PATH_MAX
|
||||
#define _POSIX_PATH_MAX 255
|
||||
#endif
|
||||
|
||||
#ifndef PATH_MAX
|
||||
# ifdef MAXPATHLEN
|
||||
# define PATH_MAX MAXPATHLEN
|
||||
# else
|
||||
# include <limits.h>
|
||||
# ifndef PATH_MAX
|
||||
# ifdef _POSIX_PATH_MAX
|
||||
# define PATH_MAX _POSIX_PATH_MAX
|
||||
#endif
|
||||
#endif
|
||||
# else
|
||||
# define PATH_MAX 1024
|
||||
# endif /* _POSIX_PATH_MAX */
|
||||
# endif /* PATH_MAX */
|
||||
# endif /* MAXPATHLEN */
|
||||
#endif /* PATH_MAX */
|
||||
|
||||
#ifdef POSIX
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_UTIME_H
|
||||
#include <utime.h>
|
||||
#else
|
||||
#ifndef ALTOS
|
||||
@ -122,29 +156,33 @@ struct utimbuf
|
||||
int utime ();
|
||||
#endif
|
||||
|
||||
#if defined(USG) || defined(STDC_HEADERS)
|
||||
#if STDC_HEADERS || HAVE_STRING_H
|
||||
#include <string.h>
|
||||
#ifndef STDC_HEADERS
|
||||
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
|
||||
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||
#include <memory.h>
|
||||
#endif
|
||||
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||
|
||||
#ifndef index
|
||||
#define index strchr
|
||||
#endif
|
||||
#endif /* index */
|
||||
|
||||
#ifndef rindex
|
||||
#define rindex strrchr
|
||||
#endif
|
||||
#ifndef bcopy
|
||||
#define bcopy(from, to, len) memcpy ((to), (from), (len))
|
||||
#endif
|
||||
#ifndef bzero
|
||||
#define bzero(s, n) (void) memset ((s), 0, (n))
|
||||
#endif
|
||||
#endif /* rindex */
|
||||
|
||||
#ifndef bcmp
|
||||
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
|
||||
#endif
|
||||
#else
|
||||
#endif /* bcmp */
|
||||
|
||||
#ifndef bzero
|
||||
#define bzero(s, n) memset ((s), 0, (n))
|
||||
#endif /* bzero */
|
||||
|
||||
#else /* not STDC_HJEADERS and not HAVE_STRING_H */
|
||||
#include <strings.h>
|
||||
#endif
|
||||
/* memory.h and strings.h conflict on some systems. */
|
||||
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
|
||||
|
||||
#include <errno.h>
|
||||
#ifdef STDC_HEADERS
|
||||
@ -157,34 +195,24 @@ char *calloc ();
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#ifdef bsdi
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
#else
|
||||
#ifdef sparc
|
||||
#include <alloca.h>
|
||||
#else
|
||||
#ifndef _AIX
|
||||
/* AIX alloca decl has to be the first thing in the file, bletch! */
|
||||
char *alloca ();
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(USG) || defined(POSIX)
|
||||
#include <fcntl.h>
|
||||
char *getcwd ();
|
||||
#else
|
||||
#include <sys/file.h>
|
||||
char *getwd ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#include <sys/file.h>
|
||||
#endif
|
||||
|
||||
#ifndef SEEK_SET
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
#endif
|
||||
|
||||
#ifndef F_OK
|
||||
#define F_OK 0
|
||||
#define X_OK 1
|
||||
@ -192,23 +220,23 @@ char *getwd ();
|
||||
#define R_OK 4
|
||||
#endif
|
||||
|
||||
#ifdef DIRENT
|
||||
/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
|
||||
#if defined(DIRENT) || defined(_POSIX_VERSION)
|
||||
#include <dirent.h>
|
||||
#ifdef direct
|
||||
#undef direct
|
||||
#endif
|
||||
#define direct dirent
|
||||
#else
|
||||
#ifdef SYSNDIR
|
||||
#define NLENGTH(dirent) (strlen((dirent)->d_name))
|
||||
#else /* not (DIRENT or _POSIX_VERSION) */
|
||||
#define dirent direct
|
||||
#define NLENGTH(dirent) ((dirent)->d_namlen)
|
||||
#ifdef HAVE_SYS_NDIR_H
|
||||
#include <sys/ndir.h>
|
||||
#else
|
||||
#ifdef NDIR
|
||||
#include <ndir.h>
|
||||
#else /* must be BSD */
|
||||
#endif
|
||||
#ifdef HAVE_SYS_DIR_H
|
||||
#include <sys/dir.h>
|
||||
#endif
|
||||
#ifdef HAVE_NDIR_H
|
||||
#include <ndir.h>
|
||||
#endif
|
||||
#endif
|
||||
#endif /* not (DIRENT or _POSIX_VERSION) */
|
||||
|
||||
/* Convert B 512-byte blocks to kilobytes if K is nonzero,
|
||||
otherwise return it unchanged. */
|
||||
@ -218,6 +246,17 @@ char *getwd ();
|
||||
#define lstat stat
|
||||
#endif
|
||||
|
||||
#ifndef SIGTYPE
|
||||
#define SIGTYPE void
|
||||
/*
|
||||
* Some UNIX distributions don't include these in their stat.h Defined here
|
||||
* because "config.h" is always included last.
|
||||
*/
|
||||
#ifndef S_IWRITE
|
||||
#define S_IWRITE 0000200 /* write permission, owner */
|
||||
#endif
|
||||
#ifndef S_IWGRP
|
||||
#define S_IWGRP 0000020 /* write permission, grougroup */
|
||||
#endif
|
||||
#ifndef S_IWOTH
|
||||
#define S_IWOTH 0000002 /* write permission, other */
|
||||
#endif
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef POSIX
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/types.h> /* For pid_t. */
|
||||
#include <sys/wait.h>
|
||||
#else
|
||||
|
@ -15,6 +15,10 @@
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Read one line from standard input
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" @(#)mkmodules.1 1.3 92/01/30
|
||||
.\" $CVSid: @(#)mkmodules.1 1.3 92/01/30 $
|
||||
.\"
|
||||
.TH MKMODULES 1 "12 October 1991"
|
||||
.SH "NAME"
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright (c) 1989-1992, Brian Berliner
|
||||
*
|
||||
* You may distribute under the terms of the GNU General Public License as
|
||||
* specified in the README file that comes with the CVS 1.3 kit.
|
||||
* specified in the README file that comes with the CVS 1.4 kit.
|
||||
*
|
||||
* mkmodules
|
||||
*
|
||||
@ -13,11 +13,9 @@
|
||||
|
||||
#include "cvs.h"
|
||||
|
||||
#undef PATH_MAX
|
||||
#define PATH_MAX 1024 /* max number of bytes in pathname */
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "@(#)mkmodules.c 1.39 92/03/31";
|
||||
static char rcsid[] = "$CVSid: @(#)mkmodules.c 1.45 94/09/30 $";
|
||||
USE(rcsid)
|
||||
#endif
|
||||
|
||||
#ifndef DBLKSIZ
|
||||
@ -30,30 +28,16 @@ char *Rcsbin = RCSBIN_DFLT;
|
||||
int noexec = 0; /* Here only to satisfy use in subr.c */
|
||||
int trace = 0; /* Here only to satisfy use in subr.c */
|
||||
|
||||
#if __STDC__
|
||||
static int checkout_file (char *file, char *temp);
|
||||
static void make_tempfile (char *temp);
|
||||
static void mkmodules_usage (void);
|
||||
static void rename_rcsfile (char *temp, char *real);
|
||||
static int checkout_file PROTO((char *file, char *temp));
|
||||
static void make_tempfile PROTO((char *temp));
|
||||
static void mkmodules_usage PROTO((void));
|
||||
static void rename_rcsfile PROTO((char *temp, char *real));
|
||||
|
||||
#ifndef MY_NDBM
|
||||
static void rename_dbmfile (char *temp);
|
||||
static void write_dbmfile (char *temp);
|
||||
static void rename_dbmfile PROTO((char *temp));
|
||||
static void write_dbmfile PROTO((char *temp));
|
||||
#endif /* !MY_NDBM */
|
||||
|
||||
#else /* !__STDC__ */
|
||||
|
||||
static void make_tempfile ();
|
||||
static int checkout_file ();
|
||||
static void rename_rcsfile ();
|
||||
static void mkmodules_usage ();
|
||||
|
||||
#ifndef MY_NDBM
|
||||
static void write_dbmfile ();
|
||||
static void rename_dbmfile ();
|
||||
#endif /* !MY_NDBM */
|
||||
|
||||
#endif /* __STDC__ */
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
@ -62,15 +46,34 @@ main (argc, argv)
|
||||
{
|
||||
extern char *getenv ();
|
||||
char temp[PATH_MAX];
|
||||
char *cp;
|
||||
char *cp, *last, *fname;
|
||||
#ifdef MY_NDBM
|
||||
DBM *db;
|
||||
#endif
|
||||
FILE *fp;
|
||||
char line[512];
|
||||
static struct _checkout_file {
|
||||
char *filename;
|
||||
char *errormsg;
|
||||
} *fileptr, filelist[] = {
|
||||
{CVSROOTADM_LOGINFO,
|
||||
"no logging of 'cvs commit' messages is done without a %s file"},
|
||||
{CVSROOTADM_RCSINFO,
|
||||
"a %s file can be used to configure 'cvs commit' templates"},
|
||||
{CVSROOTADM_EDITINFO,
|
||||
"a %s file can be used to validate log messages"},
|
||||
{CVSROOTADM_COMMITINFO,
|
||||
"a %s file can be used to configure 'cvs commit' checking"},
|
||||
{CVSROOTADM_IGNORE,
|
||||
"a %s file can be used to specify files to ignore"},
|
||||
{CVSROOTADM_CHECKOUTLIST,
|
||||
"a %s file can specify extra CVSROOT files to auto-checkout"},
|
||||
{NULL, NULL}};
|
||||
|
||||
/*
|
||||
* Just save the last component of the path for error messages
|
||||
*/
|
||||
if ((program_name = rindex (argv[0], '/')) == NULL)
|
||||
if ((program_name = strrchr (argv[0], '/')) == NULL)
|
||||
program_name = argv[0];
|
||||
else
|
||||
program_name++;
|
||||
@ -135,57 +138,63 @@ main (argc, argv)
|
||||
|
||||
(void) unlink_file (temp);
|
||||
|
||||
/*
|
||||
* Now, check out the "loginfo" file, so that it is always up-to-date in
|
||||
* the CVSROOT directory.
|
||||
*/
|
||||
/* Checkout the files that need it in CVSROOT dir */
|
||||
for (fileptr = filelist; fileptr && fileptr->filename; fileptr++) {
|
||||
make_tempfile (temp);
|
||||
if (checkout_file (CVSROOTADM_LOGINFO, temp) == 0)
|
||||
rename_rcsfile (temp, CVSROOTADM_LOGINFO);
|
||||
else
|
||||
error (0, 0,
|
||||
"no logging of 'cvs commit' messages is done without a %s file",
|
||||
CVSROOTADM_LOGINFO);
|
||||
if (checkout_file (fileptr->filename, temp) == 0)
|
||||
rename_rcsfile (temp, fileptr->filename);
|
||||
#if 0
|
||||
/*
|
||||
* If there was some problem other than the file not existing,
|
||||
* checkout_file already printed a real error message. If the
|
||||
* file does not exist, it is harmless--it probably just means
|
||||
* that the repository was created with an old version of CVS
|
||||
* which didn't have so many files in CVSROOT.
|
||||
*/
|
||||
else if (fileptr->errormsg)
|
||||
error (0, 0, fileptr->errormsg, fileptr->filename);
|
||||
#endif
|
||||
(void) unlink_file (temp);
|
||||
}
|
||||
|
||||
/* Use 'fopen' instead of 'open_file' because we want to ignore error */
|
||||
fp = fopen (CVSROOTADM_CHECKOUTLIST, "r");
|
||||
if (fp)
|
||||
{
|
||||
/*
|
||||
* Now, check out the "rcsinfo" file, so that it is always up-to-date in
|
||||
* the CVSROOT directory.
|
||||
* File format:
|
||||
* [<whitespace>]<filename><whitespace><error message><end-of-line>
|
||||
*/
|
||||
make_tempfile (temp);
|
||||
if (checkout_file (CVSROOTADM_RCSINFO, temp) == 0)
|
||||
rename_rcsfile (temp, CVSROOTADM_RCSINFO);
|
||||
else
|
||||
error (0, 0,
|
||||
"a %s file can be used to configure 'cvs commit' templates",
|
||||
CVSROOTADM_RCSINFO);
|
||||
(void) unlink_file (temp);
|
||||
for (; fgets (line, sizeof (line), fp) != NULL;)
|
||||
{
|
||||
if ((last = strrchr (line, '\n')) != NULL)
|
||||
*last = '\0'; /* strip the newline */
|
||||
|
||||
/*
|
||||
* Now, check out the "editinfo" file, so that it is always up-to-date in
|
||||
* the CVSROOT directory.
|
||||
*/
|
||||
make_tempfile (temp);
|
||||
if (checkout_file (CVSROOTADM_EDITINFO, temp) == 0)
|
||||
rename_rcsfile (temp, CVSROOTADM_EDITINFO);
|
||||
else
|
||||
error (0, 0,
|
||||
"a %s file can be used to validate log messages",
|
||||
CVSROOTADM_EDITINFO);
|
||||
(void) unlink_file (temp);
|
||||
/* Skip leading white space. */
|
||||
for (fname = line; *fname && isspace(*fname); fname++)
|
||||
;
|
||||
|
||||
/* Find end of filename. */
|
||||
for (cp = fname; *cp && !isspace(*cp); cp++)
|
||||
;
|
||||
*cp = '\0';
|
||||
|
||||
/*
|
||||
* Now, check out the "commitinfo" file, so that it is always up-to-date
|
||||
* in the CVSROOT directory.
|
||||
*/
|
||||
make_tempfile (temp);
|
||||
if (checkout_file (CVSROOTADM_COMMITINFO, temp) == 0)
|
||||
rename_rcsfile (temp, CVSROOTADM_COMMITINFO);
|
||||
if (checkout_file (fname, temp) == 0)
|
||||
{
|
||||
rename_rcsfile (temp, fname);
|
||||
}
|
||||
else
|
||||
error (0, 0,
|
||||
"a %s file can be used to configure 'cvs commit' checking",
|
||||
CVSROOTADM_COMMITINFO);
|
||||
(void) unlink_file (temp);
|
||||
{
|
||||
for (cp++; cp < last && *last && isspace(*last); cp++)
|
||||
;
|
||||
if (cp < last && *cp)
|
||||
error (0, 0, cp, fname);
|
||||
}
|
||||
}
|
||||
(void) fclose (fp);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -251,7 +260,7 @@ write_dbmfile (temp)
|
||||
error (1, errno, "cannot open dbm file %s for creation", temp);
|
||||
for (cont = 0; fgets (line, sizeof (line), fp) != NULL;)
|
||||
{
|
||||
if ((cp = rindex (line, '\n')) != NULL)
|
||||
if ((cp = strrchr (line, '\n')) != NULL)
|
||||
*cp = '\0'; /* strip the newline */
|
||||
|
||||
/*
|
||||
@ -370,8 +379,15 @@ rename_rcsfile (temp, real)
|
||||
char *real;
|
||||
{
|
||||
char bak[50];
|
||||
struct stat statbuf;
|
||||
char rcs[PATH_MAX];
|
||||
|
||||
if (chmod (temp, 0444) < 0) /* chmod 444 "temp" */
|
||||
/* Set "x" bits if set in original. */
|
||||
(void) sprintf (rcs, "%s%s", real, RCSEXT);
|
||||
statbuf.st_mode = 0; /* in case rcs file doesn't exist, but it should... */
|
||||
(void) stat (rcs, &statbuf);
|
||||
|
||||
if (chmod (temp, 0444 | (statbuf.st_mode & 0111)) < 0)
|
||||
error (0, errno, "warning: cannot chmod %s", temp);
|
||||
(void) sprintf (bak, "%s%s", BAKPREFIX, real);
|
||||
(void) unlink_file (bak); /* rm .#loginfo */
|
||||
|
Loading…
Reference in New Issue
Block a user