Original sources from CVS-1.4A2 munged to fit our directory structure.
This commit is contained in:
parent
36d59faf6a
commit
33afdd16ab
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/cvs/dist/; revision=7514
@ -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
|
This "contrib" directory is a place holder for code/scripts sent to
|
||||||
me by contributors around the world. This READM file will be kept
|
me by contributors around the world. This READM file will be kept
|
||||||
@ -66,3 +66,22 @@ Contents of this directory:
|
|||||||
$CVSROOT/CVSROOT/history file, as it can grow quite
|
$CVSROOT/CVSROOT/history file, as it can grow quite
|
||||||
large after extended use.
|
large after extended use.
|
||||||
Contributed by David G. Grubbs <dgg@ksr.com>
|
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-*-
|
#!/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>
|
# Contributed by David G. Grubbs <dgg@ksr.com>
|
||||||
#
|
#
|
||||||
# Clean up the history file. 10 Record types: MAR OFT WUCG
|
# Clean up the history file. 10 Record types: MAR OFT WUCG
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/perl -- # -*-Perl-*-
|
#!/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)
|
# Access control lists for CVS. dgg@ksr.com (David G. Grubbs)
|
||||||
#
|
#
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#! /bin/sh
|
#! /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
|
# cvscheck - identify files added, changed, or removed
|
||||||
# in CVS working directory
|
# 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>
|
.\" Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
|
||||||
.TH CVSCHECK LOCAL "4 March 1991" FLUKE
|
.TH CVSCHECK LOCAL "4 March 1991" FLUKE
|
||||||
.SH NAME
|
.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>
|
.\" Contributed by Lowell Skoog <fluke!lowell@uunet.uu.net>
|
||||||
.\" Full space in nroff; half space in troff
|
.\" Full space in nroff; half space in troff
|
||||||
.de SP
|
.de SP
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#! /bin/sh
|
#! /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
|
# 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"
|
.TH DESCEND 1 "31 March 1992"
|
||||||
.SH NAME
|
.SH NAME
|
||||||
descend \- walk directory tree and execute a command at each node
|
descend \- walk directory tree and execute a command at each node
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/perl
|
#!/usr/bin/perl
|
||||||
#
|
#
|
||||||
# Support for importing a source collection into CVS.
|
# Support for importing a source collection into CVS.
|
||||||
# Trys to prevent the user from the most common pitfalls (like creating
|
# Tries to prevent the user from the most common pitfalls (like creating
|
||||||
# new top-level repositories or second-level areas accidentally), and
|
# new top-level repositories or second-level areas accidentally), and
|
||||||
# cares to do some of the `dirty' work like maintaining the modules
|
# cares to do some of the `dirty' work like maintaining the modules
|
||||||
# database accordingly.
|
# database accordingly.
|
||||||
@ -10,8 +10,22 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
require "complete.pl";
|
require "complete.pl";
|
||||||
|
require "getopts.pl";
|
||||||
|
|
||||||
|
|
||||||
|
sub scan_opts
|
||||||
|
{
|
||||||
|
&Getopts("n");
|
||||||
|
|
||||||
|
$dont_do_it = "-n" if $opt_n;
|
||||||
|
|
||||||
|
die "usage: $0 [-n] [moduledir]\n" .
|
||||||
|
" -n: don't do any commit, show only\n"
|
||||||
|
unless $#ARGV <= 0;
|
||||||
|
|
||||||
|
$moduledir = $ARGV[0] if $#ARGV == 0;
|
||||||
|
}
|
||||||
|
|
||||||
sub lsdir
|
sub lsdir
|
||||||
{
|
{
|
||||||
# find all subdirectories under @_
|
# find all subdirectories under @_
|
||||||
@ -165,12 +179,29 @@ sub checktag
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
&scan_opts;
|
||||||
&term_init;
|
&term_init;
|
||||||
&cvs_init;
|
&cvs_init;
|
||||||
|
|
||||||
|
if(! $moduledir) {
|
||||||
|
@dirs = &lsdir(".");
|
||||||
|
print "${so}Import from which directory?${se}\n";
|
||||||
|
@dirs = (@dirs, ".");
|
||||||
|
&list(@dirs);
|
||||||
|
$moduledir = &Complete("Which? [.]: ", @dirs);
|
||||||
|
$moduledir = "." unless $moduledir ne "";
|
||||||
|
}
|
||||||
|
|
||||||
|
chdir $moduledir || die "Cannot chdir to $moduledir\n";
|
||||||
|
|
||||||
print "${so}Available repositories:${se}\n";
|
print "${so}Available repositories:${se}\n";
|
||||||
&list(@reps);
|
&list(@reps);
|
||||||
|
|
||||||
|
# the following kludge prevents the Complete package from starting
|
||||||
|
# over with the string just selected; Complete should better provide
|
||||||
|
# some reinitialize method
|
||||||
|
$Complete'return = ""; $Complete'r = 0;
|
||||||
|
|
||||||
$selected =
|
$selected =
|
||||||
&Complete("Enter repository (<TAB>=complete, ^D=show): ",
|
&Complete("Enter repository (<TAB>=complete, ^D=show): ",
|
||||||
@reps);
|
@reps);
|
||||||
@ -188,9 +219,6 @@ print "\n${so}Selected repository:${se} ${us}$rep${ue}\n";
|
|||||||
print "${so}Existent areas in this repository:${se}\n";
|
print "${so}Existent areas in this repository:${se}\n";
|
||||||
&list(@areas);
|
&list(@areas);
|
||||||
|
|
||||||
# the following kludge prevents the Complete package from starting
|
|
||||||
# over with the string just selected; Complete should better provide
|
|
||||||
# some reinitialize method
|
|
||||||
$Complete'return = ""; $Complete'r = 0;
|
$Complete'return = ""; $Complete'r = 0;
|
||||||
|
|
||||||
$selected =
|
$selected =
|
||||||
@ -304,21 +332,34 @@ system("cvs co modules") && die "${us}failed.\n${ue}";
|
|||||||
|
|
||||||
print "${so}Inserting new module...${se}\n";
|
print "${so}Inserting new module...${se}\n";
|
||||||
open(ED, "|ed modules/modules") || die "${us}Cannot start ed${ue}\n";
|
open(ED, "|ed modules/modules") || die "${us}Cannot start ed${ue}\n";
|
||||||
print(ED "${cmd}${modname}" . ' ' x (32 - length($modname)) .
|
print(ED "${cmd}${modname}" . ' ' x (16 - length($modname)) .
|
||||||
"$area/${modpath}\n.\nw\nq\n");
|
"$area/${modpath}\n.\nw\nq\n");
|
||||||
close(ED);
|
close(ED);
|
||||||
|
|
||||||
print "${so}Commiting new modules database...${se}\n";
|
print "${so}Commiting new modules database...${se}\n";
|
||||||
system("cvs commit -m \" ${modname} --> $area/${modpath}\" modules")
|
system("cvs $dont_do_it commit -m \" " .
|
||||||
|
"${modname} --> $area/${modpath}\" modules")
|
||||||
&& die "Commit failed\n";
|
&& die "Commit failed\n";
|
||||||
|
|
||||||
system("cvs release -dQ modules");
|
system("cvs $dont_do_it release -dQ modules");
|
||||||
|
|
||||||
print "${so}Importing source. Enter a commit message in the editor.${se}\n";
|
print "${so}Importing source. Enter a commit message in the editor.${se}\n";
|
||||||
|
|
||||||
system("cvs import $area/$modpath $vtag $rtag");
|
system("cvs $dont_do_it import $area/$modpath $vtag $rtag");
|
||||||
|
|
||||||
print "${so}You are done now. Go to a different directory, perform a${se}\n".
|
print "${so}You are done now. Go to a different directory, perform a${se}\n".
|
||||||
"${us}cvs co ${modname}${ue} ${so}command, and see if your new module" .
|
"${us}cvs co ${modname}${ue} ${so}command, and see if your new module" .
|
||||||
" builds ok.${se}\n";
|
" builds ok.${se}\n";
|
||||||
|
|
||||||
|
if($dont_do_it) {
|
||||||
|
print <<END
|
||||||
|
|
||||||
|
|
||||||
|
${so}Since you did not allow to commit anything, you'll have${se}
|
||||||
|
${so}to remove the edited modules' database yourself.${se}
|
||||||
|
${so}To do this, perform a${se}
|
||||||
|
${us}cd ${moduledir}; cvs release -dQ modules${ue}
|
||||||
|
${so}command.${se}
|
||||||
|
END
|
||||||
|
;
|
||||||
|
}
|
||||||
|
@ -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
|
# Modified by berliner@Sun.COM to add support for CVS 1.3 2/27/92
|
||||||
#
|
#
|
||||||
# Date: Tue, 6 Aug 91 13:27 EDT
|
# Date: Tue, 6 Aug 91 13:27 EDT
|
||||||
@ -11,94 +15,134 @@
|
|||||||
# now the output looks like this:
|
# now the output looks like this:
|
||||||
#
|
#
|
||||||
# **************************************
|
# **************************************
|
||||||
# date: Tuesday, August 6, 1991 @ 13:17
|
# Date: Tuesday, August 6, 1991 @ 13:17
|
||||||
# author: samborn
|
# Author: samborn
|
||||||
|
#
|
||||||
# Update of /elmer/cvs/CVSROOT.adm
|
# Update of /elmer/cvs/CVSROOT.adm
|
||||||
# In directory astro:/home/samborn/CVSROOT.adm
|
# In directory astro:/home/samborn/CVSROOT.adm
|
||||||
#
|
#
|
||||||
# Modified Files:
|
# Modified Files:
|
||||||
# test3
|
# test3
|
||||||
#
|
|
||||||
# Added Files:
|
# Added Files:
|
||||||
# test6
|
# test6
|
||||||
#
|
|
||||||
# Removed Files:
|
# Removed Files:
|
||||||
# test4
|
# test4
|
||||||
#
|
|
||||||
# Log Message:
|
# Log Message:
|
||||||
# wow, what a test
|
# wow, what a test
|
||||||
#
|
#
|
||||||
# RCS: 1.4 /elmer/cvs/CVSROOT.adm/test3,v
|
# File: test.3 Status: Up-to-date
|
||||||
# RCS: 1.1 /elmer/cvs/CVSROOT.adm/test6,v
|
# Version: 1.4 Thu Apr 29 14:47:07 EDT 1993
|
||||||
# RCS: 1.1 /elmer/cvs/CVSROOT.adm/Attic/test4,v
|
# 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
|
# turn off setgid
|
||||||
#
|
#
|
||||||
$) = $(;
|
$) = $(;
|
||||||
|
|
||||||
#
|
|
||||||
# parse command line arguments
|
# parse command line arguments
|
||||||
#
|
#
|
||||||
@files = split(/ /,$ARGV[0]);
|
while (@ARGV) {
|
||||||
$logfile = $ARGV[1];
|
$arg = shift @ARGV;
|
||||||
$cvsroot = $ENV{'CVSROOT'};
|
|
||||||
|
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
|
# Some date and time arrays
|
||||||
#
|
#
|
||||||
@mos = (January,February,March,April,May,June,July,August,September,
|
@mos = (January,February,March,April,May,June,July,August,September,
|
||||||
October,November,December);
|
October,November,December);
|
||||||
@days = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
|
@days = (Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday);
|
||||||
|
|
||||||
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime;
|
||||||
|
|
||||||
#
|
|
||||||
# get login name
|
# get login name
|
||||||
#
|
#
|
||||||
$login = getlogin || (getpwuid($<))[0] || "nobody";
|
$login = getlogin || (getpwuid($<))[0] || "nobody";
|
||||||
|
|
||||||
#
|
|
||||||
# open log file for appending
|
# open log file for appending
|
||||||
#
|
#
|
||||||
if ((open(OUT, ">>" . $logfile)) != 1) {
|
open(OUT, ">>" . $logfile) || die "Could not open(" . $logfile . "): $!\n";
|
||||||
die "Could not open logfile " . $logfile . "\n";
|
if ($users) {
|
||||||
|
$mailcmd = "$mailcmd $users";
|
||||||
|
open(MAIL, $mailcmd) || die "Could not Exec($mailcmd): $!\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
# print out the log Header
|
||||||
# Header
|
|
||||||
#
|
#
|
||||||
print OUT "\n";
|
print OUT "\n";
|
||||||
print OUT "**************************************\n";
|
print OUT "**************************************\n";
|
||||||
print OUT "date: " . $days[$wday] . ", " . $mos[$mon] . " " . $mday . ", 19" . $year .
|
print OUT "Date:\t$days[$wday] $mos[$mon] $mday, 19$year @ $hour:" . sprintf("%02d", $min) . "\n";
|
||||||
" @ " . $hour . ":" . sprintf("%02d", $min) . "\n";
|
print OUT "Author:\t$login\n\n";
|
||||||
print OUT "author: " . $login . "\n";
|
|
||||||
|
|
||||||
#
|
if (MAIL) {
|
||||||
#print the stuff on stdin to the logfile
|
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, "-");
|
open(IN, "-");
|
||||||
while(<IN>) {
|
while (<IN>) {
|
||||||
print OUT $_;
|
print OUT $_;
|
||||||
|
if (MAIL) {
|
||||||
|
print MAIL $_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
close(IN);
|
close(IN);
|
||||||
|
|
||||||
print OUT "\n";
|
print OUT "\n";
|
||||||
|
|
||||||
#
|
|
||||||
# after log information, do an 'cvs -Qn status' on each file in the arguments.
|
# after log information, do an 'cvs -Qn status' on each file in the arguments.
|
||||||
#
|
#
|
||||||
for $file (@files[1..$#files]) {
|
while (@files) {
|
||||||
if ($file eq "-") {
|
$file = shift @files;
|
||||||
last;
|
if ($file eq "-") {
|
||||||
}
|
print OUT "[input file was '-']\n";
|
||||||
open(RCS,"-|") || exec 'cvs', '-Qn', 'status', $file;
|
if (MAIL) {
|
||||||
while (<RCS>) {
|
print MAIL "[input file was '-']\n";
|
||||||
if (substr($_, 0, 7) eq " RCS") {
|
}
|
||||||
print OUT;
|
last;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
close (RCS);
|
open(RCS, "-|") || exec 'cvs', '-Qn', 'status', $file;
|
||||||
|
|
||||||
|
while (<RCS>) {
|
||||||
|
if (/^[ \t]*Version/ || /^File:/) {
|
||||||
|
print OUT;
|
||||||
|
if (MAIL) {
|
||||||
|
print MAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
close(RCS);
|
||||||
}
|
}
|
||||||
|
|
||||||
close (OUT);
|
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
|
# Especially if they regularly beat on the same directory. Anyway if you
|
||||||
# think anyone would be interested here it is.
|
# 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
|
# 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)
|
Tue Apr 7 09:11:27 1992 Per Cederqvist (ceder@leopold)
|
||||||
|
|
||||||
* Release 1.02.
|
* Release 1.02.
|
||||||
|
@ -3,47 +3,51 @@ This text is copied from the TeXinfo manual for pcl-cvs.
|
|||||||
Installation of the pcl-cvs program
|
Installation of the pcl-cvs program
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
1. Edit the file `Makefile' to reflect the situation at your site.
|
1. Edit the file `Makefile' to reflect the situation at your site.
|
||||||
The only things you have to change is the definition of
|
The only things you have to change is the definition of `lispdir'
|
||||||
`lispdir' and `infodir'. The elisp files will be copied to
|
and `infodir'. The elisp files will be copied to `lispdir', and
|
||||||
`lispdir', and the info file to `infodir'.
|
the info file to `infodir'.
|
||||||
|
|
||||||
2. Configure pcl-cvs.el
|
2. Configure pcl-cvs.el
|
||||||
|
|
||||||
There are a couple of paths that you have to check to make
|
There are a couple of paths that you have to check to make sure
|
||||||
sure that they match you system. They appear early in the file
|
that they match you system. They appear early in the file
|
||||||
pcl-cvs.el.
|
pcl-cvs.el.
|
||||||
|
|
||||||
*NOTE:* If your system is running emacs 18.57 or earlier
|
*NOTE:* If your system is running emacs 18.57 or earlier you
|
||||||
you MUST uncomment the line that says:
|
MUST uncomment the line that says:
|
||||||
|
|
||||||
(setq delete-exited-processes nil)
|
(setq delete-exited-processes nil)
|
||||||
|
|
||||||
Setting `delete-exited-processes' to `nil' works around a bug
|
Setting `delete-exited-processes' to `nil' works around a bug in
|
||||||
in emacs that causes it to dump core. The bug was fixed in
|
emacs that causes it to dump core. The bug was fixed in emacs
|
||||||
emacs 18.58.
|
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
|
byte-compile all `.el' files and copy both the `.el' and the
|
||||||
`.elc' into the directory you specified in step 1.
|
`.elc' into the directory you specified in step 1.
|
||||||
|
|
||||||
If you don't want to install the `.el' files but only the
|
If you don't want to install the `.el' files but only the `.elc'
|
||||||
`.elc' files (the byte-compiled files), you can type ``make
|
files (the byte-compiled files), you can type ``make
|
||||||
install_elc'' instead of ``make install''.
|
install_elc'' instead of ``make install''.
|
||||||
|
|
||||||
If you only want to create the compiled elisp files, but
|
If you only want to create the compiled elisp files, but don't
|
||||||
don't want to install them, you can type `make elcfiles'
|
want to install them, you can type `make elcfiles' instead.
|
||||||
instead. This is what happens if you only type `make' without
|
This is what happens if you only type `make' without parameters.
|
||||||
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
|
`/usr/gnu/emacs/lisp' or something similar) and enter the
|
||||||
contents of the file `pcl-cvs-startup.el' into it. It contains
|
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.
|
a couple of `auto-load's that facilitates the use of pcl-cvs.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Installation of the on-line manual.
|
Installation of the on-line manual.
|
||||||
===================================
|
===================================
|
||||||
|
|
||||||
@ -55,7 +59,7 @@ Installation of the on-line manual.
|
|||||||
info file `pcl-cvs.info' that is included in the distribution
|
info file `pcl-cvs.info' that is included in the distribution
|
||||||
(type `cp pcl-cvs.info pcl-cvs').
|
(type `cp pcl-cvs.info pcl-cvs').
|
||||||
|
|
||||||
2. Move the info file `pcl-cvs' to your standard info directory.
|
2. Move the info file `pcl-cvs' to your standard info directory.
|
||||||
This might be called something like `/usr/gnu/emacs/info'.
|
This might be called something like `/usr/gnu/emacs/info'.
|
||||||
|
|
||||||
3. Edit the file `dir' in the info directory and enter one line to
|
3. Edit the file `dir' in the info directory and enter one line to
|
||||||
@ -65,8 +69,6 @@ Installation of the on-line manual.
|
|||||||
* Pcl-cvs: (pcl-cvs). An Emacs front-end to CVS.
|
* Pcl-cvs: (pcl-cvs). An Emacs front-end to CVS.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
How to make typeset documentation from pcl-cvs.texinfo
|
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.
|
postscript printer there is a program, `dvi2ps', which does.
|
||||||
There is also a program which comes together with TeX, `dvips',
|
There is also a program which comes together with TeX, `dvips',
|
||||||
which you can use.
|
which you can use.
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# Makefile,v 1.2 1992/04/07 20:49:07 berliner Exp
|
# @(#) Id: dist-makefile,v 1.19 1993/05/31 22:43:45 ceder Exp
|
||||||
# Makefile for pcl-cvs release 1.02.
|
# Makefile for pcl-cvs release 1.05.
|
||||||
# Copyright (C) 1992 Per Cederqvist
|
# Copyright (C) 1992, 1993 Per Cederqvist
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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
|
# 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
|
prefix=/usr/local
|
||||||
infodir = $(prefix)/info
|
infodir = $(prefix)/info
|
||||||
|
|
||||||
|
# Used to byte-compile files.
|
||||||
|
|
||||||
|
EMACS=emacs
|
||||||
|
|
||||||
#
|
#
|
||||||
# The rest of this file should not need to be modified.
|
# The rest of this file should not need to be modified.
|
||||||
#
|
#
|
||||||
@ -33,8 +37,8 @@ infodir = $(prefix)/info
|
|||||||
# Just in case...
|
# Just in case...
|
||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
ELFILES = pcl-cvs.el cookie.el elib-dll.el elib-node.el
|
ELFILES = pcl-cvs.el pcl-cvs-lucid.el
|
||||||
ELCFILES = pcl-cvs.elc cookie.elc elib-dll.elc elib-node.elc
|
ELCFILES = pcl-cvs.elc pcl-cvs-lucid.elc
|
||||||
INFOFILES = pcl-cvs
|
INFOFILES = pcl-cvs
|
||||||
TEXTMPS = pcl-cvs.aux pcl-cvs.log pcl-cvs.toc pcl-cvs.dvi pcl-cvs.cp \
|
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 \
|
pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky pcl-cvs.pg \
|
||||||
@ -45,7 +49,7 @@ INSTALL = install
|
|||||||
INSTALL_DATA = $(INSTALL)
|
INSTALL_DATA = $(INSTALL)
|
||||||
|
|
||||||
elcfiles:
|
elcfiles:
|
||||||
emacs -batch -l ./compile-all.el -f compile-pcl-cvs
|
$(EMACS) -batch -l ./compile-all.el -f compile-pcl-cvs
|
||||||
|
|
||||||
all: elcfiles info
|
all: elcfiles info
|
||||||
|
|
||||||
@ -66,6 +70,7 @@ info pcl-cvs: pcl-cvs.texinfo
|
|||||||
makeinfo +fill-column=70 pcl-cvs.texinfo
|
makeinfo +fill-column=70 pcl-cvs.texinfo
|
||||||
|
|
||||||
pcl-cvs.dvi: pcl-cvs.texinfo
|
pcl-cvs.dvi: pcl-cvs.texinfo
|
||||||
|
tex 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 \
|
-texindex pcl-cvs.cp pcl-cvs.fn pcl-cvs.vr pcl-cvs.tp pcl-cvs.ky \
|
||||||
pcl-cvs.pg
|
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
|
Pcl-cvs is a front-end to CVS version 1.3. It integrates the most
|
||||||
frequently used CVS commands into emacs.
|
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.
|
it to work. See the instructions in file INSTALL.
|
||||||
|
|
||||||
Full documentation is in pcl-cvs.texinfo. Since it requires makeinfo
|
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
|
;;;; @(#) 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.02.
|
;;;; This file byte-compiles all .el files in pcl-cvs release 1.05.
|
||||||
;;;;
|
;;;;
|
||||||
;;;; Copyright (C) 1991 Inge Wallin
|
;;;; 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
|
;;;; 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
|
;;;; it under the terms of the GNU General Public License as published by
|
||||||
@ -21,14 +22,11 @@
|
|||||||
;;;;
|
;;;;
|
||||||
|
|
||||||
|
|
||||||
(setq elib-files '("elib-node"
|
(setq files-to-compile '("pcl-cvs" "pcl-cvs-lucid"))
|
||||||
"elib-dll"
|
|
||||||
"cookie"
|
|
||||||
"pcl-cvs"))
|
|
||||||
|
|
||||||
|
|
||||||
(defun compile-file-if-necessary (file)
|
(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."
|
This is done if FILE.el is newer than FILE.elc or if FILE.elc doesn't exist."
|
||||||
(let ((el-name (concat file ".el"))
|
(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 ()
|
(defun compile-pcl-cvs ()
|
||||||
"Byte-compile all uncompiled files of elib.
|
"Byte-compile all uncompiled files of pcl-cvs."
|
||||||
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."
|
|
||||||
|
|
||||||
(interactive)
|
(interactive)
|
||||||
(setq load-path (append '(".") load-path))
|
|
||||||
(mapcar (function compile-file-if-necessary)
|
;; Be sure to have . in load-path since a number of files
|
||||||
elib-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)
|
||||||
|
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"
|
(autoload 'cvs-update "pcl-cvs"
|
||||||
"Run a 'cvs update' in the current working directory. Feed the
|
"Run a 'cvs update' in the current working directory. Feed the
|
||||||
output to a *cvs* buffer and run cvs-mode on it.
|
output to a *cvs* buffer and run cvs-mode on it.
|
||||||
If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
|
If optional prefix argument LOCAL is non-nil, 'cvs update -l' is run."
|
||||||
t)
|
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-*-
|
\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 Documentation for the GNU Emacs CVS mode.
|
||||||
@comment Copyright (C) 1992 Per Cederqvist
|
@comment Copyright (C) 1992 Per Cederqvist
|
||||||
|
|
||||||
@ -62,12 +62,12 @@ Free Software Foundation instead of in the original English.
|
|||||||
@sp
|
@sp
|
||||||
@center @titlefont{pcl-cvs - the Emacs Front-End to CVS}
|
@center @titlefont{pcl-cvs - the Emacs Front-End to CVS}
|
||||||
@sp 2
|
@sp 2
|
||||||
@center release 1.02
|
@center release 1.05
|
||||||
@comment -release-
|
@comment -release-
|
||||||
@sp 3
|
@sp 3
|
||||||
@center Per Cederqvist
|
@center Per Cederqvist
|
||||||
@sp 3
|
@sp 3
|
||||||
@center last updated 29 Mar 1992
|
@center last updated 31 May 1993
|
||||||
@comment -date-
|
@comment -date-
|
||||||
|
|
||||||
@comment The following two commands start the copyright page
|
@comment The following two commands start the copyright page
|
||||||
@ -104,7 +104,7 @@ Free Software Foundation instead of in the original English.
|
|||||||
@ifinfo
|
@ifinfo
|
||||||
This info manual describes pcl-cvs which is a GNU Emacs front-end to
|
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
|
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
|
@end ifinfo
|
||||||
@comment -release-
|
@comment -release-
|
||||||
|
|
||||||
@ -119,9 +119,8 @@ 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.
|
* Customization:: How you can tailor pcl-cvs to suit your needs.
|
||||||
* Future enhancements:: Future enhancements of pcl-cvs.
|
* 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.
|
||||||
* Function and Variable Index:: List of functions and variables.
|
|
||||||
* Concept Index:: List of concepts.
|
* Concept Index:: List of concepts.
|
||||||
* Key Index:: List of keystrokes.
|
* Key Index:: List of keystrokes.
|
||||||
|
|
||||||
@ -129,7 +128,7 @@ CVS. It works with CVS version 1.3. This manual is updated to release
|
|||||||
|
|
||||||
Installation
|
Installation
|
||||||
|
|
||||||
* Pcl-cvs installation:: How to install pcl-cvs on your system.
|
* Pcl-cvs installation:: How to install pcl-cvs on your system.
|
||||||
* On-line manual installation:: How to install the on-line manual.
|
* On-line manual installation:: How to install the on-line manual.
|
||||||
* Typeset manual installation:: How to create typeset documentation
|
* Typeset manual installation:: How to create typeset documentation
|
||||||
about pcl-cvs.
|
about pcl-cvs.
|
||||||
@ -155,9 +154,13 @@ Commands
|
|||||||
* Editing files:: Loading files into Emacs.
|
* Editing files:: Loading files into Emacs.
|
||||||
* Getting info about files:: Display the log and status of files.
|
* Getting info about files:: Display the log and status of files.
|
||||||
* Adding and removing files:: Adding and removing files
|
* Adding and removing files:: Adding and removing files
|
||||||
|
* Undoing changes:: Undoing changes
|
||||||
* Removing handled entries:: Uninteresting lines can easily be removed.
|
* Removing handled entries:: Uninteresting lines can easily be removed.
|
||||||
* Ignoring files:: Telling CVS to ignore generated files.
|
* Ignoring files:: Telling CVS to ignore generated files.
|
||||||
* Viewing differences:: Commands to @samp{diff} different versions.
|
* Viewing differences:: Commands to @samp{diff} different versions.
|
||||||
|
* Emerge::
|
||||||
|
* Reverting your buffers:: Reverting your buffers
|
||||||
|
* Miscellaneous commands:: Miscellaneous commands
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Copying, Installation, Top, Top
|
@node Copying, Installation, Top, Top
|
||||||
@ -565,7 +568,7 @@ steps are also described in the file @file{INSTALL} in the source
|
|||||||
directory.
|
directory.
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Pcl-cvs installation:: How to install pcl-cvs on your system.
|
* Pcl-cvs installation:: How to install pcl-cvs on your system.
|
||||||
* On-line manual installation:: How to install the on-line manual.
|
* On-line manual installation:: How to install the on-line manual.
|
||||||
* Typeset manual installation:: How to create typeset documentation
|
* Typeset manual installation:: How to create typeset documentation
|
||||||
about pcl-cvs.
|
about pcl-cvs.
|
||||||
@ -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
|
in emacs that causes it to dump core. The bug was fixed in emacs
|
||||||
18.58.@refill
|
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
|
@item
|
||||||
Type @samp{make install} in the source directory. This will
|
Type @samp{make install} in the source directory. This will
|
||||||
byte-compile all @file{.el} files and copy both the @file{.el} and the
|
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
|
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
|
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.
|
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
|
Linus Tolke (@samp{linus@@lysator.liu.se}) contributed useful comments
|
||||||
on both the functionality and the documentation.@refill
|
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
|
@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
|
@node Archives, , Contributors, About pcl-cvs
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@ -736,11 +755,6 @@ on both the functionality and the documentation.@refill
|
|||||||
@cindex Getting pcl-cvs
|
@cindex Getting pcl-cvs
|
||||||
@cindex Email archives
|
@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
|
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{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
|
@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
|
you invoke it you must have a copy of a module somewhere in the file
|
||||||
system.
|
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
|
responds with @samp{[No match]} your system administrator has not
|
||||||
installed pcl-cvs properly. Try @kbd{M-x load-library RET pcl-cvs RET}.
|
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
|
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:
|
@samp{*cvs*}. It might look something like this:
|
||||||
|
|
||||||
@example
|
@example
|
||||||
PCL-CVS release 1.02.
|
PCL-CVS release 1.05.
|
||||||
@comment -release-
|
@comment -release-
|
||||||
|
|
||||||
In directory /users/ceder/FOO/test:
|
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.
|
* Editing files:: Loading files into Emacs.
|
||||||
* Getting info about files:: Display the log and status of files.
|
* Getting info about files:: Display the log and status of files.
|
||||||
* Adding and removing files:: Adding and removing files
|
* Adding and removing files:: Adding and removing files
|
||||||
|
* Undoing changes:: Undoing changes
|
||||||
* Removing handled entries:: Uninteresting lines can easily be removed.
|
* Removing handled entries:: Uninteresting lines can easily be removed.
|
||||||
* Ignoring files:: Telling CVS to ignore generated files.
|
* Ignoring files:: Telling CVS to ignore generated files.
|
||||||
* Viewing differences:: Commands to @samp{diff} different versions.
|
* Viewing differences:: Commands to @samp{diff} different versions.
|
||||||
|
* Emerge::
|
||||||
|
* Reverting your buffers:: Reverting your buffers
|
||||||
|
* Miscellaneous commands:: Miscellaneous commands
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Updating the directory, Movement commands, Commands, Commands
|
@node Updating the directory, Movement commands, Commands, Commands
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@section Updating the directory
|
@section Updating the directory
|
||||||
@findex cvs-update
|
@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}
|
@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*}
|
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
|
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
|
@item g
|
||||||
This will run @samp{cvs update} again. It will always use the same
|
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
|
buffer that was used with the previous @samp{cvs update}. Give a prefix
|
||||||
argument to avoid descending into subdirectories. This runs the command
|
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
|
@end table
|
||||||
@node Movement commands, Marking files, Updating the directory, Commands
|
@node Movement commands, Marking files, Updating the directory, Commands
|
||||||
@comment node-name, next, previous, up
|
@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 a file
|
||||||
@kindex M - marking all files
|
@kindex M - marking all files
|
||||||
@kindex u - unmark a file
|
@kindex u - unmark a file
|
||||||
@kindex U - unmark all files
|
@kindex ESC DEL - unmark all files
|
||||||
@kindex DEL - unmark previous file
|
@kindex DEL - unmark previous file
|
||||||
@findex cvs-mark
|
@findex cvs-mode-mark
|
||||||
@findex cvs-unmark
|
@findex cvs-mode-unmark
|
||||||
@findex cvs-mark-all-files
|
@findex cvs-mode-mark-all-files
|
||||||
@findex cvs-unmark-all-files
|
@findex cvs-mode-unmark-all-files
|
||||||
@findex cvs-unmark-up
|
@findex cvs-mode-unmark-up
|
||||||
|
|
||||||
Pcl-cvs works on a set of @dfn{selected files} (@pxref{Selected files}).
|
Pcl-cvs works on a set of @dfn{selected files} (@pxref{Selected files}).
|
||||||
You can mark and unmark files with these commands:
|
You can mark and unmark files with these commands:
|
||||||
@ -1066,22 +1096,22 @@ You can mark and unmark files with these commands:
|
|||||||
@item m
|
@item m
|
||||||
This marks the file that the cursor is positioned on. If the cursor is
|
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.
|
positioned on a directory all files in that directory will be marked.
|
||||||
(@code{cvs-mark}).
|
(@code{cvs-mode-mark}).
|
||||||
|
|
||||||
@item u
|
@item u
|
||||||
Unmark the file that the cursor is positioned on. If the cursor is on a
|
Unmark the file that the cursor is positioned on. If the cursor is on a
|
||||||
directory, all files in that directory will be unmarked.
|
directory, all files in that directory will be unmarked.
|
||||||
(@code{cvs-unmark}).@refill
|
(@code{cvs-mode-unmark}).@refill
|
||||||
|
|
||||||
@item M
|
@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
|
@item @key{ESC} @key{DEL}
|
||||||
Unmark @emph{all} files (@code{cvs-unmark-all-files}).
|
Unmark @emph{all} files (@code{cvs-mode-unmark-all-files}).
|
||||||
|
|
||||||
@item @key{DEL}
|
@item @key{DEL}
|
||||||
Unmark the file on the previous line, and move point to that line
|
Unmark the file on the previous line, and move point to that line
|
||||||
(@code{cvs-unmark-up}).
|
(@code{cvs-mode-unmark-up}).
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@node Committing changes, Editing files, Marking files, Commands
|
@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
|
@section Committing changes
|
||||||
@cindex Committing changes
|
@cindex Committing changes
|
||||||
@cindex Ci
|
@cindex Ci
|
||||||
@findex cvs-commit
|
@findex cvs-mode-commit
|
||||||
@kindex c - commit files
|
@kindex c - commit files
|
||||||
@vindex cvs-erase-input-buffer (variable)
|
@vindex cvs-erase-input-buffer (variable)
|
||||||
|
@vindex cvs-auto-revert-after-commit (variable)
|
||||||
@cindex Commit buffer
|
@cindex Commit buffer
|
||||||
@cindex Edit buffer
|
@cindex Edit buffer
|
||||||
@cindex Erasing commit message
|
@cindex Erasing commit message
|
||||||
|
@cindex Reverting buffers after commit
|
||||||
|
|
||||||
@table @kbd
|
@table @kbd
|
||||||
@item c
|
@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
|
contents}) can be checked in with the @kbd{c} command. It checks in all
|
||||||
selected files (@pxref{Selected files}) (except those who lack the
|
selected files (@pxref{Selected files}) (except those who lack the
|
||||||
"ci"-marker - they are ignored). Pressing @kbd{c} causes
|
"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
|
When you press @kbd{c} you will get a buffer called
|
||||||
@samp{*cvs-commit-message*}. Enter the log message for the file(s) in
|
@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
|
Normally the @samp{*cvs-commit-message*} buffer will retain the log
|
||||||
message from the previous commit, but if the variable
|
message from the previous commit, but if the variable
|
||||||
@code{cvs-erase-input-buffer} is set to a non-nil value the buffer will
|
@code{cvs-erase-input-buffer} is set to a non-@code{nil} value the
|
||||||
be erased. Point and mark will always be located around the entire
|
buffer will be erased. Point and mark will always be located around the
|
||||||
buffer so that you can easily erase it with @kbd{C-w}
|
entire buffer so that you can easily erase it with @kbd{C-w}
|
||||||
(@samp{kill-region}).@refill
|
(@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
|
@end table
|
||||||
|
|
||||||
@node Editing files, Getting info about files, Committing changes, Commands
|
@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 Loading files
|
||||||
@cindex Dired
|
@cindex Dired
|
||||||
@cindex Invoking dired
|
@cindex Invoking dired
|
||||||
@findex cvs-find-file
|
@findex cvs-mode-find-file
|
||||||
@findex cvs-find-file-other-window
|
@findex cvs-mode-find-file-other-window
|
||||||
@findex cvs-add-change-log-entry-other-window
|
@findex cvs-mode-add-change-log-entry-other-window
|
||||||
@kindex f - find file or directory
|
@kindex f - find file or directory
|
||||||
@kindex o - find file in other window
|
@kindex o - find file in other window
|
||||||
@kindex A - add ChangeLog entry
|
@kindex A - add ChangeLog entry
|
||||||
@ -1144,17 +1184,17 @@ Find the file that the cursor points to. Run @samp{dired}
|
|||||||
@ifinfo
|
@ifinfo
|
||||||
(@pxref{Dired,,,Emacs})
|
(@pxref{Dired,,,Emacs})
|
||||||
@end ifinfo
|
@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
|
@item o
|
||||||
Like @kbd{f}, but use another window
|
Like @kbd{f}, but use another window
|
||||||
(@code{cvs-find-file-other-window}).@refill
|
(@code{cvs-mode-find-file-other-window}).@refill
|
||||||
|
|
||||||
@item A
|
@item A
|
||||||
Invoke @samp{add-change-log-entry-other-window} to edit a
|
Invoke @samp{add-change-log-entry-other-window} to edit a
|
||||||
@samp{ChangeLog} file. The @samp{ChangeLog} will be found in the
|
@samp{ChangeLog} file. The @samp{ChangeLog} will be found in the
|
||||||
directory of the file the cursor points to.
|
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
|
@end table
|
||||||
|
|
||||||
@node Getting info about files, Adding and removing files, Editing files, Commands
|
@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
|
@cindex Getting status
|
||||||
@kindex l - run @samp{cvs log}
|
@kindex l - run @samp{cvs log}
|
||||||
@kindex s - run @samp{cvs status}
|
@kindex s - run @samp{cvs status}
|
||||||
@findex cvs-log
|
@findex cvs-mode-log
|
||||||
@findex cvs-status
|
@findex cvs-mode-status
|
||||||
|
|
||||||
Both of the following commands can be customized.
|
Both of the following commands can be customized.
|
||||||
@xref{Customization}.@refill
|
@xref{Customization}.@refill
|
||||||
@ -1174,14 +1214,14 @@ Both of the following commands can be customized.
|
|||||||
@table @kbd
|
@table @kbd
|
||||||
@item l
|
@item l
|
||||||
Run @samp{cvs log} on all selected files, and show the result in a
|
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
|
@item s
|
||||||
Run @samp{cvs status} on all selected files, and show the result in a
|
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
|
@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
|
@comment node-name, next, previous, up
|
||||||
@section Adding and removing files
|
@section Adding and removing files
|
||||||
@cindex Adding files
|
@cindex Adding files
|
||||||
@ -1191,8 +1231,8 @@ temporary buffer (@code{cvs-status}).
|
|||||||
@cindex Putting files under CVS control
|
@cindex Putting files under CVS control
|
||||||
@kindex a - add a file
|
@kindex a - add a file
|
||||||
@kindex r - remove a file
|
@kindex r - remove a file
|
||||||
@findex cvs-add
|
@findex cvs-mode-add
|
||||||
@findex cvs-remove-file
|
@findex cvs-mode-remove-file
|
||||||
|
|
||||||
The following commands are available to make it easy to add and remove
|
The following commands are available to make it easy to add and remove
|
||||||
files from the CVS repository.
|
files from the CVS repository.
|
||||||
@ -1201,7 +1241,7 @@ files from the CVS repository.
|
|||||||
@item a
|
@item a
|
||||||
Add all selected files. This command can be used on @samp{Unknown}
|
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
|
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
|
@pxref{Committing changes}) to really add the file to the
|
||||||
repository.@refill
|
repository.@refill
|
||||||
|
|
||||||
@ -1211,7 +1251,7 @@ them) to resurrect them.
|
|||||||
Selected files that are neither @samp{Unknown} nor @samp{Removed} will
|
Selected files that are neither @samp{Unknown} nor @samp{Removed} will
|
||||||
be ignored by this command.
|
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
|
@item r
|
||||||
This command removes the selected files (after prompting for
|
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
|
(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
|
also be @samp{cvs remove}d. If the files were @samp{Unknown} they will
|
||||||
disappear from the buffer. Otherwise their status will change to
|
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
|
@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
|
@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
|
@comment node-name, next, previous, up
|
||||||
@section Removing handled entries
|
@section Removing handled entries
|
||||||
@cindex Expunging uninteresting entries
|
@cindex Expunging uninteresting entries
|
||||||
@ -1235,8 +1291,9 @@ The command that is run is @code{cvs-remove-file}.
|
|||||||
@cindex Handled lines, removing them
|
@cindex Handled lines, removing them
|
||||||
@kindex x - remove processed entries
|
@kindex x - remove processed entries
|
||||||
@kindex C-k - remove selected entries
|
@kindex C-k - remove selected entries
|
||||||
@findex cvs-remove-handled
|
@findex cvs-mode-remove-handled
|
||||||
@findex cvs-acknowledge
|
@findex cvs-mode-acknowledge
|
||||||
|
@findex cvs-mode-ignore
|
||||||
|
|
||||||
@table @kbd
|
@table @kbd
|
||||||
@item x
|
@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
|
for that directory is also removed. This makes it easier to get an
|
||||||
overview of what needs to be done.
|
overview of what needs to be done.
|
||||||
|
|
||||||
The command is called @code{cvs-remove-handled}. If
|
The command is called @code{cvs-mode-remove-handled}. If
|
||||||
@samp{cvs-auto-remove-handled} is set to non-@samp{nil} this will
|
@samp{cvs-auto-remove-handled} is set to non-@code{nil} this will
|
||||||
automatically be performed after every commit.@refill
|
automatically be performed after every commit.@refill
|
||||||
|
|
||||||
@item C-k
|
@item C-k
|
||||||
This command can be used for lines that @samp{cvs-remove-handled} would
|
This command can be used for lines that @samp{cvs-mode-remove-handled} would
|
||||||
not delete, but that you want to delete (@code{cvs-acknowledge}).
|
not delete, but that you want to delete (@code{cvs-mode-acknowledge}).
|
||||||
@end table
|
@end table
|
||||||
|
|
||||||
@node Ignoring files, Viewing differences, Removing handled entries, Commands
|
@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,
|
The @file{.cvsignore} file should normally be added to the repository,
|
||||||
but you could ignore it also if you like it better that way.
|
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
|
@end table
|
||||||
|
|
||||||
@node Viewing differences, , Ignoring files, Commands
|
@node Viewing differences, Emerge, Ignoring files, Commands
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@section Viewing differences
|
@section Viewing differences
|
||||||
@cindex Diff
|
@cindex Diff
|
||||||
@ -1280,29 +1337,122 @@ This runs @code{cvs-ignore}.
|
|||||||
@cindex Viewing differences
|
@cindex Viewing differences
|
||||||
@kindex d - run @samp{cvs diff}
|
@kindex d - run @samp{cvs diff}
|
||||||
@kindex b - diff backup file
|
@kindex b - diff backup file
|
||||||
@findex cvs-diff-cvs
|
@findex cvs-mode-diff-cvs
|
||||||
@findex cvs-diff-backup
|
@findex cvs-mode-diff-backup
|
||||||
|
@vindex cvs-diff-ignore-marks (variable)
|
||||||
|
|
||||||
@table @kbd
|
@table @kbd
|
||||||
@item d
|
@item d
|
||||||
Display a @samp{cvs diff} between the selected files and the RCS version
|
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
|
that they are based on. @xref{Customization} describes how you can send
|
||||||
flags to @samp{cvs diff}. (The function that does the job is
|
flags to @samp{cvs diff}. If @var{cvs-diff-ignore-marks} is set to a
|
||||||
@code{cvs-diff-cvs}).@refill
|
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
|
@item b
|
||||||
If CVS finds a conflict while merging two versions of a file (during a
|
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
|
@samp{cvs update}, @pxref{Updating the directory}) it will save the
|
||||||
original file in a file called @file{.#@var{FILE}.@var{VERSION}} where
|
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
|
@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
|
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
|
@file{.#@var{FILE}.@var{VERSION}} and @file{@var{FILE}}. You can get a
|
||||||
context- or Unidiff by setting @samp{cvs-diff-flags} -
|
context- or Unidiff by setting @samp{cvs-diff-flags} -
|
||||||
@pxref{Customization}. This command only works on files that have
|
@pxref{Customization}. This command only works on files that have
|
||||||
status @samp{Conflict} or @samp{Merged}. The name of the command is
|
status @samp{Conflict} or @samp{Merged}.@refill
|
||||||
@code{cvs-diff-backup}. @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
|
@end table
|
||||||
|
|
||||||
@node Customization, Future enhancements, Commands, Top
|
@node Customization, Future enhancements, Commands, Top
|
||||||
@ -1310,11 +1460,17 @@ status @samp{Conflict} or @samp{Merged}. The name of the command is
|
|||||||
@chapter Customization
|
@chapter Customization
|
||||||
@vindex cvs-erase-input-buffer (variable)
|
@vindex cvs-erase-input-buffer (variable)
|
||||||
@vindex cvs-inhibit-copyright-message (variable)
|
@vindex cvs-inhibit-copyright-message (variable)
|
||||||
@vindex cvs-cvs-diff-flags (variable)
|
|
||||||
@vindex cvs-diff-flags (variable)
|
@vindex cvs-diff-flags (variable)
|
||||||
|
@vindex cvs-diff-ignore-marks (variable)
|
||||||
@vindex cvs-log-flags (variable)
|
@vindex cvs-log-flags (variable)
|
||||||
@vindex cvs-status-flags (variable)
|
@vindex cvs-status-flags (variable)
|
||||||
@vindex cvs-auto-remove-handled (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 Inhibiting the Copyright message.
|
||||||
@cindex Copyright message, getting rid of it
|
@cindex Copyright message, getting rid of it
|
||||||
@cindex Getting rid of the Copyright message.
|
@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 Context diff, how to get
|
||||||
@cindex Unidiff, how to get
|
@cindex Unidiff, how to get
|
||||||
@cindex Automatically remove handled files
|
@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
|
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
|
isn't present in this list, please tell me! @xref{Bugs} for info on how
|
||||||
ideas} for info on how to reach me.@refill
|
to reach me.@refill
|
||||||
|
|
||||||
@table @samp
|
@table @samp
|
||||||
@item cvs-erase-input-buffer
|
@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}).
|
before you write the log message (@pxref{Committing changes}).
|
||||||
|
|
||||||
@item cvs-inhibit-copyright-message
|
@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
|
(But don't set this to @samp{t} in the system defaults file - new users
|
||||||
should see this message at least once).
|
should see this message at least once).
|
||||||
|
|
||||||
@item cvs-cvs-diff-flags
|
@item cvs-diff-flags
|
||||||
A list of strings to pass as arguments to the @samp{cvs diff} program.
|
A list of strings to pass as arguments to the @samp{cvs diff} and
|
||||||
This is used by @samp{cvs-diff-cvs} (key @kbd{d}, @pxref{Viewing
|
@samp{diff} programs. This is used by @samp{cvs-mode-diff-cvs} and
|
||||||
differences}). If you prefer the Unidiff format you could add this line
|
@samp{cvs-mode-diff-backup} (key @kbd{b}, @pxref{Viewing differences}). If
|
||||||
to your @file{.emacs} file:@refill
|
you prefer the Unidiff format you could add this line to your
|
||||||
|
@file{.emacs} file:@refill
|
||||||
|
|
||||||
@example
|
@example
|
||||||
(setq cvs-cvs-diff-flags '("-u"))
|
(setq cvs-diff-flags '("-u"))
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
@item cvs-diff-flags
|
@item cvs-diff-ignore-marks
|
||||||
Like @samp{cvs-cvs-diff-flags}, but passed to @samp{diff}. This is used
|
If this variable is non-@code{nil} or if a prefix argument is given (but
|
||||||
by @samp{cvs-diff-backup} (key @kbd{b}, @pxref{Viewing differences}).
|
not both) to @samp{cvs-mode-diff-cvs} or @samp{cvs-mode-diff-backup}
|
||||||
|
marked files are not considered selected.
|
||||||
|
|
||||||
@item cvs-log-flags
|
@item cvs-log-flags
|
||||||
List of strings to send to @samp{cvs log}. Used by @samp{cvs-log} (key
|
List of strings to send to @samp{cvs log}. Used by @samp{cvs-mode-log}
|
||||||
@kbd{l}, @pxref{Getting info about files}).
|
(key @kbd{l}, @pxref{Getting info about files}).
|
||||||
|
|
||||||
@item cvs-status-flags
|
@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}).
|
(key @kbd{s}, @pxref{Getting info about files}).
|
||||||
|
|
||||||
@item cvs-auto-remove-handled
|
@item cvs-auto-remove-handled
|
||||||
If this variable is set to any non-@samp{nil} value
|
If this variable is set to any non-@code{nil} value
|
||||||
@samp{cvs-remove-handled} will be called every time you check in files,
|
@samp{cvs-mode-remove-handled} will be called every time you check in
|
||||||
after the check-in is ready. @xref{Removing handled entries}.@refill
|
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
|
@end table
|
||||||
@node Future enhancements, Reporting bugs and ideas, Customization, Top
|
@node Future enhancements, Bugs, Customization, Top
|
||||||
@comment node-name, next, previous, up
|
@comment node-name, next, previous, up
|
||||||
@chapter Future enhancements
|
@chapter Future enhancements
|
||||||
@cindex Enhancements
|
@cindex Enhancements
|
||||||
|
|
||||||
Pcl-cvs is still under development and needs a number of enhancements to
|
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
|
be called complete. Below is my current wish-list for future releases
|
||||||
pcl-cvs:
|
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
|
@itemize @bullet
|
||||||
@item
|
@item
|
||||||
Dired support. I have an experimental @file{dired-cvs.el} that works
|
Rewritten parser code. There are many situations where pcl-cvs will
|
||||||
together with CVS 1.2. Unfortunately I wrote it on top of a
|
fail to recognize the output from CVS. The situation could be greatly
|
||||||
non-standard @file{dired.el}, so it must be rewritten.@refill
|
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
|
@item
|
||||||
It should be possible to run commands such as @samp{cvs log}, @samp{cvs
|
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,
|
status} and @samp{cvs commit} directly from a buffer containing a file,
|
||||||
instead of having to @samp{cvs-update}. If the directory contains many
|
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
|
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
|
@end itemize
|
||||||
|
|
||||||
|
|
||||||
If you miss something in this wish-list, let me know! I don't promise
|
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
|
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
|
of making a good Emacs front end to CVS. See @xref{Bugs} for
|
||||||
ideas} for information about how to reach me.@refill
|
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
|
@comment node-name, next, previous, up
|
||||||
@chapter Reporting bugs and ideas
|
@chapter Bugs (known and unknown)
|
||||||
@cindex Reporting bugs and ideas
|
@cindex Reporting bugs and ideas
|
||||||
@cindex Bugs, how to report them
|
@cindex Bugs, how to report them
|
||||||
@cindex Author, how to reach
|
@cindex Author, how to reach
|
||||||
@cindex Email to the author
|
@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
|
If you find a bug or misfeature, don't hesitate to tell me! Send email
|
||||||
to @samp{ceder@@lysator.liu.se}.
|
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
|
extensions to this package, I would like to hear from you. I hope that
|
||||||
you find this package useful!
|
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
|
@comment node-name, next, previous, up
|
||||||
@unnumbered Function and Variable Index
|
@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
|
# $Id: rcs-to-cvs,v 1.4 1994/09/21 07:23:16 berliner Exp $
|
||||||
# Contributed by Per Cederqvist <ceder@lysator.liu.se>.
|
# 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
|
# Copyright (c) 1989, Brian Berliner
|
||||||
#
|
#
|
||||||
# You may distribute under the terms of the GNU General Public License
|
# 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.
|
|
||||||
#
|
#
|
||||||
#############################################################################
|
#############################################################################
|
||||||
# #
|
#
|
||||||
# This script is used to check in sources that previously was under RCS or #
|
# Check in sources that previously were under RCS or no source control system.
|
||||||
# no source control system. #
|
#
|
||||||
# #
|
# The repository is the directory where the sources should be deposited.
|
||||||
# Usage: rcs-to-cvs repository #
|
#
|
||||||
# #
|
# Traverses the current directory, ensuring that an
|
||||||
# The repository is the directory where the sources should #
|
# identical directory structure exists in the repository directory. It
|
||||||
# be deposited.
|
# then checks the files in in the following manner:
|
||||||
# #
|
#
|
||||||
# checkin traverses the current directory, ensuring that an #
|
# 1) If the file doesn't yet exist, check it in as revision 1.1
|
||||||
# identical directory structure exists in the repository directory. It #
|
#
|
||||||
# then checks the files in in the following manner: #
|
# 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
|
||||||
# 1) If the file doesn't yet exist, check it in #
|
# a file that has been modified on the trunk.
|
||||||
# as revision 0.1 #
|
#
|
||||||
# #
|
# Bugs: doesn't put the files in branch 1.1.1
|
||||||
# The script also is somewhat verbose in letting the user know what is #
|
# doesn't put in release and vendor tags
|
||||||
# going on. It prints a diagnostic when it creates a new file, or updates #
|
#
|
||||||
# a file that has been modified on the trunk. #
|
|
||||||
# #
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
|
|
||||||
set vbose = 0
|
usage="Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository"
|
||||||
set message = ""
|
vbose=0
|
||||||
set cvsbin = /usr/gnu/bin
|
message=""
|
||||||
set rcsbin = /usr/gnu/bin
|
message_file=/usr/tmp/checkin.$$
|
||||||
set grep = /bin/grep
|
got_one=0
|
||||||
set message_file = /usr/tmp/checkin.$$
|
|
||||||
set got_one = 0
|
|
||||||
|
|
||||||
if ( $#argv < 1 ) then
|
if [ $# -lt 1 ]; then
|
||||||
echo "Usage: rcs-to-cvs [-v] [-m message] [-f message_file] repository"
|
echo "$usage" >&2
|
||||||
exit 1
|
exit 1
|
||||||
endif
|
fi
|
||||||
while ( $#argv )
|
|
||||||
switch ( $argv[1] )
|
while [ $# -ne 0 ]; do
|
||||||
case -v:
|
case "$1" in
|
||||||
set vbose = 1
|
-v)
|
||||||
breaksw
|
vbose=1
|
||||||
case -m:
|
;;
|
||||||
|
-m)
|
||||||
shift
|
shift
|
||||||
echo $argv[1] > $message_file
|
echo $1 > $message_file
|
||||||
set got_one = 1
|
got_one=1
|
||||||
breaksw
|
;;
|
||||||
case -f:
|
-f)
|
||||||
shift
|
shift
|
||||||
set message_file = $argv[1]
|
message_file=$1
|
||||||
set got_one = 2
|
got_one=2
|
||||||
breaksw
|
;;
|
||||||
default:
|
*)
|
||||||
break
|
break
|
||||||
endsw
|
esac
|
||||||
shift
|
shift
|
||||||
end
|
done
|
||||||
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
|
exit 1
|
||||||
endif
|
fi
|
||||||
set repository = $argv[1]
|
|
||||||
|
repository=$1
|
||||||
shift
|
shift
|
||||||
|
|
||||||
if ( ! $?CVSROOT ) then
|
if [ -z "$CVSROOT" ]; then
|
||||||
echo "Please set the environmental variable CVSROOT to the root"
|
echo "Please the environmental variable CVSROOT to the root" >&2
|
||||||
echo " of the tree you wish to update"
|
echo " of the tree you wish to update" >&2
|
||||||
exit 1
|
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 "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
|
echo "to be associated with this directory (please remove these lines)">>$message_file
|
||||||
if ( $?EDITOR ) then
|
${EDITOR-/usr/ucb/vi} $message_file
|
||||||
$EDITOR $message_file > /dev/tty
|
got_one=1
|
||||||
else
|
fi
|
||||||
/usr/ucb/vi $message_file > /dev/tty
|
|
||||||
endif
|
|
||||||
set got_one = 1
|
|
||||||
endif
|
|
||||||
|
|
||||||
umask 22
|
umask 22
|
||||||
|
|
||||||
set update_dir = ${CVSROOT}/${repository}
|
update_dir=${CVSROOT}/${repository}
|
||||||
if ( -d SCCS ) then
|
[ ! -d ${update_dir} ] && mkdir $update_dir
|
||||||
echo SCCS files detected!
|
|
||||||
|
if [ -d SCCS ]; then
|
||||||
|
echo SCCS files detected! >&2
|
||||||
exit 1
|
exit 1
|
||||||
endif
|
fi
|
||||||
if ( -d RCS ) then
|
if [ -d RCS ]; then
|
||||||
$rcsbin/co RCS/* >& /dev/null
|
co RCS/*
|
||||||
endif
|
fi
|
||||||
foreach name ( * .[a-zA-Z0-9]* )
|
|
||||||
|
for name in * .[a-zA-Z0-9]*
|
||||||
|
do
|
||||||
|
case "$name" in
|
||||||
|
RCS | \* | .\[a-zA-Z0-9\]\* ) continue ;;
|
||||||
|
esac
|
||||||
echo $name
|
echo $name
|
||||||
if ( "$name" == SCCS ) then
|
if [ $vbose -ne 0 ]; then
|
||||||
continue
|
|
||||||
endif
|
|
||||||
if ( "$name" == RCS ) then
|
|
||||||
continue
|
|
||||||
endif
|
|
||||||
if ( $vbose ) then
|
|
||||||
echo "Updating ${repository}/${name}"
|
echo "Updating ${repository}/${name}"
|
||||||
endif
|
fi
|
||||||
if ( -d "$name" ) then
|
if [ -d "$name" ]; then
|
||||||
if ( ! -d "${update_dir}/${name}" ) then
|
if [ ! -d "${update_dir}/${name}" ]; then
|
||||||
echo "WARNING: Creating new directory ${repository}/${name}"
|
echo "WARNING: Creating new directory ${repository}/${name}"
|
||||||
mkdir "${update_dir}/${name}"
|
mkdir "${update_dir}/${name}"
|
||||||
if ( $status ) then
|
if [ $? -ne 0 ]; then
|
||||||
echo "ERROR: mkdir failed - aborting"
|
echo "ERROR: mkdir failed - aborting" >&2
|
||||||
exit 1
|
exit 1
|
||||||
endif
|
fi
|
||||||
endif
|
fi
|
||||||
chdir "$name"
|
cd "$name"
|
||||||
if ( $status ) then
|
if [ $? -ne 0 ]; then
|
||||||
echo "ERROR: Couldn\'t chdir to "$name" - aborting"
|
echo "ERROR: Couldn\'t cd to $name - aborting" >&2
|
||||||
exit 1
|
exit 1
|
||||||
endif
|
fi
|
||||||
if ( $vbose ) then
|
if [ $vbose -ne 0 ]; then
|
||||||
rcs-to-cvs -v -f $message_file "${repository}/${name}"
|
$0 -v -f $message_file "${repository}/${name}"
|
||||||
else
|
else
|
||||||
rcs-to-cvs -f $message_file "${repository}/${name}"
|
$0 -f $message_file "${repository}/${name}"
|
||||||
endif
|
fi
|
||||||
if ( $status ) then
|
if [ $? -ne 0 ]; then
|
||||||
exit 1
|
exit 1
|
||||||
endif
|
fi
|
||||||
chdir ..
|
cd ..
|
||||||
else # if not directory
|
else # if not directory
|
||||||
if ( ! -f "$name" ) then
|
if [ ! -f "$name" ]; then
|
||||||
echo "WARNING: "$name" is neither a regular file"
|
echo "WARNING: $name is neither a regular file"
|
||||||
echo " nor a directory - ignored"
|
echo " nor a directory - ignored"
|
||||||
continue
|
continue
|
||||||
endif
|
fi
|
||||||
set file = "${update_dir}/${name},v"
|
file="${update_dir}/${name},v"
|
||||||
set new = 0
|
comment=""
|
||||||
set comment = ""
|
if grep -s '\$Log.*\$' "${name}"; then # If $Log keyword
|
||||||
grep -s '\$Log.*\$' "${name}"
|
myext=`echo $name | sed 's,.*\.,,'`
|
||||||
if ( $status == 0 ) then # If $Log keyword
|
[ "$myext" = "$name" ] && myext=
|
||||||
set myext = ${name:e}
|
case "$myext" in
|
||||||
set knownext = 0
|
c | csh | e | f | h | l | mac | me | mm | ms | p | r | red | s | sh | sl | cl | ml | el | tex | y | ye | yr | "" )
|
||||||
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
|
echo "For file ${file}:"
|
||||||
endif
|
|
||||||
end
|
|
||||||
if ( $knownext == 0 ) then
|
|
||||||
echo For file ${file}:
|
|
||||||
grep '\$Log.*\$' "${name}"
|
grep '\$Log.*\$' "${name}"
|
||||||
echo -n "Please insert a comment leader for file ${name} > "
|
echo -n "Please insert a comment leader for file ${name} > "
|
||||||
set comment = $<
|
read comment
|
||||||
endif
|
;;
|
||||||
endif
|
esac
|
||||||
if ( ! -f "$file" ) then # If not exists in repository
|
fi
|
||||||
if ( ! -f "${update_dir}/Attic/${name},v" ) then
|
if [ ! -f "$file" ]; then # If not exists in repository
|
||||||
|
if [ ! -f "${update_dir}/Attic/${name},v" ]; then
|
||||||
echo "WARNING: Creating new file ${repository}/${name}"
|
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."
|
echo "MSG: Copying old rcs file."
|
||||||
cp RCS/"${name}",v "$file"
|
cp RCS/"${name}",v "$file"
|
||||||
else
|
else
|
||||||
if ( "${comment}" != "" ) then
|
if [ -n "${comment}" ]; then
|
||||||
$rcsbin/rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file"
|
rcs -q -i -c"${comment}" -t${message_file} -m'.' "$file"
|
||||||
endif
|
fi
|
||||||
$rcsbin/ci -q -u0.1 -t${message_file} -m'.' "$file"
|
ci -q -u1.1 -t${message_file} -m'.' "$file"
|
||||||
if ( $status ) then
|
if [ $? -ne 0 ]; then
|
||||||
echo "ERROR: Initial check-in of $file failed - aborting"
|
echo "ERROR: Initial check-in of $file failed - aborting" >&2
|
||||||
exit 1
|
exit 1
|
||||||
endif
|
fi
|
||||||
set new = 1
|
fi
|
||||||
endif
|
|
||||||
else
|
else
|
||||||
set file = "${update_dir}/Attic/${name},v"
|
file="${update_dir}/Attic/${name},v"
|
||||||
echo "WARNING: IGNORED: ${repository}/Attic/${name}"
|
echo "WARNING: IGNORED: ${repository}/Attic/${name}"
|
||||||
continue
|
continue
|
||||||
endif
|
fi
|
||||||
else # File existed
|
else # File existed
|
||||||
echo ERROR: File exists: Ignored: "$file"
|
echo "ERROR: File exists in repository: Ignored: $file"
|
||||||
continue
|
continue
|
||||||
# set headbranch = `sed -n '/^head/p; /^branch/p; 2q' $file`
|
fi
|
||||||
# if ( $#headbranch != 2 && $#headbranch != 4 ) then
|
fi
|
||||||
# echo "ERROR: corrupted RCS file $file - aborting"
|
done
|
||||||
# endif
|
|
||||||
# set head = "$headbranch[2]"
|
[ $got_one -eq 1 ] && rm -f $message_file
|
||||||
# set branch = ""
|
|
||||||
# if ( $#headbranch == 4 ) then
|
exit 0
|
||||||
# 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
|
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
#
|
#
|
||||||
# Various hacks made by Brian Berliner before inclusion in CVS contrib area.
|
# 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
|
#we'll assume the user set up the path correctly
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Add
|
||||||
*
|
*
|
||||||
@ -27,17 +27,13 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static int add_directory PROTO((char *repository, char *dir));
|
||||||
static int add_directory (char *repository, char *dir);
|
static int build_entry PROTO((char *repository, char *user, char *options,
|
||||||
static int build_entry (char *repository, char *user, char *options,
|
char *message, List * entries, char *tag));
|
||||||
char *message, List * entries);
|
|
||||||
#else
|
|
||||||
static int add_directory ();
|
|
||||||
static int build_entry ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char *add_usage[] =
|
static char *add_usage[] =
|
||||||
{
|
{
|
||||||
@ -52,7 +48,7 @@ add (argc, argv)
|
|||||||
int argc;
|
int argc;
|
||||||
char *argv[];
|
char *argv[];
|
||||||
{
|
{
|
||||||
char message[MAXMESGLEN];
|
char *message = NULL;
|
||||||
char *user;
|
char *user;
|
||||||
int i;
|
int i;
|
||||||
char *repository;
|
char *repository;
|
||||||
@ -67,9 +63,8 @@ add (argc, argv)
|
|||||||
usage (add_usage);
|
usage (add_usage);
|
||||||
|
|
||||||
/* parse args */
|
/* parse args */
|
||||||
message[0] = '\0';
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "k:m:")) != -1)
|
while ((c = getopt (argc, argv, "k:m:")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -80,14 +75,7 @@ add (argc, argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'm':
|
case 'm':
|
||||||
if (strlen (optarg) >= sizeof (message))
|
message = xstrdup (optarg);
|
||||||
{
|
|
||||||
error (0, 0, "warning: message too long; truncated!");
|
|
||||||
(void) strncpy (message, optarg, sizeof (message));
|
|
||||||
message[sizeof (message) - 1] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(void) strcpy (message, optarg);
|
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
@ -111,7 +99,8 @@ add (argc, argv)
|
|||||||
int begin_err = err;
|
int begin_err = err;
|
||||||
|
|
||||||
user = argv[i];
|
user = argv[i];
|
||||||
if (index (user, '/') != NULL)
|
strip_trailing_slashes (user);
|
||||||
|
if (strchr (user, '/') != NULL)
|
||||||
{
|
{
|
||||||
error (0, 0,
|
error (0, 0,
|
||||||
"cannot add files with '/' in their name; %s not added", user);
|
"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 */
|
/* There is a user file, so build the entry for it */
|
||||||
if (build_entry (repository, user, vers->options,
|
if (build_entry (repository, user, vers->options,
|
||||||
message, entries) != 0)
|
message, entries, vers->tag) != 0)
|
||||||
err++;
|
err++;
|
||||||
else if (!quiet)
|
else
|
||||||
{
|
{
|
||||||
added_files++;
|
added_files++;
|
||||||
error (0, 0, "scheduling file `%s' for addition",
|
if (!quiet)
|
||||||
user);
|
error (0, 0, "scheduling file `%s' for addition", user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* There is an RCS file already, so somebody else must've
|
* There is an RCS file already, so somebody else must've
|
||||||
* added it
|
* added it
|
||||||
@ -214,7 +202,7 @@ add (argc, argv)
|
|||||||
(void) strcpy (vers->vn_user, tmp);
|
(void) strcpy (vers->vn_user, tmp);
|
||||||
(void) sprintf (tmp, "Resurrected %s", user);
|
(void) sprintf (tmp, "Resurrected %s", user);
|
||||||
Register (entries, user, vers->vn_user, tmp, vers->options,
|
Register (entries, user, vers->vn_user, tmp, vers->options,
|
||||||
vers->tag, vers->date);
|
vers->tag, vers->date, vers->ts_conflict);
|
||||||
free (tmp);
|
free (tmp);
|
||||||
|
|
||||||
/* XXX - bugs here; this really resurrect the head */
|
/* 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",
|
error (0, 0, "use 'cvs commit' to add %s permanently",
|
||||||
(added_files == 1) ? "this file" : "these files");
|
(added_files == 1) ? "this file" : "these files");
|
||||||
dellist (&entries);
|
dellist (&entries);
|
||||||
|
|
||||||
|
if (message)
|
||||||
|
free (message);
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +268,7 @@ add_directory (repository, dir)
|
|||||||
char message[PATH_MAX + 100];
|
char message[PATH_MAX + 100];
|
||||||
char *tag, *date;
|
char *tag, *date;
|
||||||
|
|
||||||
if (index (dir, '/') != NULL)
|
if (strchr (dir, '/') != NULL)
|
||||||
{
|
{
|
||||||
error (0, 0,
|
error (0, 0,
|
||||||
"directory %s not added; must be a direct sub-directory", dir);
|
"directory %s not added; must be a direct sub-directory", dir);
|
||||||
@ -334,10 +326,12 @@ add_directory (repository, dir)
|
|||||||
if (!isdir (rcsdir))
|
if (!isdir (rcsdir))
|
||||||
{
|
{
|
||||||
mode_t omask;
|
mode_t omask;
|
||||||
char line[MAXLINELEN];
|
|
||||||
Node *p;
|
Node *p;
|
||||||
List *ulist;
|
List *ulist;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
char line[MAXLINELEN];
|
||||||
|
|
||||||
(void) printf ("Add directory %s to the repository (y/n) [n] ? ",
|
(void) printf ("Add directory %s to the repository (y/n) [n] ? ",
|
||||||
rcsdir);
|
rcsdir);
|
||||||
(void) fflush (stdout);
|
(void) fflush (stdout);
|
||||||
@ -348,6 +342,8 @@ add_directory (repository, dir)
|
|||||||
error (0, 0, "directory %s not added", rcsdir);
|
error (0, 0, "directory %s not added", rcsdir);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
omask = umask (2);
|
omask = umask (2);
|
||||||
if (mkdir (rcsdir, 0777) < 0)
|
if (mkdir (rcsdir, 0777) < 0)
|
||||||
{
|
{
|
||||||
@ -389,12 +385,13 @@ add_directory (repository, dir)
|
|||||||
* interrogating the user. Returns non-zero on error.
|
* interrogating the user. Returns non-zero on error.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
build_entry (repository, user, options, message, entries)
|
build_entry (repository, user, options, message, entries, tag)
|
||||||
char *repository;
|
char *repository;
|
||||||
char *user;
|
char *user;
|
||||||
char *options;
|
char *options;
|
||||||
char *message;
|
char *message;
|
||||||
List *entries;
|
List *entries;
|
||||||
|
char *tag;
|
||||||
{
|
{
|
||||||
char fname[PATH_MAX];
|
char fname[PATH_MAX];
|
||||||
char line[MAXLINELEN];
|
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
|
* 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);
|
(void) sprintf (fname, "%s/%s%s", CVSADM, user, CVSEXT_OPT);
|
||||||
fp = open_file (fname, "w+");
|
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);
|
(void) sprintf (fname, "%s/%s%s", CVSADM, user, CVSEXT_LOG);
|
||||||
fp = open_file (fname, "w+");
|
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);
|
error (1, errno, "cannot write to %s", fname);
|
||||||
if (fclose(fp) == EOF)
|
if (fclose(fp) == EOF)
|
||||||
error(1, errno, "cannot close %s", fname);
|
error(1, errno, "cannot close %s", fname);
|
||||||
@ -442,6 +440,6 @@ build_entry (repository, user, options, message, entries)
|
|||||||
* and ,t files, but who cares).
|
* and ,t files, but who cares).
|
||||||
*/
|
*/
|
||||||
(void) sprintf (line, "Initial %s", user);
|
(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);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Administration
|
||||||
*
|
*
|
||||||
@ -14,18 +14,14 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static Dtype admin_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||||
static Dtype admin_dirproc (char *dir, char *repos, char *update_dir);
|
static int admin_fileproc PROTO((char *file, char *update_dir,
|
||||||
static int admin_fileproc (char *file, char *update_dir,
|
|
||||||
char *repository, List *entries,
|
char *repository, List *entries,
|
||||||
List *srcfiles);
|
List *srcfiles));
|
||||||
#else
|
|
||||||
static int admin_fileproc ();
|
|
||||||
static Dtype admin_dirproc ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char *admin_usage[] =
|
static char *admin_usage[] =
|
||||||
{
|
{
|
||||||
@ -60,7 +56,7 @@ admin (argc, argv)
|
|||||||
/* start the recursion processor */
|
/* start the recursion processor */
|
||||||
err = start_recursion (admin_fileproc, (int (*) ()) NULL, admin_dirproc,
|
err = start_recursion (admin_fileproc, (int (*) ()) NULL, admin_dirproc,
|
||||||
(int (*) ()) NULL, argc, argv, 0,
|
(int (*) ()) NULL, argc, argv, 0,
|
||||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
W_LOCAL, 0, 1, (char *) NULL, 1, 0);
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
||||||
*
|
*
|
||||||
* Check In
|
* Check In
|
||||||
*
|
*
|
||||||
@ -18,22 +18,25 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)checkin.c 1.40 92/03/31";
|
static char rcsid[] = "$CVSid: @(#)checkin.c 1.48 94/10/07 $";
|
||||||
|
USE(rcsid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
Checkin (type, file, repository, rcs, rev, tag, message, entries)
|
Checkin (type, file, repository, rcs, rev, tag, options, message, entries)
|
||||||
int type;
|
int type;
|
||||||
char *file;
|
char *file;
|
||||||
char *repository;
|
char *repository;
|
||||||
char *rcs;
|
char *rcs;
|
||||||
char *rev;
|
char *rev;
|
||||||
char *tag;
|
char *tag;
|
||||||
|
char *options;
|
||||||
char *message;
|
char *message;
|
||||||
List *entries;
|
List *entries;
|
||||||
{
|
{
|
||||||
char fname[PATH_MAX];
|
char fname[PATH_MAX];
|
||||||
Vers_TS *vers;
|
Vers_TS *vers;
|
||||||
|
int set_time;
|
||||||
|
|
||||||
(void) printf ("Checking in %s;\n", file);
|
(void) printf ("Checking in %s;\n", file);
|
||||||
(void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
|
(void) sprintf (fname, "%s/%s%s", CVSADM, CVSPREFIX, file);
|
||||||
@ -48,7 +51,8 @@ Checkin (type, file, repository, rcs, rev, tag, message, entries)
|
|||||||
|
|
||||||
run_setup ("%s%s -f %s%s", Rcsbin, RCS_CI,
|
run_setup ("%s%s -f %s%s", Rcsbin, RCS_CI,
|
||||||
rev ? "-r" : "", rev ? rev : "");
|
rev ? "-r" : "", rev ? rev : "");
|
||||||
run_args ("-m%s", message);
|
run_args ("-m%s", (*message == '\0' || strcmp(message, "\n") == 0) ?
|
||||||
|
"*** empty log message ***\n" : message);
|
||||||
run_arg (rcs);
|
run_arg (rcs);
|
||||||
|
|
||||||
switch (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL))
|
switch (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL))
|
||||||
@ -64,16 +68,25 @@ Checkin (type, file, repository, rcs, rev, tag, message, entries)
|
|||||||
* original user file.
|
* original user file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* XXX - make sure -k options are used on the co; and tag/date? */
|
if (strcmp (options, "-V4") == 0) /* upgrade to V5 now */
|
||||||
run_setup ("%s%s -q %s%s", Rcsbin, RCS_CO,
|
options[0] = '\0';
|
||||||
|
run_setup ("%s%s -q %s %s%s", Rcsbin, RCS_CO, options,
|
||||||
rev ? "-r" : "", rev ? rev : "");
|
rev ? "-r" : "", rev ? rev : "");
|
||||||
run_arg (rcs);
|
run_arg (rcs);
|
||||||
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
||||||
xchmod (file, 1);
|
xchmod (file, 1);
|
||||||
if (xcmp (file, fname) == 0)
|
if (xcmp (file, fname) == 0)
|
||||||
|
{
|
||||||
rename_file (fname, file);
|
rename_file (fname, file);
|
||||||
|
/* the time was correct, so leave it alone */
|
||||||
|
set_time = 0;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
(void) unlink_file (fname);
|
(void) unlink_file (fname);
|
||||||
|
/* sync up with the time from the RCS file */
|
||||||
|
set_time = 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we want read-only files, muck the permissions here, before
|
* If we want read-only files, muck the permissions here, before
|
||||||
@ -92,11 +105,11 @@ Checkin (type, file, repository, rcs, rev, tag, message, entries)
|
|||||||
|
|
||||||
/* re-register with the new data */
|
/* re-register with the new data */
|
||||||
vers = Version_TS (repository, (char *) NULL, tag, (char *) NULL,
|
vers = Version_TS (repository, (char *) NULL, tag, (char *) NULL,
|
||||||
file, 1, 1, entries, (List *) NULL);
|
file, 1, set_time, entries, (List *) NULL);
|
||||||
if (strcmp (vers->options, "-V4") == 0)
|
if (strcmp (vers->options, "-V4") == 0)
|
||||||
vers->options[0] = '\0';
|
vers->options[0] = '\0';
|
||||||
Register (entries, file, vers->vn_rcs, vers->ts_user, vers->options,
|
Register (entries, file, vers->vn_rcs, vers->ts_user,
|
||||||
vers->tag, vers->date);
|
vers->options, vers->tag, vers->date, (char *) 0);
|
||||||
history_write (type, (char *) 0, vers->vn_rcs, file, repository);
|
history_write (type, (char *) 0, vers->vn_rcs, file, repository);
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
break;
|
break;
|
||||||
@ -131,5 +144,6 @@ Checkin (type, file, repository, rcs, rev, tag, message, entries)
|
|||||||
run_arg (rcs);
|
run_arg (rcs);
|
||||||
(void) run_exec (RUN_TTY, RUN_TTY, DEVNULL, RUN_NORMAL);
|
(void) run_exec (RUN_TTY, RUN_TTY, DEVNULL, RUN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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 Version
|
* Create Version
|
||||||
*
|
*
|
||||||
@ -36,22 +36,17 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)checkout.c 1.67 92/04/10";
|
static char rcsid[] = "$CVSid: @(#)checkout.c 1.78 94/10/07 $";
|
||||||
|
USE(rcsid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static char *findslash PROTO((char *start, char *p));
|
||||||
static char *findslash (char *start, char *p);
|
static int build_dirs_and_chdir PROTO((char *dir, char *prepath, char *realdir,
|
||||||
static int build_dirs_and_chdir (char *dir, char *prepath, char *realdir,
|
int sticky));
|
||||||
int sticky);
|
static int checkout_proc PROTO((int *pargc, char *argv[], char *where,
|
||||||
static int checkout_proc (int *pargc, char *argv[], char *where,
|
|
||||||
char *mwhere, char *mfile, int shorten,
|
char *mwhere, char *mfile, int shorten,
|
||||||
int local_specified, char *omodule,
|
int local_specified, char *omodule,
|
||||||
char *msg);
|
char *msg));
|
||||||
#else
|
|
||||||
static int checkout_proc ();
|
|
||||||
static char *findslash ();
|
|
||||||
static int build_dirs_and_chdir ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char *checkout_usage[] =
|
static char *checkout_usage[] =
|
||||||
{
|
{
|
||||||
@ -84,8 +79,8 @@ static char *export_usage[] =
|
|||||||
"\t-l\tLocal directory only, not recursive\n",
|
"\t-l\tLocal directory only, not recursive\n",
|
||||||
"\t-n\tDo not run module program (if any).\n",
|
"\t-n\tDo not run module program (if any).\n",
|
||||||
"\t-q\tSomewhat quiet.\n",
|
"\t-q\tSomewhat quiet.\n",
|
||||||
"\t-r rev\tCheck out revision or tag. (implies -P)\n",
|
"\t-r rev\tCheck out revision or tag.\n",
|
||||||
"\t-D date\tCheck out revisions as of date. (implies -P)\n",
|
"\t-D date\tCheck out revisions as of date.\n",
|
||||||
"\t-d dir\tCheck out into dir instead of module name.\n",
|
"\t-d dir\tCheck out into dir instead of module name.\n",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
@ -106,7 +101,7 @@ checkout (argc, argv)
|
|||||||
int argc;
|
int argc;
|
||||||
char *argv[];
|
char *argv[];
|
||||||
{
|
{
|
||||||
register int i;
|
int i;
|
||||||
int c;
|
int c;
|
||||||
DBM *db;
|
DBM *db;
|
||||||
int cat = 0, err = 0, status = 0;
|
int cat = 0, err = 0, status = 0;
|
||||||
@ -139,7 +134,7 @@ checkout (argc, argv)
|
|||||||
ign_setup ();
|
ign_setup ();
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, valid_options)) != -1)
|
while ((c = getopt (argc, argv, valid_options)) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -261,9 +256,15 @@ checkout (argc, argv)
|
|||||||
where = (char *) NULL;
|
where = (char *) NULL;
|
||||||
if (!isfile (CVSADM) && !isfile (OCVSADM))
|
if (!isfile (CVSADM) && !isfile (OCVSADM))
|
||||||
{
|
{
|
||||||
(void) sprintf (repository, "%s/%s", CVSroot, CVSNULLREPOS);
|
(void) sprintf (repository, "%s/%s/%s", CVSroot, CVSROOTADM,
|
||||||
|
CVSNULLREPOS);
|
||||||
if (!isfile (repository))
|
if (!isfile (repository))
|
||||||
(void) mkdir (repository, 0777);
|
(void) mkdir (repository, 0777);
|
||||||
|
|
||||||
|
/* I'm not sure whether this check is redundant. */
|
||||||
|
if (!isdir (repository))
|
||||||
|
error (1, 0, "there is no repository %s", repository);
|
||||||
|
|
||||||
Create_Admin (".", repository, (char *) NULL, (char *) NULL);
|
Create_Admin (".", repository, (char *) NULL, (char *) NULL);
|
||||||
if (!noexec)
|
if (!noexec)
|
||||||
{
|
{
|
||||||
@ -283,11 +284,11 @@ checkout (argc, argv)
|
|||||||
* attempt to cd to the indicated place. where then becomes simply the
|
* attempt to cd to the indicated place. where then becomes simply the
|
||||||
* last component
|
* last component
|
||||||
*/
|
*/
|
||||||
if (where != NULL && index (where, '/') != NULL)
|
if (where != NULL && strchr (where, '/') != NULL)
|
||||||
{
|
{
|
||||||
char *slash;
|
char *slash;
|
||||||
|
|
||||||
slash = rindex (where, '/');
|
slash = strrchr (where, '/');
|
||||||
*slash = '\0';
|
*slash = '\0';
|
||||||
|
|
||||||
if (chdir (where) < 0)
|
if (chdir (where) < 0)
|
||||||
@ -358,7 +359,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
|
|||||||
char file[PATH_MAX];
|
char file[PATH_MAX];
|
||||||
|
|
||||||
/* if mfile is really a path, straighten it out first */
|
/* if mfile is really a path, straighten it out first */
|
||||||
if ((cp = rindex (mfile, '/')) != NULL)
|
if ((cp = strrchr (mfile, '/')) != NULL)
|
||||||
{
|
{
|
||||||
*cp = 0;
|
*cp = 0;
|
||||||
(void) strcat (repository, "/");
|
(void) strcat (repository, "/");
|
||||||
@ -386,7 +387,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
|
|||||||
{
|
{
|
||||||
char *slash;
|
char *slash;
|
||||||
|
|
||||||
if ((slash = rindex (mfile, '/')) != NULL)
|
if ((slash = strrchr (mfile, '/')) != NULL)
|
||||||
mwhere = slash + 1;
|
mwhere = slash + 1;
|
||||||
else
|
else
|
||||||
mwhere = mfile;
|
mwhere = mfile;
|
||||||
@ -448,7 +449,7 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
|
|||||||
*/
|
*/
|
||||||
if (shorten && where == NULL)
|
if (shorten && where == NULL)
|
||||||
{
|
{
|
||||||
if ((cp = rindex (argv[0], '/')) != NULL)
|
if ((cp = strrchr (argv[0], '/')) != NULL)
|
||||||
{
|
{
|
||||||
(void) strcpy (xwhere, cp + 1);
|
(void) strcpy (xwhere, cp + 1);
|
||||||
where = xwhere;
|
where = xwhere;
|
||||||
@ -498,8 +499,8 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
|
|||||||
* elements exist in where. Big Black Magic
|
* elements exist in where. Big Black Magic
|
||||||
*/
|
*/
|
||||||
prepath = xstrdup (repository);
|
prepath = xstrdup (repository);
|
||||||
cp = rindex (where, '/');
|
cp = strrchr (where, '/');
|
||||||
cp2 = rindex (prepath, '/');
|
cp2 = strrchr (prepath, '/');
|
||||||
while (cp != NULL)
|
while (cp != NULL)
|
||||||
{
|
{
|
||||||
cp = findslash (where, cp - 1);
|
cp = findslash (where, cp - 1);
|
||||||
@ -533,13 +534,23 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
|
|||||||
|
|
||||||
if (!noexec && *pargc > 1)
|
if (!noexec && *pargc > 1)
|
||||||
{
|
{
|
||||||
|
/* I'm not sure whether this check is redundant. */
|
||||||
|
if (!isdir (repository))
|
||||||
|
error (1, 0, "there is no repository %s", repository);
|
||||||
|
|
||||||
Create_Admin (".", repository, (char *) NULL, (char *) NULL);
|
Create_Admin (".", repository, (char *) NULL, (char *) NULL);
|
||||||
fp = open_file (CVSADM_ENTSTAT, "w+");
|
fp = open_file (CVSADM_ENTSTAT, "w+");
|
||||||
if (fclose(fp) == EOF)
|
if (fclose(fp) == EOF)
|
||||||
error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
|
error(1, errno, "cannot close %s", CVSADM_ENTSTAT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
/* I'm not sure whether this check is redundant. */
|
||||||
|
if (!isdir (repository))
|
||||||
|
error (1, 0, "there is no repository %s", repository);
|
||||||
|
|
||||||
Create_Admin (".", repository, tag, date);
|
Create_Admin (".", repository, tag, date);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -622,8 +633,9 @@ checkout_proc (pargc, argv, where, mwhere, mfile, shorten,
|
|||||||
if (vers->ts_user == NULL)
|
if (vers->ts_user == NULL)
|
||||||
{
|
{
|
||||||
(void) sprintf (line, "Initial %s", user);
|
(void) sprintf (line, "Initial %s", user);
|
||||||
Register (entries, user, vers->vn_rcs, line, vers->options,
|
Register (entries, user, vers->vn_rcs ? vers->vn_rcs : "0",
|
||||||
vers->tag, vers->date);
|
line, vers->options, vers->tag,
|
||||||
|
vers->date, (char *) 0);
|
||||||
}
|
}
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
}
|
}
|
||||||
@ -650,9 +662,9 @@ findslash (start, p)
|
|||||||
char *start;
|
char *start;
|
||||||
char *p;
|
char *p;
|
||||||
{
|
{
|
||||||
while ((int) p >= (int) start && *p != '/')
|
while (p >= start && *p != '/')
|
||||||
p--;
|
p--;
|
||||||
if ((int) p < (int) start)
|
if (p < start)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
else
|
else
|
||||||
return (p);
|
return (p);
|
||||||
@ -681,7 +693,7 @@ build_dirs_and_chdir (dir, prepath, realdir, sticky)
|
|||||||
(void) strcpy (path, dir);
|
(void) strcpy (path, dir);
|
||||||
(void) strcpy (path2, realdir);
|
(void) strcpy (path2, realdir);
|
||||||
for (cp = path, cp2 = path2;
|
for (cp = path, cp2 = path2;
|
||||||
(slash = index (cp, '/')) != NULL && (slash2 = index (cp2, '/')) != NULL;
|
(slash = strchr (cp, '/')) != NULL && (slash2 = strchr (cp2, '/')) != NULL;
|
||||||
cp = slash + 1, cp2 = slash2 + 1)
|
cp = slash + 1, cp2 = slash2 + 1)
|
||||||
{
|
{
|
||||||
*slash = '\0';
|
*slash = '\0';
|
||||||
@ -696,6 +708,9 @@ build_dirs_and_chdir (dir, prepath, realdir, sticky)
|
|||||||
strcmp (command_name, "export") != 0)
|
strcmp (command_name, "export") != 0)
|
||||||
{
|
{
|
||||||
(void) sprintf (repository, "%s/%s", prepath, path2);
|
(void) sprintf (repository, "%s/%s", prepath, path2);
|
||||||
|
/* I'm not sure whether this check is redundant. */
|
||||||
|
if (!isdir (repository))
|
||||||
|
error (1, 0, "there is no repository %s", repository);
|
||||||
Create_Admin (".", repository, sticky ? (char *) NULL : tag,
|
Create_Admin (".", repository, sticky ? (char *) NULL : tag,
|
||||||
sticky ? (char *) NULL : date);
|
sticky ? (char *) NULL : date);
|
||||||
if (!noexec)
|
if (!noexec)
|
||||||
|
@ -3,28 +3,25 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static void sticky_ck PROTO((char *file, int aflag, Vers_TS * vers, List * entries));
|
||||||
static void sticky_ck (char *file, int aflag, Vers_TS * vers, List * entries);
|
|
||||||
#else
|
|
||||||
static void sticky_ck ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Classify the state of a file
|
* Classify the state of a file
|
||||||
*/
|
*/
|
||||||
Ctype
|
Ctype
|
||||||
Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
||||||
entries, srcfiles, versp)
|
entries, srcfiles, versp, update_dir, pipeout)
|
||||||
char *file;
|
char *file;
|
||||||
char *tag;
|
char *tag;
|
||||||
char *date;
|
char *date;
|
||||||
@ -35,9 +32,18 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
|||||||
List *entries;
|
List *entries;
|
||||||
List *srcfiles;
|
List *srcfiles;
|
||||||
Vers_TS **versp;
|
Vers_TS **versp;
|
||||||
|
char *update_dir;
|
||||||
|
int pipeout;
|
||||||
{
|
{
|
||||||
Vers_TS *vers;
|
Vers_TS *vers;
|
||||||
Ctype ret;
|
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 */
|
/* get all kinds of good data about the file */
|
||||||
vers = Version_TS (repository, options, tag, date, 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 */
|
/* there is no user file */
|
||||||
if (!force_tag_match || !(vers->tag || vers->date))
|
if (!force_tag_match || !(vers->tag || vers->date))
|
||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0, "nothing known about %s", file);
|
error (0, 0, "nothing known about %s", fullname);
|
||||||
ret = T_UNKNOWN;
|
ret = T_UNKNOWN;
|
||||||
}
|
}
|
||||||
else
|
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 (!force_tag_match || !(vers->tag || vers->date))
|
||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0, "use `cvs add' to create an entry for %s",
|
error (0, 0, "use `cvs add' to create an entry for %s",
|
||||||
file);
|
fullname);
|
||||||
ret = T_UNKNOWN;
|
ret = T_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,16 +84,26 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
|||||||
}
|
}
|
||||||
else
|
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
|
* There is a user file; print a warning and add it to the
|
||||||
* conflict list, only if it is indeed different from what we
|
* conflict list, only if it is indeed different from what we
|
||||||
* plan to extract
|
* 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 */
|
/* the files were different so it is a conflict */
|
||||||
if (!really_quiet)
|
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;
|
ret = T_CONFLICT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -107,7 +123,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
|||||||
* entry
|
* entry
|
||||||
*/
|
*/
|
||||||
if (!really_quiet)
|
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;
|
ret = T_REMOVE_ENTRY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -126,7 +142,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
|||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0,
|
error (0, 0,
|
||||||
"conflict: %s created independently by second party",
|
"conflict: %s created independently by second party",
|
||||||
file);
|
fullname);
|
||||||
ret = T_CONFLICT;
|
ret = T_CONFLICT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -169,7 +185,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
|||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0,
|
error (0, 0,
|
||||||
"conflict: removed %s was modified by second party",
|
"conflict: removed %s was modified by second party",
|
||||||
file);
|
fullname);
|
||||||
ret = T_CONFLICT;
|
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 */
|
/* The user file shouldn't be there */
|
||||||
if (!really_quiet)
|
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;
|
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 */
|
/* There is no user file, so just remove the entry */
|
||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0, "warning: %s is not (any longer) pertinent",
|
error (0, 0, "warning: %s is not (any longer) pertinent",
|
||||||
file);
|
fullname);
|
||||||
ret = T_REMOVE_ENTRY;
|
ret = T_REMOVE_ENTRY;
|
||||||
}
|
}
|
||||||
else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
|
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
|
* the entry list
|
||||||
*/
|
*/
|
||||||
if (!really_quiet)
|
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;
|
ret = T_REMOVE_ENTRY;
|
||||||
}
|
}
|
||||||
else
|
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
|
* The user file has been modified and since it is no longer
|
||||||
* in the repository, a conflict is raised
|
* 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 */
|
/* they are different -> conflict */
|
||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0,
|
error (0, 0,
|
||||||
"conflict: %s is modified but no longer in the repository",
|
"conflict: %s is modified but no longer in the repository",
|
||||||
file);
|
fullname);
|
||||||
ret = T_CONFLICT;
|
ret = T_CONFLICT;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -228,7 +247,7 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
|||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0,
|
error (0, 0,
|
||||||
"warning: %s is not (any longer) pertinent",
|
"warning: %s is not (any longer) pertinent",
|
||||||
file);
|
fullname);
|
||||||
ret = T_REMOVE_ENTRY;
|
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 (strcmp (command_name, "update") == 0)
|
||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0, "warning: %s was lost", file);
|
error (0, 0, "warning: %s was lost", fullname);
|
||||||
ret = T_CHECKOUT;
|
ret = T_CHECKOUT;
|
||||||
}
|
}
|
||||||
else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
|
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
|
* The user file appears to have been modified, but we call
|
||||||
* No_Difference to verify that it really has been modified
|
* 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 (strcmp (command_name, "update") == 0)
|
||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0, "warning: %s was lost", file);
|
error (0, 0, "warning: %s was lost", fullname);
|
||||||
ret = T_CHECKOUT;
|
ret = T_CHECKOUT;
|
||||||
}
|
}
|
||||||
else if (strcmp (vers->ts_user, vers->ts_rcs) == 0)
|
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
|
else
|
||||||
{
|
{
|
||||||
if (No_Difference (file, vers, entries))
|
if (No_Difference (file, vers, entries,
|
||||||
|
repository, update_dir))
|
||||||
/* really modified, needs to merge */
|
/* really modified, needs to merge */
|
||||||
ret = T_NEEDS_MERGE;
|
ret = T_NEEDS_MERGE;
|
||||||
else
|
else
|
||||||
@ -352,6 +373,8 @@ Classify_File (file, tag, date, options, force_tag_match, aflag, repository,
|
|||||||
else
|
else
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
|
|
||||||
|
free (fullname);
|
||||||
|
|
||||||
/* return the status of the file */
|
/* return the status of the file */
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
@ -374,7 +397,7 @@ sticky_ck (file, aflag, vers, entries)
|
|||||||
((entdate && !vers->date) || (!entdate && vers->date)))
|
((entdate && !vers->date) || (!entdate && vers->date)))
|
||||||
{
|
{
|
||||||
Register (entries, file, vers->vn_user, vers->ts_rcs,
|
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
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Commit Files
|
||||||
*
|
*
|
||||||
@ -17,68 +17,46 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static Dtype check_direntproc PROTO((char *dir, char *repos, char *update_dir));
|
||||||
static Dtype check_direntproc (char *dir, char *repos, char *update_dir);
|
static int check_fileproc PROTO((char *file, char *update_dir, char *repository,
|
||||||
static int check_fileproc (char *file, char *update_dir, char *repository,
|
List * entries, List * srcfiles));
|
||||||
List * entries, List * srcfiles);
|
static int check_filesdoneproc PROTO((int err, char *repos, char *update_dir));
|
||||||
static int check_filesdoneproc (int err, char *repos, char *update_dir);
|
static int checkaddfile PROTO((char *file, char *repository, char *tag,
|
||||||
static int checkaddfile (char *file, char *repository, char *tag);
|
List *srcfiles));
|
||||||
static Dtype commit_direntproc (char *dir, char *repos, char *update_dir);
|
static Dtype commit_direntproc PROTO((char *dir, char *repos, char *update_dir));
|
||||||
static int commit_dirleaveproc (char *dir, int err, char *update_dir);
|
static int commit_dirleaveproc PROTO((char *dir, int err, char *update_dir));
|
||||||
static int commit_fileproc (char *file, char *update_dir, char *repository,
|
static int commit_fileproc PROTO((char *file, char *update_dir, char *repository,
|
||||||
List * entries, List * srcfiles);
|
List * entries, List * srcfiles));
|
||||||
static int commit_filesdoneproc (int err, char *repository, char *update_dir);
|
static int commit_filesdoneproc PROTO((int err, char *repository, char *update_dir));
|
||||||
static int finaladd (char *file, char *revision, char *tag, char *repository,
|
static int finaladd PROTO((char *file, char *revision, char *tag, char *options,
|
||||||
List *entries);
|
char *repository, List *entries));
|
||||||
static int findmaxrev (Node * p);
|
static int findmaxrev PROTO((Node * p, void *closure));
|
||||||
static int fsortcmp (Node * p, Node * q);
|
static int fsortcmp PROTO((Node * p, Node * q));
|
||||||
static int lock_RCS (char *user, char *rcs, char *rev, char *repository);
|
static int lock_RCS PROTO((char *user, char *rcs, char *rev, char *repository));
|
||||||
static int lock_filesdoneproc (int err, char *repository, char *update_dir);
|
static int lock_filesdoneproc PROTO((int err, char *repository, char *update_dir));
|
||||||
static int lockrcsfile (char *file, char *repository, char *rev);
|
static int lockrcsfile PROTO((char *file, char *repository, char *rev));
|
||||||
static int precommit_list_proc (Node * p);
|
static int precommit_list_proc PROTO((Node * p, void *closure));
|
||||||
static int precommit_proc (char *repository, char *filter);
|
static int precommit_proc PROTO((char *repository, char *filter));
|
||||||
static int remove_file (char *file, char *repository, char *tag,
|
static int remove_file PROTO((char *file, char *repository, char *tag,
|
||||||
List *entries);
|
char *message, List *entries, List *srcfiles));
|
||||||
static void fix_rcs_modes (char *rcs, char *user);
|
static void fix_rcs_modes PROTO((char *rcs, char *user));
|
||||||
static void fixaddfile (char *file, char *repository);
|
static void fixaddfile PROTO((char *file, char *repository));
|
||||||
static void fixbranch (char *file, char *repository, char *branch);
|
static void fixbranch PROTO((char *file, char *repository, char *branch));
|
||||||
static void unlockrcs (char *file, char *repository);
|
static void unlockrcs PROTO((char *file, char *repository));
|
||||||
static void ci_delproc (Node *p);
|
static void ci_delproc PROTO((Node *p));
|
||||||
static void locate_rcs (char *file, char *repository, char *rcs);
|
static void masterlist_delproc PROTO((Node *p));
|
||||||
#else
|
static void locate_rcs PROTO((char *file, char *repository, char *rcs));
|
||||||
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__ */
|
|
||||||
|
|
||||||
struct commit_info
|
struct commit_info
|
||||||
{
|
{
|
||||||
Ctype status; /* as returned from Classify_File() */
|
Ctype status; /* as returned from Classify_File() */
|
||||||
char *rev; /* a numeric rev, if we know it */
|
char *rev; /* a numeric rev, if we know it */
|
||||||
char *tag; /* any sticky tag, or -r option */
|
char *tag; /* any sticky tag, or -r option */
|
||||||
|
char *options; /* Any sticky -k option */
|
||||||
};
|
};
|
||||||
struct master_lists
|
struct master_lists
|
||||||
{
|
{
|
||||||
@ -86,6 +64,7 @@ struct master_lists
|
|||||||
List *cilist; /* list with commit_info structs */
|
List *cilist; /* list with commit_info structs */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int force_ci;
|
||||||
static int got_message;
|
static int got_message;
|
||||||
static int run_module_prog = 1;
|
static int run_module_prog = 1;
|
||||||
static int aflag;
|
static int aflag;
|
||||||
@ -98,11 +77,12 @@ static char *message;
|
|||||||
|
|
||||||
static char *commit_usage[] =
|
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-n\tDo not run the module program (if any).\n",
|
||||||
"\t-R\tProcess directories recursively.\n",
|
"\t-R\tProcess directories recursively.\n",
|
||||||
"\t-l\tLocal directory only (not recursive).\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-m msg\tLog message.\n",
|
||||||
"\t-r rev\tCommit to this branch or trunk revision.\n",
|
"\t-r rev\tCommit to this branch or trunk revision.\n",
|
||||||
NULL
|
NULL
|
||||||
@ -136,10 +116,8 @@ commit (argc, argv)
|
|||||||
}
|
}
|
||||||
#endif /* CVS_BADROOT */
|
#endif /* CVS_BADROOT */
|
||||||
|
|
||||||
message = xmalloc (MAXMESGLEN + 1);
|
|
||||||
message[0] = '\0'; /* Null message by default */
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "nlRm:f:r:")) != -1)
|
while ((c = getopt (argc, argv, "nlRm:fF:r:")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -152,14 +130,13 @@ commit (argc, argv)
|
|||||||
#else
|
#else
|
||||||
use_editor = FALSE;
|
use_editor = FALSE;
|
||||||
#endif
|
#endif
|
||||||
if (strlen (optarg) >= (size_t) MAXMESGLEN)
|
if (message)
|
||||||
{
|
{
|
||||||
error (0, 0, "warning: message too long; truncated!");
|
free (message);
|
||||||
(void) strncpy (message, optarg, MAXMESGLEN);
|
message = NULL;
|
||||||
message[MAXMESGLEN] = '\0';
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
(void) strcpy (message, optarg);
|
message = xstrdup(optarg);
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (tag)
|
if (tag)
|
||||||
@ -173,6 +150,10 @@ commit (argc, argv)
|
|||||||
local = 0;
|
local = 0;
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
|
force_ci = 1;
|
||||||
|
local = 1; /* also disable recursion */
|
||||||
|
break;
|
||||||
|
case 'F':
|
||||||
#ifdef FORCE_USE_EDITOR
|
#ifdef FORCE_USE_EDITOR
|
||||||
use_editor = TRUE;
|
use_editor = TRUE;
|
||||||
#else
|
#else
|
||||||
@ -198,19 +179,26 @@ commit (argc, argv)
|
|||||||
tag[strlen (tag) - 1] = '\0';
|
tag[strlen (tag) - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* some checks related to the "-f logfile" option */
|
/* some checks related to the "-F logfile" option */
|
||||||
if (logfile)
|
if (logfile)
|
||||||
{
|
{
|
||||||
int n, logfd;
|
int n, logfd;
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
if (*message)
|
if (message)
|
||||||
error (1, 0, "cannot specify both a message and a log file");
|
error (1, 0, "cannot specify both a message and a log file");
|
||||||
|
|
||||||
if ((logfd = open (logfile, O_RDONLY)) < 0 ||
|
if ((logfd = open (logfile, O_RDONLY)) < 0)
|
||||||
(n = read (logfd, message, MAXMESGLEN)) < 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);
|
error (1, errno, "cannot read log message from %s", logfile);
|
||||||
}
|
|
||||||
(void) close (logfd);
|
(void) close (logfd);
|
||||||
message[n] = '\0';
|
message[n] = '\0';
|
||||||
}
|
}
|
||||||
@ -226,7 +214,8 @@ commit (argc, argv)
|
|||||||
locklist = getlist ();
|
locklist = getlist ();
|
||||||
err = start_recursion ((int (*) ()) NULL, lock_filesdoneproc,
|
err = start_recursion ((int (*) ()) NULL, lock_filesdoneproc,
|
||||||
(Dtype (*) ()) NULL, (int (*) ()) NULL, argc,
|
(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);
|
sortlist (locklist, fsortcmp);
|
||||||
if (Writer_Lock (locklist) != 0)
|
if (Writer_Lock (locklist) != 0)
|
||||||
error (1, 0, "lock failed - giving up");
|
error (1, 0, "lock failed - giving up");
|
||||||
@ -241,7 +230,8 @@ commit (argc, argv)
|
|||||||
*/
|
*/
|
||||||
err = start_recursion (check_fileproc, check_filesdoneproc,
|
err = start_recursion (check_fileproc, check_filesdoneproc,
|
||||||
check_direntproc, (int (*) ()) NULL, argc,
|
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)
|
if (err)
|
||||||
{
|
{
|
||||||
Lock_Cleanup ();
|
Lock_Cleanup ();
|
||||||
@ -255,7 +245,7 @@ commit (argc, argv)
|
|||||||
err = start_recursion (commit_fileproc, commit_filesdoneproc,
|
err = start_recursion (commit_fileproc, commit_filesdoneproc,
|
||||||
commit_direntproc, commit_dirleaveproc,
|
commit_direntproc, commit_dirleaveproc,
|
||||||
argc, argv, local, W_LOCAL, aflag, 0,
|
argc, argv, local, W_LOCAL, aflag, 0,
|
||||||
(char *) NULL, 1);
|
(char *) NULL, 1, 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unlock all the dirs and clean up
|
* Unlock all the dirs and clean up
|
||||||
@ -291,6 +281,7 @@ lock_filesdoneproc (err, repository, update_dir)
|
|||||||
p = getnode ();
|
p = getnode ();
|
||||||
p->type = LOCK;
|
p->type = LOCK;
|
||||||
p->key = xstrdup (repository);
|
p->key = xstrdup (repository);
|
||||||
|
/* FIXME-KRP: this error condition should not simply be passed by. */
|
||||||
if (p->key == NULL || addnode (locklist, p) != 0)
|
if (p->key == NULL || addnode (locklist, p) != 0)
|
||||||
freenode (p);
|
freenode (p);
|
||||||
return (err);
|
return (err);
|
||||||
@ -330,15 +321,23 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
{
|
{
|
||||||
status = Classify_File (file, (char *) NULL, (char *) NULL,
|
status = Classify_File (file, (char *) NULL, (char *) NULL,
|
||||||
(char *) NULL, 1, aflag, repository,
|
(char *) NULL, 1, aflag, repository,
|
||||||
entries, srcfiles, &vers);
|
entries, srcfiles, &vers, update_dir, 0);
|
||||||
if (status == T_UPTODATE)
|
if (status == T_UPTODATE || status == T_MODIFIED ||
|
||||||
|
status == T_ADDED)
|
||||||
{
|
{
|
||||||
|
Ctype xstatus;
|
||||||
|
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
status = Classify_File (file, tag, (char *) NULL,
|
xstatus = Classify_File (file, tag, (char *) NULL,
|
||||||
(char *) NULL, 1, aflag, repository,
|
(char *) NULL, 1, aflag, repository,
|
||||||
entries, srcfiles, &vers);
|
entries, srcfiles, &vers, update_dir,
|
||||||
if (status == T_REMOVE_ENTRY)
|
0);
|
||||||
|
if (xstatus == T_REMOVE_ENTRY)
|
||||||
status = T_MODIFIED;
|
status = T_MODIFIED;
|
||||||
|
else if (status == T_MODIFIED && xstatus == T_CONFLICT)
|
||||||
|
status = T_MODIFIED;
|
||||||
|
else
|
||||||
|
status = xstatus;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -352,21 +351,22 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
xtag = xstrdup (tag);
|
xtag = xstrdup (tag);
|
||||||
if ((numdots (xtag) & 1) != 0)
|
if ((numdots (xtag) & 1) != 0)
|
||||||
{
|
{
|
||||||
cp = rindex (xtag, '.');
|
cp = strrchr (xtag, '.');
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
}
|
}
|
||||||
status = Classify_File (file, xtag, (char *) NULL,
|
status = Classify_File (file, xtag, (char *) NULL,
|
||||||
(char *) NULL, 1, aflag, repository,
|
(char *) NULL, 1, aflag, repository,
|
||||||
entries, srcfiles, &vers);
|
entries, srcfiles, &vers, update_dir, 0);
|
||||||
if ((status == T_REMOVE_ENTRY || status == T_CONFLICT)
|
if ((status == T_REMOVE_ENTRY || status == T_CONFLICT)
|
||||||
&& (cp = rindex (xtag, '.')) != NULL)
|
&& (cp = strrchr (xtag, '.')) != NULL)
|
||||||
{
|
{
|
||||||
/* pluck one more dot off the revision */
|
/* pluck one more dot off the revision */
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
status = Classify_File (file, xtag, (char *) NULL,
|
status = Classify_File (file, xtag, (char *) NULL,
|
||||||
(char *) NULL, 1, aflag, repository,
|
(char *) NULL, 1, aflag, repository,
|
||||||
entries, srcfiles, &vers);
|
entries, srcfiles, &vers, update_dir,
|
||||||
|
0);
|
||||||
if (status == T_UPTODATE || status == T_REMOVE_ENTRY)
|
if (status == T_UPTODATE || status == T_REMOVE_ENTRY)
|
||||||
status = T_MODIFIED;
|
status = T_MODIFIED;
|
||||||
}
|
}
|
||||||
@ -378,17 +378,30 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
status = Classify_File (file, tag, (char *) NULL, (char *) NULL,
|
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;
|
noexec = save_noexec;
|
||||||
quiet = save_quiet;
|
quiet = save_quiet;
|
||||||
really_quiet = save_really_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)
|
switch (status)
|
||||||
{
|
{
|
||||||
case T_CHECKOUT:
|
case T_CHECKOUT:
|
||||||
case T_NEEDS_MERGE:
|
case T_NEEDS_MERGE:
|
||||||
case T_CONFLICT:
|
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);
|
error (0, 0, "Up-to-date check failed for `%s'", file);
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
return (1);
|
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_REMOVED, can't have a numeric tag
|
||||||
* - if status is T_ADDED, rcs file must not exist
|
* - 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_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 (!tag || !isdigit (*tag))
|
||||||
{
|
{
|
||||||
if (vers->date)
|
if (vers->date)
|
||||||
{
|
{
|
||||||
error (0, 0,
|
if (update_dir[0] == '\0')
|
||||||
"cannot commit with sticky date for file `%s'",
|
error (0, 0,
|
||||||
file);
|
"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);
|
freevers_ts (&vers);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
if (status == T_MODIFIED && vers->tag &&
|
if (status == T_MODIFIED && vers->tag &&
|
||||||
!RCS_isbranch (file, vers->tag, srcfiles))
|
!RCS_isbranch (file, vers->tag, srcfiles))
|
||||||
{
|
{
|
||||||
error (0, 0,
|
if (update_dir[0] == '\0')
|
||||||
"sticky tag `%s' for file `%s' is not a branch",
|
error (0, 0,
|
||||||
vers->tag, file);
|
"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);
|
freevers_ts (&vers);
|
||||||
return (1);
|
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 (status == T_REMOVED && vers->tag && isdigit (*vers->tag))
|
||||||
{
|
{
|
||||||
error (0, 0,
|
if (update_dir[0] == '\0')
|
||||||
|
error (0, 0,
|
||||||
"cannot remove file `%s' which has a numeric sticky tag of `%s'",
|
"cannot remove file `%s' which has a numeric sticky tag of `%s'",
|
||||||
file, vers->tag);
|
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);
|
freevers_ts (&vers);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -439,18 +535,28 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
locate_rcs (file, repository, rcs);
|
locate_rcs (file, repository, rcs);
|
||||||
if (isreadable (rcs))
|
if (isreadable (rcs))
|
||||||
{
|
{
|
||||||
error (0, 0,
|
if (update_dir[0] == '\0')
|
||||||
|
error (0, 0,
|
||||||
"cannot add file `%s' when RCS file `%s' already exists",
|
"cannot add file `%s' when RCS file `%s' already exists",
|
||||||
file, rcs);
|
file, rcs);
|
||||||
|
else
|
||||||
|
error (0, 0,
|
||||||
|
"cannot add file `%s/%s' when RCS file `%s' already exists",
|
||||||
|
update_dir, file, rcs);
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
if (vers->tag && isdigit (*vers->tag) &&
|
if (vers->tag && isdigit (*vers->tag) &&
|
||||||
numdots (vers->tag) > 1)
|
numdots (vers->tag) > 1)
|
||||||
{
|
{
|
||||||
error (0, 0,
|
if (update_dir[0] == '\0')
|
||||||
|
error (0, 0,
|
||||||
"cannot add file `%s' with revision `%s'; must be on trunk",
|
"cannot add file `%s' with revision `%s'; must be on trunk",
|
||||||
file, vers->tag);
|
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);
|
freevers_ts (&vers);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
@ -480,6 +586,7 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
ml->ulist = ulist;
|
ml->ulist = ulist;
|
||||||
ml->cilist = cilist;
|
ml->cilist = cilist;
|
||||||
p->data = (char *) ml;
|
p->data = (char *) ml;
|
||||||
|
p->delproc = masterlist_delproc;
|
||||||
(void) addnode (mulist, p);
|
(void) addnode (mulist, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,17 +612,21 @@ check_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
else
|
else
|
||||||
ci->rev = (char *) NULL;
|
ci->rev = (char *) NULL;
|
||||||
ci->tag = xstrdup (vers->tag);
|
ci->tag = xstrdup (vers->tag);
|
||||||
|
ci->options = xstrdup(vers->options);
|
||||||
p->data = (char *) ci;
|
p->data = (char *) ci;
|
||||||
(void) addnode (cilist, p);
|
(void) addnode (cilist, p);
|
||||||
break;
|
break;
|
||||||
case T_UNKNOWN:
|
case T_UNKNOWN:
|
||||||
error (0, 0, "nothing known about `%s'", file);
|
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);
|
freevers_ts (&vers);
|
||||||
return (1);
|
return (1);
|
||||||
case T_UPTODATE:
|
case T_UPTODATE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error (0, 0, "Unknown status 0x%x for `%s'", status, file);
|
error (0, 0, "CVS internal error: unknown status %d", status);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,11 +654,15 @@ check_direntproc (dir, repos, update_dir)
|
|||||||
* Walklist proc to run pre-commit checks
|
* Walklist proc to run pre-commit checks
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
precommit_list_proc (p)
|
precommit_list_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
if (p->data == (char *) T_ADDED || p->data == (char *) T_MODIFIED)
|
if (p->data == (char *) T_ADDED || p->data == (char *) T_MODIFIED ||
|
||||||
|
p->data == (char *) T_REMOVED)
|
||||||
|
{
|
||||||
run_arg (p->key);
|
run_arg (p->key);
|
||||||
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -561,14 +676,28 @@ precommit_proc (repository, filter)
|
|||||||
char *filter;
|
char *filter;
|
||||||
{
|
{
|
||||||
/* see if the filter is there, only if it's a full path */
|
/* 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;
|
||||||
return (1); /* so it fails! */
|
|
||||||
|
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);
|
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));
|
return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -647,10 +776,10 @@ commit_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
* need to get the commit message ourselves
|
* need to get the commit message ourselves
|
||||||
*/
|
*/
|
||||||
if (use_editor && !got_message)
|
if (use_editor && !got_message)
|
||||||
{
|
{
|
||||||
got_message = 1;
|
got_message = 1;
|
||||||
do_editor (update_dir, message, repository, ulist);
|
do_editor (update_dir, &message, repository, ulist);
|
||||||
}
|
}
|
||||||
|
|
||||||
p = findnode (cilist, file);
|
p = findnode (cilist, file);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
@ -662,15 +791,17 @@ commit_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
if (lockrcsfile (file, repository, ci->rev) != 0)
|
if (lockrcsfile (file, repository, ci->rev) != 0)
|
||||||
{
|
{
|
||||||
unlockrcs (file, repository);
|
unlockrcs (file, repository);
|
||||||
return (1);
|
err = 1;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ci->status == T_ADDED)
|
else if (ci->status == T_ADDED)
|
||||||
{
|
{
|
||||||
if (checkaddfile (file, repository, ci->tag) != 0)
|
if (checkaddfile (file, repository, ci->tag, srcfiles) != 0)
|
||||||
{
|
{
|
||||||
fixaddfile (file, repository);
|
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 */
|
/* find the max major rev number in this directory */
|
||||||
maxrev = 0;
|
maxrev = 0;
|
||||||
(void) walklist (entries, findmaxrev);
|
(void) walklist (entries, findmaxrev, NULL);
|
||||||
if (maxrev == 0)
|
if (maxrev == 0)
|
||||||
maxrev = 1;
|
maxrev = 1;
|
||||||
xrev = xmalloc (20);
|
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 */
|
/* 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);
|
repository, entries);
|
||||||
if (xrev)
|
if (xrev)
|
||||||
free (xrev);
|
free (xrev);
|
||||||
return (err);
|
|
||||||
}
|
}
|
||||||
|
else if (ci->status == T_MODIFIED)
|
||||||
if (ci->status == T_MODIFIED)
|
|
||||||
{
|
{
|
||||||
locate_rcs (file, repository, rcs);
|
locate_rcs (file, repository, rcs);
|
||||||
err = Checkin ('M', file, repository, rcs, ci->rev, ci->tag,
|
err = Checkin ('M', file, repository, rcs, ci->rev, ci->tag,
|
||||||
message, entries);
|
ci->options, message, entries);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
{
|
{
|
||||||
unlockrcs (file, repository);
|
unlockrcs (file, repository);
|
||||||
fixbranch (file, repository, sbranch);
|
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)
|
out:
|
||||||
err = remove_file (file, repository, ci->tag, entries);
|
if (err != 0)
|
||||||
|
{
|
||||||
|
/* on failure, remove the file from ulist */
|
||||||
|
p = findnode (ulist, file);
|
||||||
|
if (p)
|
||||||
|
delnode (p);
|
||||||
|
}
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
@ -728,19 +866,16 @@ commit_filesdoneproc (err, repository, update_dir)
|
|||||||
char *repository;
|
char *repository;
|
||||||
char *update_dir;
|
char *update_dir;
|
||||||
{
|
{
|
||||||
List *ulist, *cilist;
|
|
||||||
char *xtag = (char *) NULL;
|
char *xtag = (char *) NULL;
|
||||||
Node *p;
|
Node *p;
|
||||||
|
List *ulist;
|
||||||
|
|
||||||
p = findnode (mulist, update_dir);
|
p = findnode (mulist, update_dir);
|
||||||
if (p != NULL)
|
if (p == NULL)
|
||||||
{
|
|
||||||
ulist = ((struct master_lists *) p->data)->ulist;
|
|
||||||
cilist = ((struct master_lists *) p->data)->cilist;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
|
ulist = ((struct master_lists *) p->data)->ulist;
|
||||||
|
|
||||||
got_message = 0;
|
got_message = 0;
|
||||||
|
|
||||||
/* see if we need to specify a per-directory or -r option tag */
|
/* 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);
|
ParseTag (&xtag, (char **) NULL);
|
||||||
|
|
||||||
Update_Logfile (repository, message, tag ? tag : xtag, (FILE *) 0, ulist);
|
Update_Logfile (repository, message, tag ? tag : xtag, (FILE *) 0, ulist);
|
||||||
dellist (&ulist);
|
|
||||||
dellist (&cilist);
|
|
||||||
if (xtag)
|
if (xtag)
|
||||||
free (xtag);
|
free (xtag);
|
||||||
|
|
||||||
@ -765,7 +898,7 @@ commit_filesdoneproc (err, repository, update_dir)
|
|||||||
{
|
{
|
||||||
if (fgets (line, sizeof (line), fp) != NULL)
|
if (fgets (line, sizeof (line), fp) != NULL)
|
||||||
{
|
{
|
||||||
if ((cp = rindex (line, '\n')) != NULL)
|
if ((cp = strrchr (line, '\n')) != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
repository = Name_Repository ((char *) NULL, update_dir);
|
repository = Name_Repository ((char *) NULL, update_dir);
|
||||||
run_setup ("%s %s", line, repository);
|
run_setup ("%s %s", line, repository);
|
||||||
@ -817,7 +950,7 @@ commit_direntproc (dir, repos, update_dir)
|
|||||||
{
|
{
|
||||||
got_message = 1;
|
got_message = 1;
|
||||||
real_repos = Name_Repository (dir, update_dir);
|
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);
|
free (real_repos);
|
||||||
}
|
}
|
||||||
return (R_PROCESS);
|
return (R_PROCESS);
|
||||||
@ -844,15 +977,16 @@ commit_dirleaveproc (dir, err, update_dir)
|
|||||||
* find the maximum major rev number in an entries file
|
* find the maximum major rev number in an entries file
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
findmaxrev (p)
|
findmaxrev (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
int thisrev;
|
int thisrev;
|
||||||
Entnode *entdata;
|
Entnode *entdata;
|
||||||
|
|
||||||
entdata = (Entnode *) p->data;
|
entdata = (Entnode *) p->data;
|
||||||
cp = index (entdata->version, '.');
|
cp = strchr (entdata->version, '.');
|
||||||
if (cp != NULL)
|
if (cp != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
thisrev = atoi (entdata->version);
|
thisrev = atoi (entdata->version);
|
||||||
@ -870,18 +1004,23 @@ findmaxrev (p)
|
|||||||
* link to keep it relative after we move it into the attic.
|
* link to keep it relative after we move it into the attic.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
remove_file (file, repository, tag, entries)
|
remove_file (file, repository, tag, message, entries, srcfiles)
|
||||||
char *file;
|
char *file;
|
||||||
char *repository;
|
char *repository;
|
||||||
char *tag;
|
char *tag;
|
||||||
|
char *message;
|
||||||
List *entries;
|
List *entries;
|
||||||
|
List *srcfiles;
|
||||||
{
|
{
|
||||||
int omask;
|
mode_t omask;
|
||||||
int retcode;
|
int retcode;
|
||||||
char rcs[PATH_MAX];
|
char rcs[PATH_MAX];
|
||||||
char tmp[PATH_MAX];
|
char *tmp;
|
||||||
|
|
||||||
|
retcode = 0;
|
||||||
|
|
||||||
locate_rcs (file, repository, rcs);
|
locate_rcs (file, repository, rcs);
|
||||||
|
|
||||||
if (tag)
|
if (tag)
|
||||||
{
|
{
|
||||||
/* a symbolic tag is specified; just remove the tag from the file */
|
/* a symbolic tag is specified; just remove the tag from the file */
|
||||||
@ -894,20 +1033,28 @@ remove_file (file, repository, tag, entries)
|
|||||||
"failed to remove tag `%s' from `%s'", tag, rcs);
|
"failed to remove tag `%s' from `%s'", tag, rcs);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
Scratch_Entry (entries, file);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
else
|
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);
|
(void) sprintf (tmp, "%s/%s", repository, CVSATTIC);
|
||||||
omask = umask (2);
|
omask = umask (2);
|
||||||
(void) mkdir (tmp, 0777);
|
(void) mkdir (tmp, 0777);
|
||||||
(void) umask (omask);
|
(void) umask (omask);
|
||||||
(void) sprintf (tmp, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
|
(void) sprintf (tmp, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
|
||||||
|
|
||||||
|
|
||||||
if ((strcmp (rcs, tmp) == 0 || rename (rcs, tmp) != -1) ||
|
if ((strcmp (rcs, tmp) == 0 || rename (rcs, tmp) != -1) ||
|
||||||
(!isreadable (rcs) && isreadable (tmp)))
|
(!isreadable (rcs) && isreadable (tmp)))
|
||||||
{
|
{
|
||||||
Scratch_Entry (entries, file);
|
Scratch_Entry (entries, file);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -919,10 +1066,11 @@ remove_file (file, repository, tag, entries)
|
|||||||
* Do the actual checkin for added files
|
* Do the actual checkin for added files
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
finaladd (file, rev, tag, repository, entries)
|
finaladd (file, rev, tag, options, repository, entries)
|
||||||
char *file;
|
char *file;
|
||||||
char *rev;
|
char *rev;
|
||||||
char *tag;
|
char *tag;
|
||||||
|
char *options;
|
||||||
char *repository;
|
char *repository;
|
||||||
List *entries;
|
List *entries;
|
||||||
{
|
{
|
||||||
@ -931,7 +1079,7 @@ finaladd (file, rev, tag, repository, entries)
|
|||||||
char rcs[PATH_MAX];
|
char rcs[PATH_MAX];
|
||||||
|
|
||||||
locate_rcs (file, repository, rcs);
|
locate_rcs (file, repository, rcs);
|
||||||
ret = Checkin ('A', file, repository, rcs, rev, tag,
|
ret = Checkin ('A', file, repository, rcs, rev, tag, options,
|
||||||
message, entries);
|
message, entries);
|
||||||
if (ret == 0)
|
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
|
* with a tag, put the file in the Attic and point the symbolic tag
|
||||||
* at the committed revision.
|
* at the committed revision.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
checkaddfile (file, repository, tag)
|
checkaddfile (file, repository, tag, srcfiles)
|
||||||
char *file;
|
char *file;
|
||||||
char *repository;
|
char *repository;
|
||||||
char *tag;
|
char *tag;
|
||||||
|
List *srcfiles;
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *cp;
|
char *cp;
|
||||||
char rcs[PATH_MAX];
|
char rcs[PATH_MAX];
|
||||||
char fname[PATH_MAX];
|
char fname[PATH_MAX];
|
||||||
int omask;
|
mode_t omask;
|
||||||
int retcode = 0;
|
int retcode = 0;
|
||||||
|
|
||||||
if (tag)
|
if (tag)
|
||||||
{
|
{
|
||||||
(void) sprintf(rcs, "%s/%s", repository, CVSATTIC);
|
(void) sprintf(rcs, "%s/%s", repository, CVSATTIC);
|
||||||
omask = umask (2);
|
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) umask (omask);
|
||||||
(void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
|
(void) sprintf (rcs, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT);
|
||||||
}
|
}
|
||||||
@ -1045,7 +1196,7 @@ checkaddfile (file, repository, tag)
|
|||||||
fp = open_file (fname, "r");
|
fp = open_file (fname, "r");
|
||||||
while (fgets (fname, sizeof (fname), fp) != NULL)
|
while (fgets (fname, sizeof (fname), fp) != NULL)
|
||||||
{
|
{
|
||||||
if ((cp = rindex (fname, '\n')) != NULL)
|
if ((cp = strrchr (fname, '\n')) != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
if (*fname)
|
if (*fname)
|
||||||
run_arg (fname);
|
run_arg (fname);
|
||||||
@ -1058,6 +1209,7 @@ checkaddfile (file, repository, tag)
|
|||||||
"could not create %s", rcs);
|
"could not create %s", rcs);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
fix_rcs_modes (rcs, file);
|
fix_rcs_modes (rcs, file);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1207,9 +1359,26 @@ ci_delproc (p)
|
|||||||
free (ci->rev);
|
free (ci->rev);
|
||||||
if (ci->tag)
|
if (ci->tag)
|
||||||
free (ci->tag);
|
free (ci->tag);
|
||||||
|
if (ci->options)
|
||||||
|
free (ci->options);
|
||||||
free (ci);
|
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.
|
* Find an RCS file in the repository.
|
||||||
*/
|
*/
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
* Create Administration.
|
||||||
*
|
*
|
||||||
@ -14,7 +14,8 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -31,9 +32,6 @@ Create_Admin (dir, repository, tag, date)
|
|||||||
if (noexec)
|
if (noexec)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!isdir (repository))
|
|
||||||
error (1, 0, "there is no repository %s", repository);
|
|
||||||
|
|
||||||
if (dir != NULL)
|
if (dir != NULL)
|
||||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM);
|
(void) sprintf (tmp, "%s/%s", dir, CVSADM);
|
||||||
else
|
else
|
||||||
@ -58,6 +56,11 @@ Create_Admin (dir, repository, tag, date)
|
|||||||
(void) strcpy (tmp, CVSADM);
|
(void) strcpy (tmp, CVSADM);
|
||||||
make_directory (tmp);
|
make_directory (tmp);
|
||||||
|
|
||||||
|
#ifdef CVSADM_ROOT
|
||||||
|
/* record the current cvs root for later use */
|
||||||
|
|
||||||
|
Create_Root (dir, CVSroot);
|
||||||
|
#endif /* CVSADM_ROOT */
|
||||||
if (dir != NULL)
|
if (dir != NULL)
|
||||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
|
(void) sprintf (tmp, "%s/%s", dir, CVSADM_REP);
|
||||||
else
|
else
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
.ds Rv \\$3
|
.ds Rv \\$3
|
||||||
.ds Dt \\$4
|
.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"
|
.TH CVS 1 "\*(Dt"
|
||||||
.\" Full space in nroff; half space in troff
|
.\" Full space in nroff; half space in troff
|
||||||
.de SP
|
.de SP
|
||||||
@ -181,8 +181,10 @@ Use
|
|||||||
.I editor
|
.I editor
|
||||||
to enter revision log information.
|
to enter revision log information.
|
||||||
Overrides the setting of the
|
Overrides the setting of the
|
||||||
|
.SM CVSEDITOR
|
||||||
|
and the
|
||||||
.SM EDITOR
|
.SM EDITOR
|
||||||
environment variable.
|
environment variables.
|
||||||
.TP
|
.TP
|
||||||
.B \-l
|
.B \-l
|
||||||
Do not log the
|
Do not log the
|
||||||
@ -206,7 +208,7 @@ activity. Particularly useful with
|
|||||||
to explore the potential impact of an unfamiliar command.
|
to explore the potential impact of an unfamiliar command.
|
||||||
.TP
|
.TP
|
||||||
.B \-r
|
.B \-r
|
||||||
Makes new working files files read-only.
|
Makes new working files read-only.
|
||||||
Same effect as if the
|
Same effect as if the
|
||||||
.SM CVSREAD
|
.SM CVSREAD
|
||||||
environment variable is set.
|
environment variable is set.
|
||||||
@ -388,7 +390,7 @@ same date (unless you explicitly override it; see the description of
|
|||||||
the \fBupdate\fP command).
|
the \fBupdate\fP command).
|
||||||
.B \-D
|
.B \-D
|
||||||
is available with the
|
is available with the
|
||||||
.BR checkout ", " diff, ", " history ", " export ", "
|
.BR checkout ", " diff ", " history ", " export ", "
|
||||||
.BR rdiff ", " rtag ", and "
|
.BR rdiff ", " rtag ", and "
|
||||||
.B update
|
.B update
|
||||||
commands.
|
commands.
|
||||||
@ -437,7 +439,7 @@ options described in
|
|||||||
.BR rcs ( 1 )
|
.BR rcs ( 1 )
|
||||||
are available. The \fB\-k\fP option is available with the
|
are available. The \fB\-k\fP option is available with the
|
||||||
.BR add ", " checkout ", " diff ", "
|
.BR add ", " checkout ", " diff ", "
|
||||||
.RB rdiff ", and " update
|
.BR rdiff ", and " update
|
||||||
commands. Your \fIkflag\fP specification is ``sticky'' when you use
|
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
|
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,
|
this option with the \fBcheckout\fP or \fBupdate\fP commands,
|
||||||
@ -911,6 +913,13 @@ changed; you can use the
|
|||||||
option to limit
|
option to limit
|
||||||
.B commit
|
.B commit
|
||||||
to the current directory only.
|
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
|
.SP
|
||||||
.B commit
|
.B commit
|
||||||
verifies that the selected files are up to date with the current revisions
|
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
|
You can instead specify the log message on the command line with the
|
||||||
.B \-m
|
.B \-m
|
||||||
option, thus suppressing the editor invocation, or use the
|
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.
|
option to specify that the argument \fIfile\fP contains the log message.
|
||||||
.SP
|
.SP
|
||||||
The
|
The
|
||||||
@ -960,7 +969,8 @@ number of dots) with the
|
|||||||
.B \-r
|
.B \-r
|
||||||
option.
|
option.
|
||||||
To create a branch revision, one typically use the
|
To create a branch revision, one typically use the
|
||||||
.B \-b option of the
|
.B \-b
|
||||||
|
option of the
|
||||||
.BR rtag " or " tag
|
.BR rtag " or " tag
|
||||||
commands.
|
commands.
|
||||||
Then, either
|
Then, either
|
||||||
@ -1144,7 +1154,7 @@ Report on checked-out modules.
|
|||||||
.B \ \ \ \ \ \ \-T
|
.B \ \ \ \ \ \ \-T
|
||||||
Report on all tags.
|
Report on all tags.
|
||||||
.TP 1i
|
.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
|
Extract a particular set of record types \fIX\fP from the \fBcvs\fP
|
||||||
history. The types are indicated by single letters, which you may
|
history. The types are indicated by single letters, which you may
|
||||||
specify in combination.
|
specify in combination.
|
||||||
@ -1162,6 +1172,18 @@ added; and `R', when a file is removed.
|
|||||||
.B \ \ \ \ \ \ \-e
|
.B \ \ \ \ \ \ \-e
|
||||||
Everything (all record types); equivalent to specifying
|
Everything (all record types); equivalent to specifying
|
||||||
.` "\-xMACFROGWUT".
|
.` "\-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
|
.PP
|
||||||
.RS .5i
|
.RS .5i
|
||||||
The options shown as \fB\-\fP\fIflags\fP constrain the report without
|
The options shown as \fB\-\fP\fIflags\fP constrain the report without
|
||||||
@ -1260,8 +1282,8 @@ CVS* cvslog.*
|
|||||||
tags TAGS
|
tags TAGS
|
||||||
\&.make.state .nse_depinfo
|
\&.make.state .nse_depinfo
|
||||||
*~ #* .#* ,*
|
*~ #* .#* ,*
|
||||||
*.old *.bak *.orig *.rej .del\-*
|
*.old *.bak *.BAK *.orig *.rej .del\-*
|
||||||
*.a *.o *.Z *.elc *.ln core
|
*.a *.o *.so *.Z *.elc *.ln core
|
||||||
.fi
|
.fi
|
||||||
.ft P
|
.ft P
|
||||||
.in -1i
|
.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
|
\fB\-m\fP, your editor is invoked (as with \fBcommit\fP) to allow you
|
||||||
to enter one.
|
to enter one.
|
||||||
.SP
|
.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
|
.SP
|
||||||
Use
|
Use
|
||||||
.` "\-b \fIbranch\fP"
|
.` "\-b \fIbranch\fP"
|
||||||
@ -1481,7 +1508,7 @@ into the
|
|||||||
.` "Attic"
|
.` "Attic"
|
||||||
directory (also within the source repository).
|
directory (also within the source repository).
|
||||||
.SP
|
.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
|
files that it finds for removal by the next
|
||||||
.BR commit .
|
.BR commit .
|
||||||
Use the
|
Use the
|
||||||
@ -1546,7 +1573,7 @@ option to have
|
|||||||
.B rtag
|
.B rtag
|
||||||
look in the
|
look in the
|
||||||
.` "Attic"
|
.` "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
|
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
|
symbolic tag as development continues (and files get removed from the
|
||||||
up-coming distribution).
|
up-coming distribution).
|
||||||
@ -1796,8 +1823,8 @@ CVS* cvslog.*
|
|||||||
tags TAGS
|
tags TAGS
|
||||||
\&.make.state .nse_depinfo
|
\&.make.state .nse_depinfo
|
||||||
*~ #* .#* ,*
|
*~ #* .#* ,*
|
||||||
*.old *.bak *.orig *.rej .del\-*
|
*.old *.bak *.BAK *.orig *.rej .del\-*
|
||||||
*.a *.o *.Z *.elc *.ln core
|
*.a *.o *.so *.Z *.elc *.ln core
|
||||||
.fi
|
.fi
|
||||||
.ft P
|
.ft P
|
||||||
.in -1i
|
.in -1i
|
||||||
@ -1881,7 +1908,7 @@ Records programs for piping
|
|||||||
log entries.
|
log entries.
|
||||||
.TP
|
.TP
|
||||||
CVSROOT/rcsinfo,v
|
CVSROOT/rcsinfo,v
|
||||||
Records pathnames to templates used dueing a
|
Records pathnames to templates used during a
|
||||||
.` "cvs commit"
|
.` "cvs commit"
|
||||||
operation.
|
operation.
|
||||||
.TP
|
.TP
|
||||||
@ -1946,10 +1973,15 @@ and
|
|||||||
If not set, a compiled-in value is used; see the display from
|
If not set, a compiled-in value is used; see the display from
|
||||||
.` "cvs \-v".
|
.` "cvs \-v".
|
||||||
.TP
|
.TP
|
||||||
.SM EDITOR
|
.SM CVSEDITOR
|
||||||
Specifies the program to use for recording log messages during
|
Specifies the program to use for recording log messages during
|
||||||
.BR commit .
|
.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 .
|
.BR /usr/ucb/vi .
|
||||||
.SH "AUTHORS"
|
.SH "AUTHORS"
|
||||||
.TP
|
.TP
|
||||||
|
@ -243,7 +243,7 @@ removed by this \fBcommit\fP invocation.
|
|||||||
.SP
|
.SP
|
||||||
For `\|commitinfo\|', the rest of the line is a command-line template to
|
For `\|commitinfo\|', the rest of the line is a command-line template to
|
||||||
execute.
|
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.
|
list of arguments you wish.
|
||||||
The full path to the current source repository is appended to the template,
|
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,
|
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
|
.SP
|
||||||
For `\|editinfo\|', the rest of the line is a command-line template to
|
For `\|editinfo\|', the rest of the line is a command-line template to
|
||||||
execute.
|
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.
|
list of arguments you wish.
|
||||||
The full path to the current log message template file is appended to the
|
The full path to the current log message template file is appended to the
|
||||||
template.
|
template.
|
||||||
|
@ -1,35 +1,30 @@
|
|||||||
/* @(#)cvs.h 1.72 92/03/31 */
|
/* $CVSid: @(#)cvs.h 1.86 94/10/22 $ */
|
||||||
|
|
||||||
#include "system.h"
|
/*
|
||||||
#include <stdio.h>
|
* basic information used in all source files
|
||||||
#include <ctype.h>
|
*
|
||||||
#include <pwd.h>
|
*/
|
||||||
#include <signal.h>
|
|
||||||
#include "hash.h"
|
|
||||||
#include "rcs.h"
|
|
||||||
#include "regex.h"
|
|
||||||
#include "fnmatch.h"
|
|
||||||
#include "getopt.h"
|
|
||||||
#include "wait.h"
|
|
||||||
#include "config.h"
|
|
||||||
#ifdef MY_NDBM
|
|
||||||
#include "myndbm.h"
|
|
||||||
#else
|
|
||||||
#include <ndbm.h>
|
|
||||||
#endif /* !MY_NDBM */
|
|
||||||
|
|
||||||
/* XXX - for now this is static */
|
|
||||||
#undef PATH_MAX
|
|
||||||
#ifdef MAXPATHLEN
|
|
||||||
#define PATH_MAX MAXPATHLEN+2
|
|
||||||
#else
|
|
||||||
#define PATH_MAX 1024+2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* just in case this implementation does not define this */
|
#include "config.h" /* this is stuff found via autoconf */
|
||||||
#ifndef L_tmpnam
|
#include "options.h" /* these are some larger questions which
|
||||||
#define L_tmpnam 50
|
can't easily be automatically checked
|
||||||
#endif
|
for */
|
||||||
|
|
||||||
|
/* AIX requires this to be the first thing in the file. */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define alloca __builtin_alloca
|
||||||
|
#else /* not __GNUC__ */
|
||||||
|
#if HAVE_ALLOCA_H
|
||||||
|
#include <alloca.h>
|
||||||
|
#else /* not HAVE_ALLOCA_H */
|
||||||
|
#ifdef _AIX
|
||||||
|
#pragma alloca
|
||||||
|
#else /* not _AIX */
|
||||||
|
char *alloca ();
|
||||||
|
#endif /* not _AIX */
|
||||||
|
#endif /* not HAVE_ALLOCA_H */
|
||||||
|
#endif /* not __GNUC__ */
|
||||||
|
|
||||||
#if __STDC__
|
#if __STDC__
|
||||||
#define CONST const
|
#define CONST const
|
||||||
@ -39,12 +34,86 @@
|
|||||||
#define PTR char *
|
#define PTR char *
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Add prototype support. */
|
||||||
|
#ifndef PROTO
|
||||||
|
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
|
||||||
|
#define PROTO(ARGS) ARGS
|
||||||
|
#else
|
||||||
|
#define PROTO(ARGS) ()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if __GNUC__ == 2
|
||||||
|
#define USE(var) static char sizeof##var = sizeof(sizeof##var) + sizeof(var);
|
||||||
|
#else
|
||||||
|
#define USE(var)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_UNISTD_H
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_STRING_H
|
||||||
|
#include <string.h>
|
||||||
|
#else
|
||||||
|
#include <strings.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <fnmatch.h> /* This is supposed to be available on Posix systems */
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_ERRNO_H
|
||||||
|
#include <errno.h>
|
||||||
|
#else
|
||||||
|
#ifndef errno
|
||||||
|
extern int errno;
|
||||||
|
#endif /* !errno */
|
||||||
|
#endif /* HAVE_ERRNO_H */
|
||||||
|
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#include "hash.h"
|
||||||
|
|
||||||
|
#ifdef MY_NDBM
|
||||||
|
#include "myndbm.h"
|
||||||
|
#else
|
||||||
|
#include <ndbm.h>
|
||||||
|
#endif /* MY_NDBM */
|
||||||
|
|
||||||
|
#include "regex.h"
|
||||||
|
#include "getopt.h"
|
||||||
|
#include "wait.h"
|
||||||
|
|
||||||
|
#include "rcs.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* XXX - for now this is static */
|
||||||
|
#ifndef PATH_MAX
|
||||||
|
#ifdef MAXPATHLEN
|
||||||
|
#define PATH_MAX MAXPATHLEN+2
|
||||||
|
#else
|
||||||
|
#define PATH_MAX 1024+2
|
||||||
|
#endif
|
||||||
|
#endif /* PATH_MAX */
|
||||||
|
|
||||||
|
/* just in case this implementation does not define this */
|
||||||
|
#ifndef L_tmpnam
|
||||||
|
#define L_tmpnam 50
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
||||||
*
|
*
|
||||||
* Definitions for the CVS Administrative directory and the files it contains.
|
* Definitions for the CVS Administrative directory and the files it contains.
|
||||||
* Here as #define's to make changing the names a simple task.
|
* Here as #define's to make changing the names a simple task.
|
||||||
@ -54,6 +123,7 @@
|
|||||||
#define CVSADM_ENTBAK "CVS/Entries.Backup"
|
#define CVSADM_ENTBAK "CVS/Entries.Backup"
|
||||||
#define CVSADM_ENTSTAT "CVS/Entries.Static"
|
#define CVSADM_ENTSTAT "CVS/Entries.Static"
|
||||||
#define CVSADM_REP "CVS/Repository"
|
#define CVSADM_REP "CVS/Repository"
|
||||||
|
#define CVSADM_ROOT "CVS/Root"
|
||||||
#define CVSADM_CIPROG "CVS/Checkin.prog"
|
#define CVSADM_CIPROG "CVS/Checkin.prog"
|
||||||
#define CVSADM_UPROG "CVS/Update.prog"
|
#define CVSADM_UPROG "CVS/Update.prog"
|
||||||
#define CVSADM_TAG "CVS/Tag"
|
#define CVSADM_TAG "CVS/Tag"
|
||||||
@ -80,6 +150,7 @@
|
|||||||
#define CVSROOTADM_EDITINFO "editinfo"
|
#define CVSROOTADM_EDITINFO "editinfo"
|
||||||
#define CVSROOTADM_HISTORY "history"
|
#define CVSROOTADM_HISTORY "history"
|
||||||
#define CVSROOTADM_IGNORE "cvsignore"
|
#define CVSROOTADM_IGNORE "cvsignore"
|
||||||
|
#define CVSROOTADM_CHECKOUTLIST "checkoutlist"
|
||||||
#define CVSNULLREPOS "Emptydir" /* an empty directory */
|
#define CVSNULLREPOS "Emptydir" /* an empty directory */
|
||||||
|
|
||||||
/* support for the modules file (CVSROOTADM_MODULES) */
|
/* support for the modules file (CVSROOTADM_MODULES) */
|
||||||
@ -98,6 +169,7 @@
|
|||||||
#define CVSTFL "#cvs.tfl"
|
#define CVSTFL "#cvs.tfl"
|
||||||
#define CVSRFL "#cvs.rfl"
|
#define CVSRFL "#cvs.rfl"
|
||||||
#define CVSWFL "#cvs.wfl"
|
#define CVSWFL "#cvs.wfl"
|
||||||
|
#define CVSRFLPAT "#cvs.rfl.*" /* wildcard expr to match read locks */
|
||||||
#define CVSEXT_OPT ",p"
|
#define CVSEXT_OPT ",p"
|
||||||
#define CVSEXT_LOG ",t"
|
#define CVSEXT_LOG ",t"
|
||||||
#define CVSPREFIX ",,"
|
#define CVSPREFIX ",,"
|
||||||
@ -129,7 +201,8 @@
|
|||||||
#define RCSBIN_ENV "RCSBIN" /* RCS binary directory */
|
#define RCSBIN_ENV "RCSBIN" /* RCS binary directory */
|
||||||
/* #define RCSBIN_DFLT Set by config.h */
|
/* #define RCSBIN_DFLT Set by config.h */
|
||||||
|
|
||||||
#define EDITOR_ENV "EDITOR" /* which editor to use */
|
#define EDITOR1_ENV "CVSEDITOR" /* which editor to use */
|
||||||
|
#define EDITOR2_ENV "EDITOR" /* which editor to use */
|
||||||
/* #define EDITOR_DFLT Set by config.h */
|
/* #define EDITOR_DFLT Set by config.h */
|
||||||
|
|
||||||
#define CVSROOT_ENV "CVSROOT" /* source directory root */
|
#define CVSROOT_ENV "CVSROOT" /* source directory root */
|
||||||
@ -154,7 +227,6 @@
|
|||||||
#define MAXLINELEN 5000 /* max input line from a file */
|
#define MAXLINELEN 5000 /* max input line from a file */
|
||||||
#define MAXPROGLEN 30000 /* max program length to system() */
|
#define MAXPROGLEN 30000 /* max program length to system() */
|
||||||
#define MAXLISTLEN 40000 /* For [A-Z]list holders */
|
#define MAXLISTLEN 40000 /* For [A-Z]list holders */
|
||||||
#define MAXMESGLEN 10000 /* max RCS log message size */
|
|
||||||
#define MAXDATELEN 50 /* max length for a date */
|
#define MAXDATELEN 50 /* max length for a date */
|
||||||
|
|
||||||
/* The type of request that is being done in do_module() */
|
/* The type of request that is being done in do_module() */
|
||||||
@ -198,12 +270,13 @@ struct vers_ts
|
|||||||
* empty = no user file
|
* empty = no user file
|
||||||
* 0 = user file is new
|
* 0 = user file is new
|
||||||
* -vers = user file to be removed */
|
* -vers = user file to be removed */
|
||||||
char *vn_rcs; /* the verion for the rcs file
|
char *vn_rcs; /* the version for the rcs file
|
||||||
* (tag version?) */
|
* (tag version?) */
|
||||||
char *ts_user; /* the timestamp for the user file */
|
char *ts_user; /* the timestamp for the user file */
|
||||||
char *ts_rcs; /* the user timestamp from entries */
|
char *ts_rcs; /* the user timestamp from entries */
|
||||||
char *options; /* opts from Entries file
|
char *options; /* opts from Entries file
|
||||||
* (keyword expansion) */
|
* (keyword expansion) */
|
||||||
|
char *ts_conflict; /* Holds time_stamp of conflict */
|
||||||
char *tag; /* tag stored in the Entries file */
|
char *tag; /* tag stored in the Entries file */
|
||||||
char *date; /* date stored in the Entries file */
|
char *date; /* date stored in the Entries file */
|
||||||
Entnode *entdata; /* pointer to entries file node */
|
Entnode *entdata; /* pointer to entries file node */
|
||||||
@ -249,190 +322,126 @@ typedef enum direnter_type Dtype;
|
|||||||
|
|
||||||
extern char *program_name, *command_name;
|
extern char *program_name, *command_name;
|
||||||
extern char *Rcsbin, *Editor, *CVSroot;
|
extern char *Rcsbin, *Editor, *CVSroot;
|
||||||
|
#ifdef CVSADM_ROOT
|
||||||
|
extern char *CVSADM_Root;
|
||||||
|
extern int cvsadmin_root;
|
||||||
|
#endif /* CVSADM_ROOT */
|
||||||
extern char *CurDir;
|
extern char *CurDir;
|
||||||
extern int really_quiet, quiet;
|
extern int really_quiet, quiet;
|
||||||
extern int use_editor;
|
extern int use_editor;
|
||||||
extern int cvswrite;
|
extern int cvswrite;
|
||||||
|
|
||||||
extern int trace; /* Show all commands */
|
extern int trace; /* Show all commands */
|
||||||
extern int noexec; /* Don't modify disk anywhere */
|
extern int noexec; /* Don't modify disk anywhere */
|
||||||
extern int logoff; /* Don't write history entry */
|
extern int logoff; /* Don't write history entry */
|
||||||
|
|
||||||
/* Externs that are included directly in the CVS sources */
|
/* Externs that are included directly in the CVS sources */
|
||||||
#if __STDC__
|
DBM *open_module PROTO((void));
|
||||||
int Reader_Lock (char *xrepository);
|
FILE *Fopen PROTO((char *name, char *mode));
|
||||||
DBM *open_module (void);
|
FILE *open_file PROTO((char *name, char *mode));
|
||||||
FILE *Fopen (char *name, char *mode);
|
List *Find_Dirs PROTO((char *repository, int which));
|
||||||
FILE *open_file (char *name, char *mode);
|
List *ParseEntries PROTO((int aflag));
|
||||||
List *Find_Dirs (char *repository, int which);
|
char *Make_Date PROTO((char *rawdate));
|
||||||
List *ParseEntries (int aflag);
|
char *Name_Repository PROTO((char *dir, char *update_dir));
|
||||||
char *Make_Date (char *rawdate);
|
#ifdef CVSADM_ROOT
|
||||||
char *Name_Repository (char *dir, char *update_dir);
|
char *Name_Root PROTO((char *dir, char *update_dir));
|
||||||
char *Short_Repository (char *repository);
|
void Create_Root PROTO((char *dir, char *rootdir));
|
||||||
char *getcaller (void);
|
int same_directories PROTO((char *dir1, char *dir2));
|
||||||
char *time_stamp (char *file);
|
#endif /* CVSADM_ROOT */
|
||||||
char *xmalloc (int bytes);
|
char *Short_Repository PROTO((char *repository));
|
||||||
char *xrealloc (char *ptr, int bytes);
|
char *gca PROTO((char *rev1, char *rev2));
|
||||||
char *xstrdup (char *str);
|
char *getcaller PROTO((void));
|
||||||
int No_Difference (char *file, Vers_TS * vers, List * entries);
|
char *time_stamp PROTO((char *file));
|
||||||
int Parse_Info (char *infofile, char *repository, int (*callproc) (), int all);
|
char *xmalloc PROTO((size_t bytes));
|
||||||
int Reader_Lock (char *xrepository);
|
char *xrealloc PROTO((char *ptr, size_t bytes));
|
||||||
int SIG_register (int sig, SIGTYPE (*fn) ());
|
char *xstrdup PROTO((char *str));
|
||||||
int Writer_Lock (List * list);
|
int No_Difference PROTO((char *file, Vers_TS * vers, List * entries,
|
||||||
int gethostname (char *name, int namelen);
|
char *repository, char *update_dir));
|
||||||
int ign_name (char *name);
|
int Parse_Info PROTO((char *infofile, char *repository, int PROTO((*callproc)) PROTO(()), int all));
|
||||||
int isdir (char *file);
|
int Reader_Lock PROTO((char *xrepository));
|
||||||
int isfile (char *file);
|
int SIG_register PROTO((int sig, RETSIGTYPE PROTO((*fn)) PROTO(())));
|
||||||
int islink (char *file);
|
int Writer_Lock PROTO((List * list));
|
||||||
int isreadable (char *file);
|
int ign_name PROTO((char *name));
|
||||||
int iswritable (char *file);
|
int isdir PROTO((char *file));
|
||||||
int link_file (char *from, char *to);
|
int isfile PROTO((char *file));
|
||||||
int numdots (char *s);
|
int islink PROTO((char *file));
|
||||||
int run_exec (char *stin, char *stout, char *sterr, int flags);
|
int isreadable PROTO((char *file));
|
||||||
int unlink_file (char *f);
|
int iswritable PROTO((char *file));
|
||||||
int update (int argc, char *argv[]);
|
int joining PROTO((void));
|
||||||
int xcmp (char *file1, char *file2);
|
int link_file PROTO((char *from, char *to));
|
||||||
int yesno (void);
|
int numdots PROTO((char *s));
|
||||||
time_t get_date (char *date, struct timeb *now);
|
int run_exec PROTO((char *stin, char *stout, char *sterr, int flags));
|
||||||
void Create_Admin (char *dir, char *repository, char *tag, char *date);
|
int unlink_file PROTO((char *f));
|
||||||
void Lock_Cleanup (void);
|
int update PROTO((int argc, char *argv[]));
|
||||||
void ParseTag (char **tagp, char **datep);
|
int xcmp PROTO((char *file1, char *file2));
|
||||||
void Scratch_Entry (List * list, char *fname);
|
int yesno PROTO((void));
|
||||||
void WriteTag (char *dir, char *tag, char *date);
|
time_t get_date PROTO((char *date, struct timeb *now));
|
||||||
void cat_module (int status);
|
void Create_Admin PROTO((char *dir, char *repository, char *tag, char *date));
|
||||||
void check_entries (char *dir);
|
void Lock_Cleanup PROTO((void));
|
||||||
void close_module (DBM * db);
|
void ParseTag PROTO((char **tagp, char **datep));
|
||||||
void copy_file (char *from, char *to);
|
void Scratch_Entry PROTO((List * list, char *fname));
|
||||||
void error (int status, int errnum, char *message,...);
|
void WriteTag PROTO((char *dir, char *tag, char *date));
|
||||||
void fperror (FILE * fp, int status, int errnum, char *message,...);
|
void cat_module PROTO((int status));
|
||||||
void free_names (int *pargc, char *argv[]);
|
void check_entries PROTO((char *dir));
|
||||||
void freevers_ts (Vers_TS ** versp);
|
void close_module PROTO((DBM * db));
|
||||||
void ign_add (char *ign, int hold);
|
void copy_file PROTO((char *from, char *to));
|
||||||
void ign_add_file (char *file, int hold);
|
void error PROTO((int status, int errnum, char *message,...));
|
||||||
void ign_setup (void);
|
void fperror PROTO((FILE * fp, int status, int errnum, char *message,...));
|
||||||
void line2argv (int *pargc, char *argv[], char *line);
|
void free_names PROTO((int *pargc, char *argv[]));
|
||||||
void make_directories (char *name);
|
void freevers_ts PROTO((Vers_TS ** versp));
|
||||||
void make_directory (char *name);
|
void ign_add PROTO((char *ign, int hold));
|
||||||
void rename_file (char *from, char *to);
|
void ign_add_file PROTO((char *file, int hold));
|
||||||
void run_arg (char *s);
|
void ign_setup PROTO((void));
|
||||||
void run_args (char *fmt,...);
|
void ign_dir_add PROTO((char *name));
|
||||||
void run_print (FILE * fp);
|
int ignore_directory PROTO((char *name));
|
||||||
void run_setup (char *fmt,...);
|
void line2argv PROTO((int *pargc, char *argv[], char *line));
|
||||||
void strip_path (char *path);
|
void make_directories PROTO((char *name));
|
||||||
void update_delproc (Node * p);
|
void make_directory PROTO((char *name));
|
||||||
void usage (char **cpp);
|
void rename_file PROTO((char *from, char *to));
|
||||||
void xchmod (char *fname, int writable);
|
void run_arg PROTO((char *s));
|
||||||
int Checkin (int type, char *file, char *repository, char *rcs, char *rev,
|
void run_args PROTO((char *fmt,...));
|
||||||
char *tag, char *message, List * entries);
|
void run_print PROTO((FILE * fp));
|
||||||
Ctype Classify_File (char *file, char *tag, char *date, char *options,
|
void run_setup PROTO((char *fmt,...));
|
||||||
|
void strip_path PROTO((char *path));
|
||||||
|
void strip_trailing_slashes PROTO((char *path));
|
||||||
|
void update_delproc PROTO((Node * p));
|
||||||
|
void usage PROTO((char **cpp));
|
||||||
|
void xchmod PROTO((char *fname, int writable));
|
||||||
|
int Checkin PROTO((int type, char *file, char *repository, char *rcs, char *rev,
|
||||||
|
char *tag, char *options, char *message, List *entries));
|
||||||
|
Ctype Classify_File PROTO((char *file, char *tag, char *date, char *options,
|
||||||
int force_tag_match, int aflag, char *repository,
|
int force_tag_match, int aflag, char *repository,
|
||||||
List *entries, List *srcfiles, Vers_TS **versp);
|
List *entries, List *srcfiles, Vers_TS **versp,
|
||||||
List *Find_Names (char *repository, int which, int aflag,
|
char *update_dir, int pipeout));
|
||||||
List ** optentries);
|
List *Find_Names PROTO((char *repository, int which, int aflag,
|
||||||
void Register (List * list, char *fname, char *vn, char *ts,
|
List ** optentries));
|
||||||
char *options, char *tag, char *date);
|
void Register PROTO((List * list, char *fname, char *vn, char *ts,
|
||||||
void Update_Logfile (char *repository, char *xmessage, char *xrevision,
|
char *options, char *tag, char *date, char *ts_conflict));
|
||||||
FILE * xlogfp, List * xchanges);
|
void Update_Logfile PROTO((char *repository, char *xmessage, char *xrevision,
|
||||||
Vers_TS *Version_TS (char *repository, char *options, char *tag,
|
FILE * xlogfp, List * xchanges));
|
||||||
|
Vers_TS *Version_TS PROTO((char *repository, char *options, char *tag,
|
||||||
char *date, char *user, int force_tag_match,
|
char *date, char *user, int force_tag_match,
|
||||||
int set_time, List * entries, List * xfiles);
|
int set_time, List * entries, List * xfiles));
|
||||||
void do_editor (char *dir, char *message, char *repository,
|
void do_editor PROTO((char *dir, char **messagep,
|
||||||
List * changes);
|
char *repository, List * changes));
|
||||||
int do_module (DBM * db, char *mname, enum mtype m_type, char *msg,
|
int do_module PROTO((DBM * db, char *mname, enum mtype m_type, char *msg,
|
||||||
int (*callback_proc) (), char *where, int shorten,
|
int PROTO((*callback_proc)) (), char *where, int shorten,
|
||||||
int local_specified, int run_module_prog, char *extra_arg);
|
int local_specified, int run_module_prog, char *extra_arg));
|
||||||
int do_recursion (int (*xfileproc) (), int (*xfilesdoneproc) (),
|
int do_recursion PROTO((int PROTO((*xfileproc)) (), int PROTO((*xfilesdoneproc)) (),
|
||||||
Dtype (*xdirentproc) (), int (*xdirleaveproc) (),
|
Dtype PROTO((*xdirentproc)) (), int PROTO((*xdirleaveproc)) (),
|
||||||
Dtype xflags, int xwhich, int xaflag, int xreadlock,
|
Dtype xflags, int xwhich, int xaflag, int xreadlock,
|
||||||
int xdosrcs);
|
int xdosrcs));
|
||||||
int do_update (int argc, char *argv[], char *xoptions, char *xtag,
|
int do_update PROTO((int argc, char *argv[], char *xoptions, char *xtag,
|
||||||
char *xdate, int xforce, int local, int xbuild,
|
char *xdate, int xforce, int local, int xbuild,
|
||||||
int xaflag, int xprune, int xpipeout, int which,
|
int xaflag, int xprune, int xpipeout, int which,
|
||||||
char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir);
|
char *xjoin_rev1, char *xjoin_rev2, char *preload_update_dir));
|
||||||
void history_write (int type, char *update_dir, char *revs, char *name,
|
void history_write PROTO((int type, char *update_dir, char *revs, char *name,
|
||||||
char *repository);
|
char *repository));
|
||||||
int start_recursion (int (*fileproc) (), int (*filesdoneproc) (),
|
int start_recursion PROTO((int PROTO((*fileproc)) (), int PROTO((*filesdoneproc)) (),
|
||||||
Dtype (*direntproc) (), int (*dirleaveproc) (),
|
Dtype PROTO((*direntproc)) (), int PROTO((*dirleaveproc)) (),
|
||||||
int argc, char *argv[], int local, int which,
|
int argc, char *argv[], int local, int which,
|
||||||
int aflag, int readlock, char *update_preload,
|
int aflag, int readlock, char *update_preload,
|
||||||
int dosrcs);
|
int dosrcs, int wd_is_repos));
|
||||||
void SIG_beginCrSect ();
|
void SIG_beginCrSect PROTO((void));
|
||||||
void SIG_endCrSect ();
|
void SIG_endCrSect PROTO((void));
|
||||||
#else /* !__STDC__ */
|
void read_cvsrc PROTO((int *argc, char ***argv));
|
||||||
DBM *open_module ();
|
|
||||||
FILE *Fopen ();
|
|
||||||
FILE *open_file ();
|
|
||||||
List *Find_Dirs ();
|
|
||||||
List *Find_Names ();
|
|
||||||
List *ParseEntries ();
|
|
||||||
Vers_TS *Version_TS ();
|
|
||||||
char *Make_Date ();
|
|
||||||
char *Name_Repository ();
|
|
||||||
char *Short_Repository ();
|
|
||||||
char *getcaller ();
|
|
||||||
char *time_stamp ();
|
|
||||||
char *xmalloc ();
|
|
||||||
char *xrealloc ();
|
|
||||||
char *xstrdup ();
|
|
||||||
int Checkin ();
|
|
||||||
Ctype Classify_File ();
|
|
||||||
int No_Difference ();
|
|
||||||
int Parse_Info ();
|
|
||||||
int Reader_Lock ();
|
|
||||||
int SIG_register ();
|
|
||||||
int Writer_Lock ();
|
|
||||||
int do_module ();
|
|
||||||
int do_recursion ();
|
|
||||||
int do_update ();
|
|
||||||
int gethostname ();
|
|
||||||
int ign_name ();
|
|
||||||
int isdir ();
|
|
||||||
int isfile ();
|
|
||||||
int islink ();
|
|
||||||
int isreadable ();
|
|
||||||
int iswritable ();
|
|
||||||
int link_file ();
|
|
||||||
int numdots ();
|
|
||||||
int run_exec ();
|
|
||||||
int start_recursion ();
|
|
||||||
int unlink_file ();
|
|
||||||
int update ();
|
|
||||||
int xcmp ();
|
|
||||||
int yesno ();
|
|
||||||
time_t get_date ();
|
|
||||||
void Create_Admin ();
|
|
||||||
void Lock_Cleanup ();
|
|
||||||
void ParseTag ();
|
|
||||||
void ParseTag ();
|
|
||||||
void Register ();
|
|
||||||
void Scratch_Entry ();
|
|
||||||
void Update_Logfile ();
|
|
||||||
void WriteTag ();
|
|
||||||
void cat_module ();
|
|
||||||
void check_entries ();
|
|
||||||
void close_module ();
|
|
||||||
void copy_file ();
|
|
||||||
void do_editor ();
|
|
||||||
void error ();
|
|
||||||
void fperror ();
|
|
||||||
void free_names ();
|
|
||||||
void freevers_ts ();
|
|
||||||
void history_write ();
|
|
||||||
void ign_add ();
|
|
||||||
void ign_add_file ();
|
|
||||||
void ign_setup ();
|
|
||||||
void line2argv ();
|
|
||||||
void make_directories ();
|
|
||||||
void make_directory ();
|
|
||||||
void rename_file ();
|
|
||||||
void run_arg ();
|
|
||||||
void run_args ();
|
|
||||||
void run_print ();
|
|
||||||
void run_setup ();
|
|
||||||
void strip_path ();
|
|
||||||
void update_delproc ();
|
|
||||||
void usage ();
|
|
||||||
void xchmod ();
|
|
||||||
void SIG_beginCrSect ();
|
|
||||||
void SIG_endCrSect ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
||||||
*
|
*
|
||||||
* Difference
|
* Difference
|
||||||
*
|
*
|
||||||
@ -17,24 +17,18 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)diff.c 1.52 92/04/10";
|
static char rcsid[] = "$CVSid: @(#)diff.c 1.61 94/10/22 $";
|
||||||
|
USE(rcsid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static Dtype diff_dirproc PROTO((char *dir, char *pos_repos, char *update_dir));
|
||||||
static Dtype diff_dirproc (char *dir, char *pos_repos, char *update_dir);
|
static int diff_filesdoneproc PROTO((int err, char *repos, char *update_dir));
|
||||||
static int diff_dirleaveproc (char *dir, int err, char *update_dir);
|
static int diff_dirleaveproc PROTO((char *dir, int err, char *update_dir));
|
||||||
static int diff_file_nodiff (char *file, char *repository, List *entries,
|
static int diff_file_nodiff PROTO((char *file, char *repository, List *entries,
|
||||||
List *srcfiles, Vers_TS *vers);
|
List *srcfiles, Vers_TS *vers));
|
||||||
static int diff_fileproc (char *file, char *update_dir, char *repository,
|
static int diff_fileproc PROTO((char *file, char *update_dir, char *repository,
|
||||||
List * entries, List * srcfiles);
|
List * entries, List * srcfiles));
|
||||||
static void diff_mark_errors (int err);
|
static void diff_mark_errors PROTO((int err));
|
||||||
#else
|
|
||||||
static int diff_fileproc ();
|
|
||||||
static Dtype diff_dirproc ();
|
|
||||||
static int diff_dirleaveproc ();
|
|
||||||
static int diff_file_nodiff ();
|
|
||||||
static void diff_mark_errors ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char *diff_rev1, *diff_rev2;
|
static char *diff_rev1, *diff_rev2;
|
||||||
static char *diff_date1, *diff_date2;
|
static char *diff_date1, *diff_date2;
|
||||||
@ -42,10 +36,11 @@ static char *use_rev1, *use_rev2;
|
|||||||
static char *options;
|
static char *options;
|
||||||
static char opts[PATH_MAX];
|
static char opts[PATH_MAX];
|
||||||
static int diff_errors;
|
static int diff_errors;
|
||||||
|
static int empty_files = 0;
|
||||||
|
|
||||||
static char *diff_usage[] =
|
static char *diff_usage[] =
|
||||||
{
|
{
|
||||||
"Usage: %s %s [-l] [rcsdiff-options]\n",
|
"Usage: %s %s [-lN] [rcsdiff-options]\n",
|
||||||
#ifdef CVS_DIFFDATE
|
#ifdef CVS_DIFFDATE
|
||||||
" [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files...] \n",
|
" [[-r rev1 | -D date1] [-r rev2 | -D date2]] [files...] \n",
|
||||||
#else
|
#else
|
||||||
@ -54,6 +49,7 @@ static char *diff_usage[] =
|
|||||||
"\t-l\tLocal directory only, not recursive\n",
|
"\t-l\tLocal directory only, not recursive\n",
|
||||||
"\t-D d1\tDiff revision for date against working file.\n",
|
"\t-D d1\tDiff revision for date against working file.\n",
|
||||||
"\t-D d2\tDiff rev1/date1 against date2.\n",
|
"\t-D d2\tDiff rev1/date1 against date2.\n",
|
||||||
|
"\t-N\tinclude diffs for added and removed files.\n",
|
||||||
"\t-r rev1\tDiff revision for rev1 against working file.\n",
|
"\t-r rev1\tDiff revision for rev1 against working file.\n",
|
||||||
"\t-r rev2\tDiff rev1/date1 against rev2.\n",
|
"\t-r rev2\tDiff rev1/date1 against rev2.\n",
|
||||||
NULL
|
NULL
|
||||||
@ -67,6 +63,7 @@ diff (argc, argv)
|
|||||||
char tmp[50];
|
char tmp[50];
|
||||||
int c, err = 0;
|
int c, err = 0;
|
||||||
int local = 0;
|
int local = 0;
|
||||||
|
int which;
|
||||||
|
|
||||||
if (argc == -1)
|
if (argc == -1)
|
||||||
usage (diff_usage);
|
usage (diff_usage);
|
||||||
@ -77,8 +74,8 @@ diff (argc, argv)
|
|||||||
* non-recursive/recursive diff.
|
* non-recursive/recursive diff.
|
||||||
*/
|
*/
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv,
|
while ((c = getopt (argc, argv,
|
||||||
"abcdefhilnpqtuw0123456789BHQRTC:D:F:I:L:V:k:r:")) != -1)
|
"abcdefhilnpqtuw0123456789BHNQRTC:D:F:I:L:V:k:r:")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -137,6 +134,9 @@ diff (argc, argv)
|
|||||||
diff_date1 = Make_Date (optarg);
|
diff_date1 = Make_Date (optarg);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case 'N':
|
||||||
|
empty_files = 1;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage (diff_usage);
|
usage (diff_usage);
|
||||||
@ -150,10 +150,14 @@ diff (argc, argv)
|
|||||||
if (!options)
|
if (!options)
|
||||||
options = xstrdup ("");
|
options = xstrdup ("");
|
||||||
|
|
||||||
|
which = W_LOCAL;
|
||||||
|
if (diff_rev2 != NULL || diff_date2 != NULL)
|
||||||
|
which |= W_REPOS | W_ATTIC;
|
||||||
|
|
||||||
/* start the recursion processor */
|
/* start the recursion processor */
|
||||||
err = start_recursion (diff_fileproc, (int (*) ()) NULL, diff_dirproc,
|
err = start_recursion (diff_fileproc, diff_filesdoneproc, diff_dirproc,
|
||||||
diff_dirleaveproc, argc, argv, local,
|
diff_dirleaveproc, argc, argv, local,
|
||||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
which, 0, 1, (char *) NULL, 1, 0);
|
||||||
|
|
||||||
/* clean up */
|
/* clean up */
|
||||||
free (options);
|
free (options);
|
||||||
@ -174,11 +178,23 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
{
|
{
|
||||||
int status, err = 2; /* 2 == trouble, like rcsdiff */
|
int status, err = 2; /* 2 == trouble, like rcsdiff */
|
||||||
Vers_TS *vers;
|
Vers_TS *vers;
|
||||||
|
enum {
|
||||||
|
DIFF_ERROR,
|
||||||
|
DIFF_ADDED,
|
||||||
|
DIFF_REMOVED,
|
||||||
|
DIFF_NEITHER
|
||||||
|
} empty_file = DIFF_NEITHER;
|
||||||
|
char tmp[L_tmpnam+1];
|
||||||
|
|
||||||
vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
|
vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
|
||||||
file, 1, 0, entries, srcfiles);
|
file, 1, 0, entries, srcfiles);
|
||||||
|
|
||||||
if (vers->vn_user == NULL)
|
if (diff_rev2 != NULL || diff_date2 != NULL)
|
||||||
|
{
|
||||||
|
/* Skip all the following checks regarding the user file; we're
|
||||||
|
not using it. */
|
||||||
|
}
|
||||||
|
else if (vers->vn_user == NULL)
|
||||||
{
|
{
|
||||||
error (0, 0, "I know nothing about %s", file);
|
error (0, 0, "I know nothing about %s", file);
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
@ -187,17 +203,27 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
}
|
}
|
||||||
else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
|
else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
|
||||||
{
|
{
|
||||||
error (0, 0, "%s is a new entry, no comparison available", file);
|
if (empty_files)
|
||||||
freevers_ts (&vers);
|
empty_file = DIFF_ADDED;
|
||||||
diff_mark_errors (err);
|
else
|
||||||
return (err);
|
{
|
||||||
|
error (0, 0, "%s is a new entry, no comparison available", file);
|
||||||
|
freevers_ts (&vers);
|
||||||
|
diff_mark_errors (err);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (vers->vn_user[0] == '-')
|
else if (vers->vn_user[0] == '-')
|
||||||
{
|
{
|
||||||
error (0, 0, "%s was removed, no comparison available", file);
|
if (empty_files)
|
||||||
freevers_ts (&vers);
|
empty_file = DIFF_REMOVED;
|
||||||
diff_mark_errors (err);
|
else
|
||||||
return (err);
|
{
|
||||||
|
error (0, 0, "%s was removed, no comparison available", file);
|
||||||
|
freevers_ts (&vers);
|
||||||
|
diff_mark_errors (err);
|
||||||
|
return (err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -220,25 +246,65 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (diff_file_nodiff (file, repository, entries, srcfiles, vers))
|
if (empty_file == DIFF_NEITHER && diff_file_nodiff (file, repository, entries, srcfiles, vers))
|
||||||
{
|
{
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Output an "Index:" line for patch to use */
|
||||||
(void) fflush (stdout);
|
(void) fflush (stdout);
|
||||||
if (use_rev2)
|
if (update_dir[0])
|
||||||
|
(void) printf ("Index: %s/%s\n", update_dir, file);
|
||||||
|
else
|
||||||
|
(void) printf ("Index: %s\n", file);
|
||||||
|
(void) fflush (stdout);
|
||||||
|
|
||||||
|
if (empty_file == DIFF_ADDED || empty_file == DIFF_REMOVED)
|
||||||
{
|
{
|
||||||
run_setup ("%s%s %s %s -r%s -r%s", Rcsbin, RCS_DIFF,
|
(void) printf ("===================================================================\nRCS file: %s\n",
|
||||||
opts, *options ? options : vers->options,
|
file);
|
||||||
use_rev1, use_rev2);
|
(void) printf ("diff -N %s\n", file);
|
||||||
|
|
||||||
|
if (empty_file == DIFF_ADDED)
|
||||||
|
{
|
||||||
|
run_setup ("%s %s %s %s", DIFF, opts, DEVNULL, file);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* FIXME: Should be setting use_rev1 using the logic in
|
||||||
|
* diff_file_nodiff, and using that revision. This code
|
||||||
|
* is broken for "cvs diff -N -r foo".
|
||||||
|
*/
|
||||||
|
run_setup ("%s%s -p -q %s -r%s", Rcsbin, RCS_CO,
|
||||||
|
*options ? options : vers->options, vers->vn_rcs);
|
||||||
|
run_arg (vers->srcfile->path);
|
||||||
|
if (run_exec (RUN_TTY, tmpnam (tmp), RUN_TTY, RUN_REALLY) == -1)
|
||||||
|
{
|
||||||
|
(void) unlink (tmp);
|
||||||
|
error (1, errno, "fork failed during checkout of %s",
|
||||||
|
vers->srcfile->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
run_setup ("%s %s %s %s", DIFF, opts, tmp, DEVNULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
run_setup ("%s%s %s %s -r%s", Rcsbin, RCS_DIFF, opts,
|
if (use_rev2)
|
||||||
*options ? options : vers->options, use_rev1);
|
{
|
||||||
|
run_setup ("%s%s %s %s -r%s -r%s", Rcsbin, RCS_DIFF,
|
||||||
|
opts, *options ? options : vers->options,
|
||||||
|
use_rev1, use_rev2);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
run_setup ("%s%s %s %s -r%s", Rcsbin, RCS_DIFF, opts,
|
||||||
|
*options ? options : vers->options, use_rev1);
|
||||||
|
}
|
||||||
|
run_arg (vers->srcfile->path);
|
||||||
}
|
}
|
||||||
run_arg (vers->srcfile->path);
|
|
||||||
|
|
||||||
switch ((status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
|
switch ((status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
|
||||||
RUN_REALLY|RUN_COMBINED)))
|
RUN_REALLY|RUN_COMBINED)))
|
||||||
@ -254,6 +320,9 @@ diff_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (empty_file == DIFF_REMOVED)
|
||||||
|
(void) unlink (tmp);
|
||||||
|
|
||||||
(void) fflush (stdout);
|
(void) fflush (stdout);
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
diff_mark_errors (err);
|
diff_mark_errors (err);
|
||||||
@ -288,7 +357,20 @@ diff_dirproc (dir, pos_repos, update_dir)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Concoct the proper exit status.
|
* Concoct the proper exit status - done with files
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
static int
|
||||||
|
diff_filesdoneproc (err, repos, update_dir)
|
||||||
|
int err;
|
||||||
|
char *repos;
|
||||||
|
char *update_dir;
|
||||||
|
{
|
||||||
|
return (diff_errors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Concoct the proper exit status - leaving directories
|
||||||
*/
|
*/
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
static int
|
static int
|
||||||
@ -366,7 +448,12 @@ diff_file_nodiff (file, repository, entries, srcfiles, vers)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* now, see if we really need to do the diff */
|
/* now, see if we really need to do the diff */
|
||||||
return (strcmp (use_rev1, use_rev2) == 0);
|
if (use_rev1 && use_rev2) {
|
||||||
|
return (strcmp (use_rev1, use_rev2) == 0);
|
||||||
|
} else {
|
||||||
|
error(0, 0, "No HEAD revision for file %s", file);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (use_rev1 == NULL || strcmp (use_rev1, vers->vn_user) == 0)
|
if (use_rev1 == NULL || strcmp (use_rev1, vers->vn_user) == 0)
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Entries file to Files file
|
||||||
*
|
*
|
||||||
@ -14,16 +14,13 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static Node *AddEntryNode PROTO((List * list, char *name, char *version,
|
||||||
static Node *AddEntryNode (List * list, char *name, char *version,
|
|
||||||
char *timestamp, char *options, char *tag,
|
char *timestamp, char *options, char *tag,
|
||||||
char *date);
|
char *date, char *conflict));
|
||||||
#else
|
|
||||||
static Node *AddEntryNode ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static FILE *entfile;
|
static FILE *entfile;
|
||||||
static char *entfilename; /* for error messages */
|
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
|
* Write out the line associated with a node of an entries file
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
write_ent_proc (node)
|
write_ent_proc (node, closure)
|
||||||
Node *node;
|
Node *node;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
Entnode *p;
|
Entnode *p;
|
||||||
|
|
||||||
p = (Entnode *) node->data;
|
p = (Entnode *) node->data;
|
||||||
if (fprintf (entfile, "/%s/%s/%s/%s/", node->key, p->version,
|
if (fprintf (entfile, "/%s/%s/%s", node->key, p->version,
|
||||||
p->timestamp, p->options) == EOF)
|
p->timestamp) == EOF)
|
||||||
error (1, errno, "cannot write %s", entfilename);
|
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 (p->tag)
|
||||||
{
|
{
|
||||||
if (fprintf (entfile, "T%s\n", p->tag) == EOF)
|
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 */
|
/* open the new one and walk the list writing entries */
|
||||||
entfilename = CVSADM_ENTBAK;
|
entfilename = CVSADM_ENTBAK;
|
||||||
entfile = open_file (entfilename, "w+");
|
entfile = open_file (entfilename, "w+");
|
||||||
(void) walklist (list, write_ent_proc);
|
(void) walklist (list, write_ent_proc, NULL);
|
||||||
if (fclose (entfile) == EOF)
|
if (fclose (entfile) == EOF)
|
||||||
error (1, errno, "error closing %s", entfilename);
|
error (1, errno, "error closing %s", entfilename);
|
||||||
|
|
||||||
@ -102,7 +108,7 @@ Scratch_Entry (list, fname)
|
|||||||
* removing the old entry first, if necessary.
|
* removing the old entry first, if necessary.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Register (list, fname, vn, ts, options, tag, date)
|
Register (list, fname, vn, ts, options, tag, date, ts_conflict)
|
||||||
List *list;
|
List *list;
|
||||||
char *fname;
|
char *fname;
|
||||||
char *vn;
|
char *vn;
|
||||||
@ -110,13 +116,19 @@ Register (list, fname, vn, ts, options, tag, date)
|
|||||||
char *options;
|
char *options;
|
||||||
char *tag;
|
char *tag;
|
||||||
char *date;
|
char *date;
|
||||||
|
char *ts_conflict;
|
||||||
{
|
{
|
||||||
|
int should_write_file = !noexec;
|
||||||
Node *node;
|
Node *node;
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
(void) fprintf (stderr, "-> Register(%s, %s, %s, %s, %s %s)\n",
|
{
|
||||||
fname, vn, ts, options, tag ? tag : "",
|
(void) fprintf (stderr, "-> Register(%s, %s, %s%s%s, %s, %s %s)\n",
|
||||||
date ? date : "");
|
fname, vn, ts,
|
||||||
|
ts_conflict ? "+" : "", ts_conflict ? ts_conflict : "",
|
||||||
|
options, tag ? tag : "", date ? date : "");
|
||||||
|
}
|
||||||
|
|
||||||
/* was it already there? */
|
/* was it already there? */
|
||||||
if ((node = findnode (list, fname)) != NULL)
|
if ((node = findnode (list, fname)) != NULL)
|
||||||
{
|
{
|
||||||
@ -124,21 +136,24 @@ Register (list, fname, vn, ts, options, tag, date)
|
|||||||
delnode (node);
|
delnode (node);
|
||||||
|
|
||||||
/* add the new one and re-write the file */
|
/* add the new one and re-write the file */
|
||||||
(void) AddEntryNode (list, fname, vn, ts, options, tag, date);
|
(void) AddEntryNode (list, fname, vn, ts, options, tag,
|
||||||
if (!noexec)
|
date, ts_conflict);
|
||||||
|
|
||||||
|
if (should_write_file)
|
||||||
write_entries (list);
|
write_entries (list);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* add the new one */
|
/* 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 */
|
/* append it to the end */
|
||||||
entfilename = CVSADM_ENT;
|
entfilename = CVSADM_ENT;
|
||||||
entfile = open_file (entfilename, "a");
|
entfile = open_file (entfilename, "a");
|
||||||
(void) write_ent_proc (node);
|
(void) write_ent_proc (node, NULL);
|
||||||
if (fclose (entfile) == EOF)
|
if (fclose (entfile) == EOF)
|
||||||
error (1, errno, "error closing %s", entfilename);
|
error (1, errno, "error closing %s", entfilename);
|
||||||
}
|
}
|
||||||
@ -174,11 +189,14 @@ ParseEntries (aflag)
|
|||||||
List *entries;
|
List *entries;
|
||||||
char line[MAXLINELEN];
|
char line[MAXLINELEN];
|
||||||
char *cp, *user, *vn, *ts, *options;
|
char *cp, *user, *vn, *ts, *options;
|
||||||
char *tag_or_date, *tag, *date;
|
char *tag_or_date, *tag, *date, *ts_conflict;
|
||||||
char *dirtag, *dirdate;
|
char *dirtag, *dirdate;
|
||||||
int lineno = 0;
|
int lineno = 0;
|
||||||
|
int do_rewrite = 0;
|
||||||
FILE *fpin;
|
FILE *fpin;
|
||||||
|
|
||||||
|
vn = ts = options = tag = date = ts_conflict = 0;
|
||||||
|
|
||||||
/* get a fresh list... */
|
/* get a fresh list... */
|
||||||
entries = getlist ();
|
entries = getlist ();
|
||||||
|
|
||||||
@ -192,7 +210,7 @@ ParseEntries (aflag)
|
|||||||
struct stickydirtag *sdtp;
|
struct stickydirtag *sdtp;
|
||||||
|
|
||||||
sdtp = (struct stickydirtag *) xmalloc (sizeof (*sdtp));
|
sdtp = (struct stickydirtag *) xmalloc (sizeof (*sdtp));
|
||||||
bzero ((char *) sdtp, sizeof (*sdtp));
|
memset ((char *) sdtp, 0, sizeof (*sdtp));
|
||||||
sdtp->aflag = aflag;
|
sdtp->aflag = aflag;
|
||||||
sdtp->tag = xstrdup (dirtag);
|
sdtp->tag = xstrdup (dirtag);
|
||||||
sdtp->date = xstrdup (dirdate);
|
sdtp->date = xstrdup (dirdate);
|
||||||
@ -214,23 +232,23 @@ ParseEntries (aflag)
|
|||||||
if (line[0] == '/')
|
if (line[0] == '/')
|
||||||
{
|
{
|
||||||
user = line + 1;
|
user = line + 1;
|
||||||
if ((cp = index (user, '/')) == NULL)
|
if ((cp = strchr (user, '/')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
vn = cp;
|
vn = cp;
|
||||||
if ((cp = index (vn, '/')) == NULL)
|
if ((cp = strchr (vn, '/')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
ts = cp;
|
ts = cp;
|
||||||
if ((cp = index (ts, '/')) == NULL)
|
if ((cp = strchr (ts, '/')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
options = cp;
|
options = cp;
|
||||||
if ((cp = index (options, '/')) == NULL)
|
if ((cp = strchr (options, '/')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
tag_or_date = cp;
|
tag_or_date = cp;
|
||||||
if ((cp = index (tag_or_date, '\n')) == NULL)
|
if ((cp = strchr (tag_or_date, '\n')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
tag = (char *) NULL;
|
tag = (char *) NULL;
|
||||||
@ -239,7 +257,40 @@ ParseEntries (aflag)
|
|||||||
tag = tag_or_date + 1;
|
tag = tag_or_date + 1;
|
||||||
else if (*tag_or_date == 'D')
|
else if (*tag_or_date == 'D')
|
||||||
date = tag_or_date + 1;
|
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
|
else
|
||||||
{
|
{
|
||||||
@ -254,6 +305,9 @@ ParseEntries (aflag)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (do_rewrite && !noexec)
|
||||||
|
write_entries (entries);
|
||||||
|
|
||||||
/* clean up and return */
|
/* clean up and return */
|
||||||
if (fpin)
|
if (fpin)
|
||||||
(void) fclose (fpin);
|
(void) fclose (fpin);
|
||||||
@ -311,13 +365,13 @@ check_entries (dir)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
rev = line;
|
rev = line;
|
||||||
if ((ts = index (line, '|')) == NULL)
|
if ((ts = strchr (line, '|')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*ts++ = '\0';
|
*ts++ = '\0';
|
||||||
if ((user = rindex (ts, ' ')) == NULL)
|
if ((user = strrchr (ts, ' ')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*user++ = '\0';
|
*user++ = '\0';
|
||||||
if ((cp = index (user, '|')) == NULL)
|
if ((cp = strchr (user, '|')) == NULL)
|
||||||
continue;
|
continue;
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
opt = "";
|
opt = "";
|
||||||
@ -368,6 +422,8 @@ Entries_delproc (node)
|
|||||||
free (p->tag);
|
free (p->tag);
|
||||||
if (p->date)
|
if (p->date)
|
||||||
free (p->date);
|
free (p->date);
|
||||||
|
if (p->conflict)
|
||||||
|
free (p->conflict);
|
||||||
free ((char *) p);
|
free ((char *) p);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +432,7 @@ Entries_delproc (node)
|
|||||||
* list
|
* list
|
||||||
*/
|
*/
|
||||||
static Node *
|
static Node *
|
||||||
AddEntryNode (list, name, version, timestamp, options, tag, date)
|
AddEntryNode (list, name, version, timestamp, options, tag, date, conflict)
|
||||||
List *list;
|
List *list;
|
||||||
char *name;
|
char *name;
|
||||||
char *version;
|
char *version;
|
||||||
@ -384,6 +440,7 @@ AddEntryNode (list, name, version, timestamp, options, tag, date)
|
|||||||
char *options;
|
char *options;
|
||||||
char *tag;
|
char *tag;
|
||||||
char *date;
|
char *date;
|
||||||
|
char *conflict;
|
||||||
{
|
{
|
||||||
Node *p;
|
Node *p;
|
||||||
Entnode *entdata;
|
Entnode *entdata;
|
||||||
@ -404,6 +461,7 @@ AddEntryNode (list, name, version, timestamp, options, tag, date)
|
|||||||
entdata->options = xstrdup (options);
|
entdata->options = xstrdup (options);
|
||||||
if (entdata->options == NULL)
|
if (entdata->options == NULL)
|
||||||
entdata->options = xstrdup ("");/* must be non-NULL */
|
entdata->options = xstrdup ("");/* must be non-NULL */
|
||||||
|
entdata->conflict = xstrdup (conflict);
|
||||||
entdata->tag = xstrdup (tag);
|
entdata->tag = xstrdup (tag);
|
||||||
entdata->date = xstrdup (date);
|
entdata->date = xstrdup (date);
|
||||||
|
|
||||||
@ -452,7 +510,8 @@ WriteTag (dir, tag, date)
|
|||||||
error (1, errno, "cannot close %s", tmp);
|
error (1, errno, "cannot close %s", tmp);
|
||||||
}
|
}
|
||||||
else
|
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 (fgets (line, sizeof (line), fp) != NULL)
|
||||||
{
|
{
|
||||||
if ((cp = rindex (line, '\n')) != NULL)
|
if ((cp = strrchr (line, '\n')) != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
if (*line == 'T' && tagp)
|
if (*line == 'T' && tagp)
|
||||||
*tagp = xstrdup (line + 1);
|
*tagp = xstrdup (line + 1);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Find Names
|
||||||
*
|
*
|
||||||
@ -19,16 +19,12 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static int find_dirs PROTO((char *dir, List * list, int checkadm));
|
||||||
static int find_dirs (char *dir, List * list, int checkadm);
|
static int find_rcs PROTO((char *dir, List * list));
|
||||||
static int find_rcs (char *dir, List * list);
|
|
||||||
#else
|
|
||||||
static int find_rcs ();
|
|
||||||
static int find_dirs ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static List *filelist;
|
static List *filelist;
|
||||||
|
|
||||||
@ -36,8 +32,9 @@ static List *filelist;
|
|||||||
* add the key from entry on entries list to the files list
|
* add the key from entry on entries list to the files list
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
add_entries_proc (node)
|
add_entries_proc (node, closure)
|
||||||
Node *node;
|
Node *node;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
Node *fnode;
|
Node *fnode;
|
||||||
|
|
||||||
@ -82,7 +79,7 @@ Find_Names (repository, which, aflag, optentries)
|
|||||||
if (entries != NULL)
|
if (entries != NULL)
|
||||||
{
|
{
|
||||||
/* walk the entries file adding elements to the files list */
|
/* 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 our caller wanted the entries list, return it; else free it */
|
||||||
if (optentries != NULL)
|
if (optentries != NULL)
|
||||||
@ -167,28 +164,21 @@ find_rcs (dir, list)
|
|||||||
List *list;
|
List *list;
|
||||||
{
|
{
|
||||||
Node *p;
|
Node *p;
|
||||||
CONST char *regex_err;
|
struct dirent *dp;
|
||||||
char line[50];
|
|
||||||
struct direct *dp;
|
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
|
|
||||||
/* set up to read the dir */
|
/* set up to read the dir */
|
||||||
if ((dirp = opendir (dir)) == NULL)
|
if ((dirp = opendir (dir)) == NULL)
|
||||||
return (1);
|
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 */
|
/* read the dir, grabbing the ,v files */
|
||||||
while ((dp = readdir (dirp)) != NULL)
|
while ((dp = readdir (dirp)) != NULL)
|
||||||
{
|
{
|
||||||
if (re_exec (dp->d_name))
|
if (fnmatch (RCSPAT, dp->d_name, 0) == 0)
|
||||||
{
|
{
|
||||||
char *comma;
|
char *comma;
|
||||||
|
|
||||||
comma = rindex (dp->d_name, ','); /* strip the ,v */
|
comma = strrchr (dp->d_name, ','); /* strip the ,v */
|
||||||
*comma = '\0';
|
*comma = '\0';
|
||||||
p = getnode ();
|
p = getnode ();
|
||||||
p->type = FILES;
|
p->type = FILES;
|
||||||
@ -213,17 +203,10 @@ find_dirs (dir, list, checkadm)
|
|||||||
int checkadm;
|
int checkadm;
|
||||||
{
|
{
|
||||||
Node *p;
|
Node *p;
|
||||||
CONST char *regex_err;
|
|
||||||
char tmp[PATH_MAX];
|
char tmp[PATH_MAX];
|
||||||
char admdir[PATH_MAX];
|
struct dirent *dp;
|
||||||
struct direct *dp;
|
|
||||||
DIR *dirp;
|
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 */
|
/* set up to read the dir */
|
||||||
if ((dirp = opendir (dir)) == NULL)
|
if ((dirp = opendir (dir)) == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
@ -234,38 +217,61 @@ find_dirs (dir, list, checkadm)
|
|||||||
if (strcmp (dp->d_name, ".") == 0 ||
|
if (strcmp (dp->d_name, ".") == 0 ||
|
||||||
strcmp (dp->d_name, "..") == 0 ||
|
strcmp (dp->d_name, "..") == 0 ||
|
||||||
strcmp (dp->d_name, CVSATTIC) == 0 ||
|
strcmp (dp->d_name, CVSATTIC) == 0 ||
|
||||||
strcmp (dp->d_name, CVSLCK) == 0 ||
|
strcmp (dp->d_name, CVSLCK) == 0)
|
||||||
re_exec (dp->d_name)) /* don't bother stating ,v files */
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
(void) sprintf (tmp, "%s/%s", dir, dp->d_name);
|
#ifdef DT_DIR
|
||||||
if (isdir (tmp))
|
if (dp->d_type != DT_DIR)
|
||||||
{
|
{
|
||||||
/* check for administration directories (if needed) */
|
if (dp->d_type != DT_UNKNOWN && dp->d_type != DT_LNK)
|
||||||
if (checkadm)
|
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)
|
||||||
{
|
{
|
||||||
/* blow off symbolic links to dirs in local dir */
|
/* we're either unknown or a symlink at this point */
|
||||||
|
if (dp->d_type == DT_LNK)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
if (islink (tmp))
|
if (islink (tmp))
|
||||||
continue;
|
continue;
|
||||||
|
#ifdef DT_DIR
|
||||||
/* check for new style */
|
|
||||||
(void) sprintf (admdir, "%s/%s", tmp, CVSADM);
|
|
||||||
if (!isdir (admdir))
|
|
||||||
{
|
|
||||||
/* and old style */
|
|
||||||
(void) sprintf (admdir, "%s/%s", tmp, OCVSADM);
|
|
||||||
if (!isdir (admdir))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* put it in the list */
|
/* check for new style */
|
||||||
p = getnode ();
|
(void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, CVSADM);
|
||||||
p->type = DIRS;
|
if (!isdir (tmp))
|
||||||
p->key = xstrdup (dp->d_name);
|
{
|
||||||
if (addnode (list, p) != 0)
|
/* and old style */
|
||||||
freenode (p);
|
(void) sprintf (tmp, "%s/%s/%s", dir, dp->d_name, OCVSADM);
|
||||||
|
if (!isdir (tmp))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* put it in the list */
|
||||||
|
p = getnode ();
|
||||||
|
p->type = DIRS;
|
||||||
|
p->key = xstrdup (dp->d_name);
|
||||||
|
if (addnode (list, p) != 0)
|
||||||
|
freenode (p);
|
||||||
}
|
}
|
||||||
(void) closedir (dirp);
|
(void) closedir (dirp);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -179,7 +179,8 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
static struct hrec
|
static struct hrec
|
||||||
@ -197,33 +198,18 @@ static struct hrec
|
|||||||
} *hrec_head;
|
} *hrec_head;
|
||||||
|
|
||||||
|
|
||||||
#if __STDC__
|
static char *fill_hrec PROTO((char *line, struct hrec * hr));
|
||||||
static char *fill_hrec (char *line, struct hrec * hr);
|
static int accept_hrec PROTO((struct hrec * hr, struct hrec * lr));
|
||||||
static int accept_hrec (struct hrec * hr, struct hrec * lr);
|
static int select_hrec PROTO((struct hrec * hr));
|
||||||
static int select_hrec (struct hrec * hr);
|
static int sort_order PROTO((CONST PTR l, CONST PTR r));
|
||||||
static int sort_order (CONST PTR l, CONST PTR r);
|
static int within PROTO((char *find, char *string));
|
||||||
static int within (char *find, char *string);
|
static time_t date_and_time PROTO((char *date_str));
|
||||||
static time_t date_and_time (char *date_str);
|
static void expand_modules PROTO((void));
|
||||||
static void expand_modules (void);
|
static void read_hrecs PROTO((char *fname));
|
||||||
static void read_hrecs (char *fname);
|
static void report_hrecs PROTO((void));
|
||||||
static void report_hrecs (void);
|
static void save_file PROTO((char *dir, char *name, char *module));
|
||||||
static void save_file (char *dir, char *name, char *module);
|
static void save_module PROTO((char *module));
|
||||||
static void save_module (char *module);
|
static void save_user PROTO((char *name));
|
||||||
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__ */
|
|
||||||
|
|
||||||
#define ALL_REC_TYPES "TOFWUCGMAR"
|
#define ALL_REC_TYPES "TOFWUCGMAR"
|
||||||
#define USER_INCREMENT 2
|
#define USER_INCREMENT 2
|
||||||
@ -247,6 +233,14 @@ static short repos_sort;
|
|||||||
static short file_sort;
|
static short file_sort;
|
||||||
static short module_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 time_t since_date;
|
||||||
static char since_rev[20]; /* Maxrev ~= 99.99.99.999 */
|
static char since_rev[20]; /* Maxrev ~= 99.99.99.999 */
|
||||||
static char since_tag[64];
|
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",
|
" -r <rev/tag> Since rev or tag (looks inside RCS files!)\n",
|
||||||
" -t <tag> Since tag record placed in history file (by anyone).\n",
|
" -t <tag> Since tag record placed in history file (by anyone).\n",
|
||||||
" -u <user> For user name (repeatable)\n",
|
" -u <user> For user name (repeatable)\n",
|
||||||
|
" -z <tz> Output for time zone <tz> (e.g. -z -0700)\n",
|
||||||
NULL};
|
NULL};
|
||||||
|
|
||||||
/* Sort routine for qsort:
|
/* Sort routine for qsort:
|
||||||
@ -385,7 +380,7 @@ history (argc, argv)
|
|||||||
usage (history_usg);
|
usage (history_usg);
|
||||||
|
|
||||||
optind = 1;
|
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)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -481,11 +476,47 @@ history (argc, argv)
|
|||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
for (cp = optarg; *cp; cp++)
|
for (cp = optarg; *cp; cp++)
|
||||||
if (!index (ALL_REC_TYPES, *cp))
|
if (!strchr (ALL_REC_TYPES, *cp))
|
||||||
error (1, 0, "%c is not a valid report type", cp);
|
error (1, 0, "%c is not a valid report type", *cp);
|
||||||
}
|
}
|
||||||
(void) strcpy (rec_types, optarg);
|
(void) strcpy (rec_types, optarg);
|
||||||
break;
|
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 '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage (history_usg);
|
usage (history_usg);
|
||||||
@ -508,7 +539,7 @@ history (argc, argv)
|
|||||||
|
|
||||||
if (tag_report)
|
if (tag_report)
|
||||||
{
|
{
|
||||||
if (!index (rec_types, 'T'))
|
if (!strchr (rec_types, 'T'))
|
||||||
(void) strcat (rec_types, "T");
|
(void) strcat (rec_types, "T");
|
||||||
}
|
}
|
||||||
else if (extract)
|
else if (extract)
|
||||||
@ -559,7 +590,7 @@ history (argc, argv)
|
|||||||
save_user (getcaller ());
|
save_user (getcaller ());
|
||||||
|
|
||||||
/* If we're looking back to a Tag value, must consider "Tag" records */
|
/* 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");
|
(void) strcat (rec_types, "T");
|
||||||
|
|
||||||
argc -= c;
|
argc -= c;
|
||||||
@ -637,7 +668,7 @@ history_write (type, update_dir, revs, name, repository)
|
|||||||
if (chdir (pw->pw_dir) < 0)
|
if (chdir (pw->pw_dir) < 0)
|
||||||
error (1, errno, "can't chdir(%s)", pw->pw_dir);
|
error (1, errno, "can't chdir(%s)", pw->pw_dir);
|
||||||
if (!getwd (homedir))
|
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);
|
(void) chdir (workdir);
|
||||||
|
|
||||||
i = strlen (homedir);
|
i = strlen (homedir);
|
||||||
@ -837,16 +868,16 @@ fill_hrec (line, hr)
|
|||||||
int off;
|
int off;
|
||||||
static int idx = 0;
|
static int idx = 0;
|
||||||
|
|
||||||
bzero ((char *) hr, sizeof (*hr));
|
memset ((char *) hr, 0, sizeof (*hr));
|
||||||
while (isspace (*line))
|
while (isspace (*line))
|
||||||
line++;
|
line++;
|
||||||
if (!(rtn = index (line, '\n')))
|
if (!(rtn = strchr (line, '\n')))
|
||||||
return ("");
|
return ("");
|
||||||
*rtn++ = '\0';
|
*rtn++ = '\0';
|
||||||
|
|
||||||
hr->type = line++;
|
hr->type = line++;
|
||||||
(void) sscanf (line, "%x", &hr->date);
|
(void) sscanf (line, "%x", &hr->date);
|
||||||
while (*line && index ("0123456789abcdefABCDEF", *line))
|
while (*line && strchr ("0123456789abcdefABCDEF", *line))
|
||||||
line++;
|
line++;
|
||||||
if (*line == '\0')
|
if (*line == '\0')
|
||||||
return (rtn);
|
return (rtn);
|
||||||
@ -854,7 +885,7 @@ fill_hrec (line, hr)
|
|||||||
line++;
|
line++;
|
||||||
NEXT_BAR (user);
|
NEXT_BAR (user);
|
||||||
NEXT_BAR (dir);
|
NEXT_BAR (dir);
|
||||||
if ((cp = rindex (hr->dir, '*')) != NULL)
|
if ((cp = strrchr (hr->dir, '*')) != NULL)
|
||||||
{
|
{
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
(void) sscanf (cp, "%x", &off);
|
(void) sscanf (cp, "%x", &off);
|
||||||
@ -865,7 +896,7 @@ fill_hrec (line, hr)
|
|||||||
NEXT_BAR (repos);
|
NEXT_BAR (repos);
|
||||||
NEXT_BAR (rev);
|
NEXT_BAR (rev);
|
||||||
hr->idx = idx++;
|
hr->idx = idx++;
|
||||||
if (index ("FOT", *(hr->type)))
|
if (strchr ("FOT", *(hr->type)))
|
||||||
hr->mod = line;
|
hr->mod = line;
|
||||||
|
|
||||||
NEXT_BAR (file); /* This returns ptr to next line or final '\0' */
|
NEXT_BAR (file); /* This returns ptr to next line or final '\0' */
|
||||||
@ -981,7 +1012,7 @@ within (find, string)
|
|||||||
|
|
||||||
while (*string)
|
while (*string)
|
||||||
{
|
{
|
||||||
if (!(string = index (string, c)))
|
if (!(string = strchr (string, c)))
|
||||||
return (0);
|
return (0);
|
||||||
string++;
|
string++;
|
||||||
if (!strncmp (find, string, len))
|
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 is null, keep everything. Otherwise, keep only files on
|
||||||
* file_list, matched appropriately.
|
* file_list, matched appropriately.
|
||||||
*/
|
*/
|
||||||
if (!index (rec_types, *(hr->type)))
|
if (!strchr (rec_types, *(hr->type)))
|
||||||
return (0);
|
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 */
|
if (file_list) /* If file_list is null, accept all */
|
||||||
{
|
{
|
||||||
@ -1132,7 +1163,7 @@ select_hrec (hr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (index (cp, '/'))
|
if (strchr (cp, '/'))
|
||||||
{
|
{
|
||||||
(void) sprintf (cp2 = cmpfile, "%s/%s",
|
(void) sprintf (cp2 = cmpfile, "%s/%s",
|
||||||
hr->repos, hr->file);
|
hr->repos, hr->file);
|
||||||
@ -1215,7 +1246,7 @@ report_hrecs ()
|
|||||||
|
|
||||||
ty = *(lr->type);
|
ty = *(lr->type);
|
||||||
(void) strcpy (repos, lr->repos);
|
(void) strcpy (repos, lr->repos);
|
||||||
if ((cp = rindex (repos, '/')) != NULL)
|
if ((cp = strrchr (repos, '/')) != NULL)
|
||||||
{
|
{
|
||||||
if (lr->mod && !strcmp (++cp, lr->mod))
|
if (lr->mod && !strcmp (++cp, lr->mod))
|
||||||
{
|
{
|
||||||
@ -1253,12 +1284,21 @@ report_hrecs ()
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ty = *(lr->type);
|
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));
|
tm = localtime (&(lr->date));
|
||||||
(void) printf ("%c %02d/%02d %02d:%02d %-*s", ty, tm->tm_mon + 1,
|
(void) printf ("%c %02d/%02d %02d:%02d %s %-*s", ty, tm->tm_mon + 1,
|
||||||
tm->tm_mday, tm->tm_hour, tm->tm_min, user_len, lr->user);
|
tm->tm_mday, tm->tm_hour, tm->tm_min, tz_name,
|
||||||
|
user_len, lr->user);
|
||||||
|
|
||||||
(void) sprintf (workdir, "%s%s", lr->dir, lr->end);
|
(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))
|
if (lr->mod && !strcmp (++cp, lr->mod))
|
||||||
{
|
{
|
||||||
@ -1266,7 +1306,7 @@ report_hrecs ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(void) strcpy (repos, lr->repos);
|
(void) strcpy (repos, lr->repos);
|
||||||
if ((cp = rindex (repos, '/')) != NULL)
|
if ((cp = strrchr (repos, '/')) != NULL)
|
||||||
{
|
{
|
||||||
if (lr->mod && !strcmp (++cp, lr->mod))
|
if (lr->mod && !strcmp (++cp, lr->mod))
|
||||||
{
|
{
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* .cvsignore file support contributed by David G. Grubbs <dgg@ksr.com>
|
* .cvsignore file support contributed by David G. Grubbs <dgg@odi.com>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)ignore.c 1.13 92/04/03";
|
static char rcsid[] = "$CVSid: @(#)ignore.c 1.16 94/09/24 $";
|
||||||
|
USE(rcsid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -147,7 +148,7 @@ ign_add (ign, hold)
|
|||||||
* (saving it if necessary). We also catch * as a special case in a
|
* (saving it if necessary). We also catch * as a special case in a
|
||||||
* global ignore file as an optimization
|
* global ignore file as an optimization
|
||||||
*/
|
*/
|
||||||
if (isspace (*(ign + 1)) && (*ign == '!' || *ign == '*'))
|
if ((!*(ign+1) || isspace (*(ign+1))) && (*ign == '!' || *ign == '*'))
|
||||||
{
|
{
|
||||||
if (!hold)
|
if (!hold)
|
||||||
{
|
{
|
||||||
@ -225,3 +226,47 @@ ign_name (name)
|
|||||||
return (1);
|
return (1);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static char **dir_ign_list = NULL;
|
||||||
|
static int dir_ign_max = 0;
|
||||||
|
static int dir_ign_current = 0;
|
||||||
|
|
||||||
|
/* add a directory to list of dirs to ignore */
|
||||||
|
void ign_dir_add (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
/* make sure we've got the space for the entry */
|
||||||
|
if (dir_ign_current <= dir_ign_max)
|
||||||
|
{
|
||||||
|
dir_ign_max += IGN_GROW;
|
||||||
|
dir_ign_list = (char **) xrealloc ((char *) dir_ign_list, (dir_ign_max+1) * sizeof(char*));
|
||||||
|
}
|
||||||
|
|
||||||
|
dir_ign_list[dir_ign_current] = name;
|
||||||
|
|
||||||
|
dir_ign_current += 1 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* this function returns 1 (true) if the given directory name is part of
|
||||||
|
* the list of directories to ignore
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ignore_directory (name)
|
||||||
|
char *name;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!dir_ign_list)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
i = dir_ign_current;
|
||||||
|
while (i--)
|
||||||
|
{
|
||||||
|
if (strncmp(name, dir_ign_list[i], strlen(dir_ign_list[i])) == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
||||||
*
|
*
|
||||||
* "import" checks in the vendor release located in the current directory into
|
* "import" checks in the vendor release located in the current directory into
|
||||||
* the CVS source repository. The CVS vendor branch support is utilized.
|
* the CVS source repository. The CVS vendor branch support is utilized.
|
||||||
@ -19,39 +19,29 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)import.c 1.52 92/03/31";
|
static char rcsid[] = "$CVSid: @(#)import.c 1.63 94/09/30 $";
|
||||||
|
USE(rcsid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FILE_HOLDER ".#cvsxxx"
|
#define FILE_HOLDER ".#cvsxxx"
|
||||||
|
|
||||||
#if __STDC__
|
static char *get_comment PROTO((char *user));
|
||||||
static char *get_comment (char *user);
|
static int add_rcs_file PROTO((char *message, char *rcs, char *user, char *vtag,
|
||||||
static int add_rcs_file (char *message, char *rcs, char *user, char *vtag,
|
int targc, char *targv[]));
|
||||||
int targc, char *targv[]);
|
static int expand_at_signs PROTO((char *buf, off_t size, FILE *fp));
|
||||||
static int expand_at_signs (char *buf, off_t size, FILE *fp);
|
static int add_rev PROTO((char *message, char *rcs, char *vfile, char *vers));
|
||||||
static int add_rev (char *message, char *rcs, char *vfile, char *vers);
|
static int add_tags PROTO((char *rcs, char *vfile, char *vtag, int targc,
|
||||||
static int add_tags (char *rcs, char *vfile, char *vtag, int targc,
|
char *targv[]));
|
||||||
char *targv[]);
|
static int import_descend PROTO((char *message, char *vtag, int targc, char *targv[]));
|
||||||
static int import_descend (char *message, char *vtag, int targc, char *targv[]);
|
static int import_descend_dir PROTO((char *message, char *dir, char *vtag,
|
||||||
static int import_descend_dir (char *message, char *dir, char *vtag,
|
int targc, char *targv[]));
|
||||||
int targc, char *targv[]);
|
static int process_import_file PROTO((char *message, char *vfile, char *vtag,
|
||||||
static int process_import_file (char *message, char *vfile, char *vtag,
|
int targc, char *targv[]));
|
||||||
int targc, char *targv[]);
|
static int update_rcs_file PROTO((char *message, char *vfile, char *vtag, int targc,
|
||||||
static int update_rcs_file (char *message, char *vfile, char *vtag, int targc,
|
char *targv[], int inattic));
|
||||||
char *targv[]);
|
static void add_log PROTO((int ch, char *fname));
|
||||||
static void add_log (int ch, char *fname);
|
static int str2expmode PROTO((char const* expstring));
|
||||||
#else
|
static int strn2expmode PROTO((char const* expstring, size_t n));
|
||||||
static int import_descend ();
|
|
||||||
static int process_import_file ();
|
|
||||||
static int update_rcs_file ();
|
|
||||||
static int add_rev ();
|
|
||||||
static int add_tags ();
|
|
||||||
static char *get_comment ();
|
|
||||||
static int add_rcs_file ();
|
|
||||||
static int expand_at_signs ();
|
|
||||||
static void add_log ();
|
|
||||||
static int import_descend_dir ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static int repos_len;
|
static int repos_len;
|
||||||
static char vhead[50];
|
static char vhead[50];
|
||||||
@ -59,25 +49,42 @@ static char vbranch[50];
|
|||||||
static FILE *logfp;
|
static FILE *logfp;
|
||||||
static char repository[PATH_MAX];
|
static char repository[PATH_MAX];
|
||||||
static int conflicts;
|
static int conflicts;
|
||||||
|
static int use_file_modtime;
|
||||||
|
static char *keyword_opt = NULL;
|
||||||
|
|
||||||
static char *import_usage[] =
|
static char *import_usage[] =
|
||||||
{
|
{
|
||||||
"Usage: %s %s [-Qq] [-I ign] [-m msg] [-b branch]\n",
|
"Usage: %s %s [-Qq] [-d] [-k subst] [-I ign] [-m msg] [-b branch]\n",
|
||||||
" repository vendor-tag release-tags...\n",
|
" repository vendor-tag release-tags...\n",
|
||||||
"\t-Q\tReally quiet.\n",
|
"\t-Q\tReally quiet.\n",
|
||||||
"\t-q\tSomewhat quiet.\n",
|
"\t-q\tSomewhat quiet.\n",
|
||||||
|
"\t-d\tUse the file's modification time as the time of import.\n",
|
||||||
|
"\t-k sub\tSet default RCS keyword substitution mode.\n",
|
||||||
"\t-I ign\tMore files to ignore (! to reset).\n",
|
"\t-I ign\tMore files to ignore (! to reset).\n",
|
||||||
"\t-b bra\tVendor branch id.\n",
|
"\t-b bra\tVendor branch id.\n",
|
||||||
"\t-m msg\tLog message.\n",
|
"\t-m msg\tLog message.\n",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static char *keyword_usage[] =
|
||||||
|
{
|
||||||
|
"%s %s: invalid RCS keyword expansion mode\n",
|
||||||
|
"Valid expansion modes include:\n",
|
||||||
|
" -kkv\tGenerate keywords using the default form.\n",
|
||||||
|
" -kkvl\tLike -kkv, except locker's name inserted.\n",
|
||||||
|
" -kk\tGenerate only keyword names in keyword strings.\n",
|
||||||
|
" -kv\tGenerate only keyword values in keyword strings.\n",
|
||||||
|
" -ko\tGenerate the old keyword string (no changes from checked in file).\n",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
import (argc, argv)
|
import (argc, argv)
|
||||||
int argc;
|
int argc;
|
||||||
char *argv[];
|
char *argv[];
|
||||||
{
|
{
|
||||||
char message[MAXMESGLEN];
|
char *message = NULL;
|
||||||
char tmpfile[L_tmpnam+1];
|
char tmpfile[L_tmpnam+1];
|
||||||
char *cp;
|
char *cp;
|
||||||
int i, c, msglen, err;
|
int i, c, msglen, err;
|
||||||
@ -90,9 +97,8 @@ import (argc, argv)
|
|||||||
ign_setup ();
|
ign_setup ();
|
||||||
|
|
||||||
(void) strcpy (vbranch, CVSBRANCH);
|
(void) strcpy (vbranch, CVSBRANCH);
|
||||||
message[0] = '\0';
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "Qqb:m:I:")) != -1)
|
while ((c = getopt (argc, argv, "Qqdb:m:I:k:")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -102,6 +108,9 @@ import (argc, argv)
|
|||||||
case 'q':
|
case 'q':
|
||||||
quiet = 1;
|
quiet = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'd':
|
||||||
|
use_file_modtime = 1;
|
||||||
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
(void) strcpy (vbranch, optarg);
|
(void) strcpy (vbranch, optarg);
|
||||||
break;
|
break;
|
||||||
@ -111,18 +120,17 @@ import (argc, argv)
|
|||||||
#else
|
#else
|
||||||
use_editor = FALSE;
|
use_editor = FALSE;
|
||||||
#endif
|
#endif
|
||||||
if (strlen (optarg) >= (sizeof (message) - 1))
|
message = xstrdup(optarg);
|
||||||
{
|
|
||||||
error (0, 0, "warning: message too long; truncated!");
|
|
||||||
(void) strncpy (message, optarg, sizeof (message));
|
|
||||||
message[sizeof (message) - 2] = '\0';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(void) strcpy (message, optarg);
|
|
||||||
break;
|
break;
|
||||||
case 'I':
|
case 'I':
|
||||||
ign_add (optarg, 0);
|
ign_add (optarg, 0);
|
||||||
break;
|
break;
|
||||||
|
case 'k':
|
||||||
|
if (str2expmode(optarg) != -1)
|
||||||
|
keyword_opt = optarg;
|
||||||
|
else
|
||||||
|
usage (keyword_usage);
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage (import_usage);
|
usage (import_usage);
|
||||||
@ -167,15 +175,25 @@ import (argc, argv)
|
|||||||
if (numdots (vbranch) != 2)
|
if (numdots (vbranch) != 2)
|
||||||
error (1, 0, "Only branches with two dots are supported: %s", vbranch);
|
error (1, 0, "Only branches with two dots are supported: %s", vbranch);
|
||||||
(void) strcpy (vhead, vbranch);
|
(void) strcpy (vhead, vbranch);
|
||||||
cp = rindex (vhead, '.');
|
cp = strrchr (vhead, '.');
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
if (use_editor)
|
if (use_editor)
|
||||||
do_editor ((char *) NULL, message, repository, (List *) NULL);
|
{
|
||||||
msglen = strlen (message);
|
do_editor ((char *) NULL, &message, repository,
|
||||||
|
(List *) NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
msglen = message == NULL ? 0 : strlen (message);
|
||||||
if (msglen == 0 || message[msglen - 1] != '\n')
|
if (msglen == 0 || message[msglen - 1] != '\n')
|
||||||
{
|
{
|
||||||
message[msglen] = '\n';
|
char *nm = xmalloc (msglen + 2);
|
||||||
message[msglen + 1] = '\0';
|
if (message != NULL)
|
||||||
|
{
|
||||||
|
(void) strcpy (nm, message);
|
||||||
|
free (message);
|
||||||
|
}
|
||||||
|
(void) strcat (nm + msglen, "\n");
|
||||||
|
message = nm;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -235,6 +253,10 @@ import (argc, argv)
|
|||||||
Update_Logfile (repository, message, vbranch, logfp, ulist);
|
Update_Logfile (repository, message, vbranch, logfp, ulist);
|
||||||
dellist (&ulist);
|
dellist (&ulist);
|
||||||
(void) fclose (logfp);
|
(void) fclose (logfp);
|
||||||
|
|
||||||
|
if (message)
|
||||||
|
free (message);
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,7 +271,7 @@ import_descend (message, vtag, targc, targv)
|
|||||||
char *targv[];
|
char *targv[];
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct direct *dp;
|
struct dirent *dp;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int has_dirs = 0;
|
int has_dirs = 0;
|
||||||
|
|
||||||
@ -299,10 +321,14 @@ import_descend (message, vtag, targc, targv)
|
|||||||
{
|
{
|
||||||
while ((dp = readdir (dirp)) != NULL)
|
while ((dp = readdir (dirp)) != NULL)
|
||||||
{
|
{
|
||||||
if (ign_name (dp->d_name) || !isdir (dp->d_name))
|
if (!strcmp(".", dp->d_name) || !strcmp("..", dp->d_name))
|
||||||
|
continue;
|
||||||
|
if (!isdir (dp->d_name) || ign_name (dp->d_name))
|
||||||
continue;
|
continue;
|
||||||
err += import_descend_dir (message, dp->d_name,
|
err += import_descend_dir (message, dp->d_name,
|
||||||
vtag, targc, targv);
|
vtag, targc, targv);
|
||||||
|
/* need to re-load .cvsignore after each dir traversal */
|
||||||
|
ign_add_file (CVSDOTIGNORE, 1);
|
||||||
}
|
}
|
||||||
(void) closedir (dirp);
|
(void) closedir (dirp);
|
||||||
}
|
}
|
||||||
@ -323,6 +349,7 @@ process_import_file (message, vfile, vtag, targc, targv)
|
|||||||
{
|
{
|
||||||
char attic_name[PATH_MAX];
|
char attic_name[PATH_MAX];
|
||||||
char rcs[PATH_MAX];
|
char rcs[PATH_MAX];
|
||||||
|
int inattic = 0;
|
||||||
|
|
||||||
(void) sprintf (rcs, "%s/%s%s", repository, vfile, RCSEXT);
|
(void) sprintf (rcs, "%s/%s%s", repository, vfile, RCSEXT);
|
||||||
if (!isfile (rcs))
|
if (!isfile (rcs))
|
||||||
@ -339,12 +366,13 @@ process_import_file (message, vfile, vtag, targc, targv)
|
|||||||
add_log ('N', vfile);
|
add_log ('N', vfile);
|
||||||
return (add_rcs_file (message, rcs, vfile, vtag, targc, targv));
|
return (add_rcs_file (message, rcs, vfile, vtag, targc, targv));
|
||||||
}
|
}
|
||||||
|
inattic = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* an rcs file exists. have to do things the official, slow, way.
|
* an rcs file exists. have to do things the official, slow, way.
|
||||||
*/
|
*/
|
||||||
return (update_rcs_file (message, vfile, vtag, targc, targv));
|
return (update_rcs_file (message, vfile, vtag, targc, targv, inattic));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -352,27 +380,32 @@ process_import_file (message, vfile, vtag, targc, targv)
|
|||||||
* (possibly already existing) vendor branch.
|
* (possibly already existing) vendor branch.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
update_rcs_file (message, vfile, vtag, targc, targv)
|
update_rcs_file (message, vfile, vtag, targc, targv, inattic)
|
||||||
char *message;
|
char *message;
|
||||||
char *vfile;
|
char *vfile;
|
||||||
char *vtag;
|
char *vtag;
|
||||||
int targc;
|
int targc;
|
||||||
char *targv[];
|
char *targv[];
|
||||||
|
int inattic;
|
||||||
{
|
{
|
||||||
Vers_TS *vers;
|
Vers_TS *vers;
|
||||||
char letter;
|
int letter;
|
||||||
int ierrno;
|
int ierrno;
|
||||||
|
char *tmpdir;
|
||||||
|
|
||||||
vers = Version_TS (repository, (char *) NULL, vbranch, (char *) NULL, vfile,
|
vers = Version_TS (repository, (char *) NULL, vbranch, (char *) NULL, vfile,
|
||||||
1, 0, (List *) NULL, (List *) NULL);
|
1, 0, (List *) NULL, (List *) NULL);
|
||||||
if (vers->vn_rcs != NULL)
|
if (vers->vn_rcs != NULL)
|
||||||
{
|
{
|
||||||
char xtmpfile[50];
|
char xtmpfile[PATH_MAX];
|
||||||
int different;
|
int different;
|
||||||
int retcode = 0;
|
int retcode = 0;
|
||||||
|
|
||||||
/* XXX - should be more unique */
|
tmpdir = getenv ("TMPDIR");
|
||||||
(void) sprintf (xtmpfile, "/tmp/%s", FILE_HOLDER);
|
if (tmpdir == NULL || tmpdir[0] == '\0')
|
||||||
|
tmpdir = "/tmp";
|
||||||
|
|
||||||
|
(void) sprintf (xtmpfile, "%s/cvs-imp%d", tmpdir, getpid());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The rcs file does have a revision on the vendor branch. Compare
|
* The rcs file does have a revision on the vendor branch. Compare
|
||||||
@ -422,15 +455,15 @@ update_rcs_file (message, vfile, vtag, targc, targv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We may have failed to parse the RCS file; check just in case */
|
/* We may have failed to parse the RCS file; check just in case */
|
||||||
if (vers->srcfile == NULL || add_rev (message, vers->srcfile->path,
|
if (vers->srcfile == NULL ||
|
||||||
vfile, vers->vn_rcs) ||
|
add_rev (message, vers->srcfile->path, vfile, vers->vn_rcs) ||
|
||||||
add_tags (vers->srcfile->path, vfile, vtag, targc, targv))
|
add_tags (vers->srcfile->path, vfile, vtag, targc, targv))
|
||||||
{
|
{
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vers->srcfile->branch == NULL ||
|
if (vers->srcfile->branch == NULL || inattic ||
|
||||||
strcmp (vers->srcfile->branch, vbranch) != 0)
|
strcmp (vers->srcfile->branch, vbranch) != 0)
|
||||||
{
|
{
|
||||||
conflicts++;
|
conflicts++;
|
||||||
@ -490,6 +523,8 @@ add_rev (message, rcs, vfile, vers)
|
|||||||
}
|
}
|
||||||
run_setup ("%s%s -q -f -r%s", Rcsbin, RCS_CI, vbranch);
|
run_setup ("%s%s -q -f -r%s", Rcsbin, RCS_CI, vbranch);
|
||||||
run_args ("-m%s", message);
|
run_args ("-m%s", message);
|
||||||
|
if (use_file_modtime)
|
||||||
|
run_arg ("-d");
|
||||||
run_arg (rcs);
|
run_arg (rcs);
|
||||||
status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
||||||
ierrno = errno;
|
ierrno = errno;
|
||||||
@ -583,8 +618,11 @@ struct compair comtable[] =
|
|||||||
*/
|
*/
|
||||||
"a", "-- ", /* Ada */
|
"a", "-- ", /* Ada */
|
||||||
"ada", "-- ",
|
"ada", "-- ",
|
||||||
|
"adb", "-- ",
|
||||||
"asm", ";; ", /* assembler (MS-DOS) */
|
"asm", ";; ", /* assembler (MS-DOS) */
|
||||||
|
"ads", "-- ", /* Ada */
|
||||||
"bat", ":: ", /* batch (MS-DOS) */
|
"bat", ":: ", /* batch (MS-DOS) */
|
||||||
|
"body", "-- ", /* Ada */
|
||||||
"c", " * ", /* C */
|
"c", " * ", /* C */
|
||||||
"c++", "// ", /* C++ in all its infinite guises */
|
"c++", "// ", /* C++ in all its infinite guises */
|
||||||
"cc", "// ",
|
"cc", "// ",
|
||||||
@ -596,6 +634,8 @@ struct compair comtable[] =
|
|||||||
"cs", " * ", /* C* */
|
"cs", " * ", /* C* */
|
||||||
"csh", "# ", /* shell */
|
"csh", "# ", /* shell */
|
||||||
"e", "# ", /* efl */
|
"e", "# ", /* efl */
|
||||||
|
"epsf", "% ", /* encapsulated postscript */
|
||||||
|
"epsi", "% ", /* encapsulated postscript */
|
||||||
"el", "; ", /* Emacs Lisp */
|
"el", "; ", /* Emacs Lisp */
|
||||||
"f", "c ", /* Fortran */
|
"f", "c ", /* Fortran */
|
||||||
"for", "c ",
|
"for", "c ",
|
||||||
@ -646,6 +686,7 @@ struct compair comtable[] =
|
|||||||
#endif
|
#endif
|
||||||
"sh", "# ", /* shell */
|
"sh", "# ", /* shell */
|
||||||
"sl", "% ", /* psl */
|
"sl", "% ", /* psl */
|
||||||
|
"spec", "-- ", /* Ada */
|
||||||
"tex", "% ", /* tex */
|
"tex", "% ", /* tex */
|
||||||
"y", " * ", /* yacc */
|
"y", " * ", /* yacc */
|
||||||
"ye", " * ", /* yacc-efl */
|
"ye", " * ", /* yacc-efl */
|
||||||
@ -663,7 +704,7 @@ get_comment (user)
|
|||||||
char suffix_path[PATH_MAX];
|
char suffix_path[PATH_MAX];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cp = rindex (user, '.');
|
cp = strrchr (user, '.');
|
||||||
if (cp != NULL)
|
if (cp != NULL)
|
||||||
{
|
{
|
||||||
cp++;
|
cp++;
|
||||||
@ -702,7 +743,10 @@ add_rcs_file (message, rcs, user, vtag, targc, targv)
|
|||||||
struct stat sb;
|
struct stat sb;
|
||||||
struct tm *ftm;
|
struct tm *ftm;
|
||||||
time_t now;
|
time_t now;
|
||||||
char altdate1[50], altdate2[50];
|
char altdate1[50];
|
||||||
|
#ifndef HAVE_RCS5
|
||||||
|
char altdate2[50];
|
||||||
|
#endif
|
||||||
char *author, *buf;
|
char *author, *buf;
|
||||||
int i, mode, ierrno, err = 0;
|
int i, mode, ierrno, err = 0;
|
||||||
|
|
||||||
@ -730,15 +774,29 @@ add_rcs_file (message, rcs, user, vtag, targc, targv)
|
|||||||
if (fprintf (fprcs, "%s:%s;\n", vtag, vbranch) == EOF ||
|
if (fprintf (fprcs, "%s:%s;\n", vtag, vbranch) == EOF ||
|
||||||
fprintf (fprcs, "locks ; strict;\n") == EOF ||
|
fprintf (fprcs, "locks ; strict;\n") == EOF ||
|
||||||
/* XXX - make sure @@ processing works in the RCS file */
|
/* XXX - make sure @@ processing works in the RCS file */
|
||||||
fprintf (fprcs, "comment @%s@;\n\n", get_comment (user)) == EOF)
|
fprintf (fprcs, "comment @%s@;\n", get_comment (user)) == EOF)
|
||||||
{
|
{
|
||||||
goto write_error;
|
goto write_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (keyword_opt != NULL)
|
||||||
|
if (fprintf (fprcs, "expand @%s@;\n", keyword_opt) == EOF)
|
||||||
|
{
|
||||||
|
goto write_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fprintf (fprcs, "\n") == EOF)
|
||||||
|
goto write_error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* puttree()
|
* puttree()
|
||||||
*/
|
*/
|
||||||
(void) time (&now);
|
if (fstat (fileno (fpuser), &sb) < 0)
|
||||||
|
error (1, errno, "cannot fstat %s", user);
|
||||||
|
if (use_file_modtime)
|
||||||
|
now = sb.st_mtime;
|
||||||
|
else
|
||||||
|
(void) time (&now);
|
||||||
#ifdef HAVE_RCS5
|
#ifdef HAVE_RCS5
|
||||||
ftm = gmtime (&now);
|
ftm = gmtime (&now);
|
||||||
#else
|
#else
|
||||||
@ -748,16 +806,20 @@ add_rcs_file (message, rcs, user, vtag, targc, targv)
|
|||||||
ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
|
ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
|
||||||
ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
|
ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
|
||||||
ftm->tm_min, ftm->tm_sec);
|
ftm->tm_min, ftm->tm_sec);
|
||||||
now++;
|
|
||||||
#ifdef HAVE_RCS5
|
#ifdef HAVE_RCS5
|
||||||
ftm = gmtime (&now);
|
#define altdate2 altdate1
|
||||||
#else
|
#else
|
||||||
|
/*
|
||||||
|
* If you don't have RCS V5 or later, you need to lie about the ci
|
||||||
|
* time, since RCS V4 and earlier insist that the times differ.
|
||||||
|
*/
|
||||||
|
now++;
|
||||||
ftm = localtime (&now);
|
ftm = localtime (&now);
|
||||||
#endif
|
|
||||||
(void) sprintf (altdate2, DATEFORM,
|
(void) sprintf (altdate2, DATEFORM,
|
||||||
ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
|
ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900),
|
||||||
ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
|
ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour,
|
||||||
ftm->tm_min, ftm->tm_sec);
|
ftm->tm_min, ftm->tm_sec);
|
||||||
|
#endif
|
||||||
author = getcaller ();
|
author = getcaller ();
|
||||||
|
|
||||||
if (fprintf (fprcs, "\n%s\n", vhead) == EOF ||
|
if (fprintf (fprcs, "\n%s\n", vhead) == EOF ||
|
||||||
@ -786,8 +848,6 @@ add_rcs_file (message, rcs, user, vtag, targc, targv)
|
|||||||
goto write_error;
|
goto write_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat (fileno (fpuser), &sb) < 0)
|
|
||||||
error (1, errno, "cannot fstat %s", user);
|
|
||||||
if (sb.st_size > 0)
|
if (sb.st_size > 0)
|
||||||
{
|
{
|
||||||
off_t size;
|
off_t size;
|
||||||
@ -797,7 +857,10 @@ add_rcs_file (message, rcs, user, vtag, targc, targv)
|
|||||||
if (fread (buf, (int) size, 1, fpuser) != 1)
|
if (fread (buf, (int) size, 1, fpuser) != 1)
|
||||||
error (1, errno, "cannot read file %s for copying", user);
|
error (1, errno, "cannot read file %s for copying", user);
|
||||||
if (expand_at_signs (buf, size, fprcs) == EOF)
|
if (expand_at_signs (buf, size, fprcs) == EOF)
|
||||||
|
{
|
||||||
|
free (buf);
|
||||||
goto write_error;
|
goto write_error;
|
||||||
|
}
|
||||||
free (buf);
|
free (buf);
|
||||||
}
|
}
|
||||||
if (fprintf (fprcs, "@\n\n") == EOF ||
|
if (fprintf (fprcs, "@\n\n") == EOF ||
|
||||||
@ -874,7 +937,7 @@ expand_at_signs (buf, size, fp)
|
|||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
add_log (ch, fname)
|
add_log (ch, fname)
|
||||||
char ch;
|
int ch;
|
||||||
char *fname;
|
char *fname;
|
||||||
{
|
{
|
||||||
if (!really_quiet) /* write to terminal */
|
if (!really_quiet) /* write to terminal */
|
||||||
@ -964,7 +1027,7 @@ import_descend_dir (message, dir, vtag, targc, targv)
|
|||||||
}
|
}
|
||||||
err = import_descend (message, vtag, targc, targv);
|
err = import_descend (message, vtag, targc, targv);
|
||||||
out:
|
out:
|
||||||
if ((cp = rindex (repository, '/')) != NULL)
|
if ((cp = strrchr (repository, '/')) != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
else
|
else
|
||||||
repository[0] = '\0';
|
repository[0] = '\0';
|
||||||
@ -972,3 +1035,36 @@ import_descend_dir (message, dir, vtag, targc, targv)
|
|||||||
error (1, errno, "cannot chdir to %s", cwd);
|
error (1, errno, "cannot chdir to %s", cwd);
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* the following code is taken from code in rcs/src/rcssyn.c, and returns a
|
||||||
|
* positive value if 'expstring' contains a valid RCS expansion token for
|
||||||
|
* the -k option. If an invalid expansion is named, then return -1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
char const *const expand_names[] = {
|
||||||
|
/* These must agree with *_EXPAND in rcs/src/rcsbase.h. */
|
||||||
|
"kv","kvl","k","v","o",
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
str2expmode(s)
|
||||||
|
char const *s;
|
||||||
|
/* Yield expand mode corresponding to S, or -1 if bad. */
|
||||||
|
{
|
||||||
|
return strn2expmode(s, strlen(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
strn2expmode(s, n)
|
||||||
|
char const *s;
|
||||||
|
size_t n;
|
||||||
|
{
|
||||||
|
char const *const *p;
|
||||||
|
|
||||||
|
for (p = expand_names; *p; ++p)
|
||||||
|
if (memcmp(*p,s,n) == 0 && !(*p)[n])
|
||||||
|
return p - expand_names;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Set Lock
|
||||||
*
|
*
|
||||||
@ -13,30 +13,20 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
extern char *ctime ();
|
extern char *ctime ();
|
||||||
|
|
||||||
#if __STDC__
|
static int readers_exist PROTO((char *repository));
|
||||||
static int readers_exist (char *repository);
|
static int set_lock PROTO((char *lockdir, int will_wait, char *repository));
|
||||||
static int set_lock (char *lockdir, int will_wait, char *repository);
|
static void set_lockers_name PROTO((struct stat *statp));
|
||||||
static void set_lockers_name (struct stat *statp);
|
static int set_writelock_proc PROTO((Node * p, void *closure));
|
||||||
static int set_writelock_proc (Node * p);
|
static int unlock_proc PROTO((Node * p, void *closure));
|
||||||
static int unlock_proc (Node * p);
|
static int write_lock PROTO((char *repository));
|
||||||
static int write_lock (char *repository);
|
static void unlock PROTO((char *repository));
|
||||||
static void unlock (char *repository);
|
static void lock_wait PROTO((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 char lockers_name[20];
|
static char lockers_name[20];
|
||||||
static char *repository;
|
static char *repository;
|
||||||
@ -65,7 +55,7 @@ Lock_Cleanup ()
|
|||||||
/* clean up multiple locks (if any) */
|
/* clean up multiple locks (if any) */
|
||||||
if (locklist != (List *) NULL)
|
if (locklist != (List *) NULL)
|
||||||
{
|
{
|
||||||
(void) walklist (locklist, unlock_proc);
|
(void) walklist (locklist, unlock_proc, NULL);
|
||||||
locklist = (List *) NULL;
|
locklist = (List *) NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -74,8 +64,9 @@ Lock_Cleanup ()
|
|||||||
* walklist proc for removing a list of locks
|
* walklist proc for removing a list of locks
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
unlock_proc (p)
|
unlock_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
unlock (p->key);
|
unlock (p->key);
|
||||||
return (0);
|
return (0);
|
||||||
@ -94,13 +85,15 @@ unlock (repository)
|
|||||||
if (readlock[0] != '\0')
|
if (readlock[0] != '\0')
|
||||||
{
|
{
|
||||||
(void) sprintf (tmp, "%s/%s", repository, readlock);
|
(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')
|
if (writelock[0] != '\0')
|
||||||
{
|
{
|
||||||
(void) sprintf (tmp, "%s/%s", repository, writelock);
|
(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;
|
cleanup_lckdir = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Since some systems don't define this...
|
||||||
|
*/
|
||||||
|
#ifndef MAXHOSTNAMELEN
|
||||||
|
#define MAXHOSTNAMELEN 256
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a lock file for readers
|
* Create a lock file for readers
|
||||||
*/
|
*/
|
||||||
@ -127,10 +127,18 @@ Reader_Lock (xrepository)
|
|||||||
int err = 0;
|
int err = 0;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char tmp[PATH_MAX];
|
char tmp[PATH_MAX];
|
||||||
|
#ifdef HAVE_LONG_FILE_NAMES
|
||||||
|
char hostname[MAXHOSTNAMELEN];
|
||||||
|
#endif
|
||||||
|
|
||||||
if (noexec)
|
if (noexec)
|
||||||
return (0);
|
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! */
|
/* we only do one directory at a time for read locks! */
|
||||||
if (repository != NULL)
|
if (repository != NULL)
|
||||||
{
|
{
|
||||||
@ -139,7 +147,13 @@ Reader_Lock (xrepository)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (readlock[0] == '\0')
|
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) */
|
/* remember what we're locking (for lock_cleanup) */
|
||||||
repository = xrepository;
|
repository = xrepository;
|
||||||
@ -152,16 +166,24 @@ Reader_Lock (xrepository)
|
|||||||
(void) SIG_register (SIGTERM, Lock_Cleanup);
|
(void) SIG_register (SIGTERM, Lock_Cleanup);
|
||||||
|
|
||||||
/* make sure we can write the repository */
|
/* 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)
|
if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
|
||||||
{
|
{
|
||||||
error (0, errno, "cannot create read lock in repository `%s'",
|
error (0, errno, "cannot create read lock in repository `%s'",
|
||||||
xrepository);
|
xrepository);
|
||||||
readlock[0] = '\0';
|
readlock[0] = '\0';
|
||||||
(void) unlink (tmp);
|
if (unlink (tmp) < 0 && errno != ENOENT)
|
||||||
|
error (0, errno, "failed to remove lock %s", tmp);
|
||||||
return (1);
|
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 */
|
/* get the lock dir for our own */
|
||||||
(void) sprintf (tmp, "%s/%s", xrepository, CVSLCK);
|
(void) sprintf (tmp, "%s/%s", xrepository, CVSLCK);
|
||||||
@ -218,7 +240,7 @@ Writer_Lock (list)
|
|||||||
locklist = list; /* init for Lock_Cleanup */
|
locklist = list; /* init for Lock_Cleanup */
|
||||||
(void) strcpy (lockers_name, "unknown");
|
(void) strcpy (lockers_name, "unknown");
|
||||||
|
|
||||||
(void) walklist (list, set_writelock_proc);
|
(void) walklist (list, set_writelock_proc, NULL);
|
||||||
|
|
||||||
switch (lock_error)
|
switch (lock_error)
|
||||||
{
|
{
|
||||||
@ -247,8 +269,9 @@ Writer_Lock (list)
|
|||||||
* walklist proc for setting write locks
|
* walklist proc for setting write locks
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
set_writelock_proc (p)
|
set_writelock_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
/* if some lock was not OK, just skip this one */
|
/* if some lock was not OK, just skip this one */
|
||||||
if (lock_error != L_OK)
|
if (lock_error != L_OK)
|
||||||
@ -271,9 +294,23 @@ write_lock (repository)
|
|||||||
int status;
|
int status;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char tmp[PATH_MAX];
|
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')
|
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 */
|
/* make sure we clean up on error */
|
||||||
(void) SIG_register (SIGHUP, Lock_Cleanup);
|
(void) SIG_register (SIGHUP, Lock_Cleanup);
|
||||||
@ -283,15 +320,23 @@ write_lock (repository)
|
|||||||
(void) SIG_register (SIGTERM, Lock_Cleanup);
|
(void) SIG_register (SIGTERM, Lock_Cleanup);
|
||||||
|
|
||||||
/* make sure we can write the repository */
|
/* 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)
|
if ((fp = fopen (tmp, "w+")) == NULL || fclose (fp) == EOF)
|
||||||
{
|
{
|
||||||
error (0, errno, "cannot create write lock in repository `%s'",
|
error (0, errno, "cannot create write lock in repository `%s'",
|
||||||
repository);
|
repository);
|
||||||
(void) unlink (tmp);
|
if (unlink (tmp) < 0 && errno != ENOENT)
|
||||||
|
error (0, errno, "failed to remove lock %s", tmp);
|
||||||
return (L_ERROR);
|
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!) */
|
/* make sure the lock dir is ours (not necessarily unique to us!) */
|
||||||
(void) sprintf (tmp, "%s/%s", repository, CVSLCK);
|
(void) sprintf (tmp, "%s/%s", repository, CVSLCK);
|
||||||
@ -318,7 +363,9 @@ write_lock (repository)
|
|||||||
{
|
{
|
||||||
int xerrno = errno;
|
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 */
|
/* free the lock dir if we created it */
|
||||||
if (status == L_OK)
|
if (status == L_OK)
|
||||||
{
|
{
|
||||||
@ -349,9 +396,8 @@ readers_exist (repository)
|
|||||||
{
|
{
|
||||||
char line[MAXLINELEN];
|
char line[MAXLINELEN];
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct direct *dp;
|
struct dirent *dp;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
CONST char *regex_err;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
#ifdef CVS_FUDGELOCKS
|
#ifdef CVS_FUDGELOCKS
|
||||||
@ -361,43 +407,46 @@ readers_exist (repository)
|
|||||||
if ((dirp = opendir (repository)) == NULL)
|
if ((dirp = opendir (repository)) == NULL)
|
||||||
error (1, 0, "cannot open directory %s", repository);
|
error (1, 0, "cannot open directory %s", repository);
|
||||||
|
|
||||||
(void) sprintf (line, "^%s.*", CVSRFL);
|
errno = 0;
|
||||||
if ((regex_err = re_comp (line)) != NULL)
|
|
||||||
error (1, 0, "%s", regex_err);
|
|
||||||
|
|
||||||
while ((dp = readdir (dirp)) != NULL)
|
while ((dp = readdir (dirp)) != NULL)
|
||||||
{
|
{
|
||||||
(void) sprintf (line, "%s/%s", repository, dp->d_name);
|
if (fnmatch (CVSRFLPAT, dp->d_name, 0) == 0)
|
||||||
if (re_exec (dp->d_name))
|
|
||||||
{
|
{
|
||||||
#ifdef CVS_FUDGELOCKS
|
#ifdef CVS_FUDGELOCKS
|
||||||
time_t now;
|
time_t now;
|
||||||
|
|
||||||
(void) time (&now);
|
(void) time (&now);
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
(void) sprintf (line, "%s/%s", repository, dp->d_name);
|
||||||
* 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 (stat (line, &sb) != -1)
|
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)
|
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;
|
goto again;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
set_lockers_name (&sb);
|
set_lockers_name (&sb);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
if (stat (line, &sb) != -1)
|
|
||||||
set_lockers_name (&sb);
|
|
||||||
#endif
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
break;
|
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);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Print Log Information
|
||||||
*
|
*
|
||||||
@ -15,17 +15,13 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static Dtype log_dirproc PROTO((char *dir, char *repository, char *update_dir));
|
||||||
static Dtype log_dirproc (char *dir, char *repository, char *update_dir);
|
static int log_fileproc PROTO((char *file, char *update_dir, char *repository,
|
||||||
static int log_fileproc (char *file, char *update_dir, char *repository,
|
List * entries, List * srcfiles));
|
||||||
List * entries, List * srcfiles);
|
|
||||||
#else
|
|
||||||
static int log_fileproc ();
|
|
||||||
static Dtype log_dirproc ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char options[PATH_MAX];
|
static char options[PATH_MAX];
|
||||||
|
|
||||||
@ -76,7 +72,7 @@ cvslog (argc, argv)
|
|||||||
err = start_recursion (log_fileproc, (int (*) ()) NULL, log_dirproc,
|
err = start_recursion (log_fileproc, (int (*) ()) NULL, log_dirproc,
|
||||||
(int (*) ()) NULL, argc, argv, local,
|
(int (*) ()) NULL, argc, argv, local,
|
||||||
W_LOCAL | W_REPOS | W_ATTIC, 0, 1,
|
W_LOCAL | W_REPOS | W_ATTIC, 0, 1,
|
||||||
(char *) NULL, 1);
|
(char *) NULL, 1, 0);
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,8 +95,25 @@ log_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
p = findnode (srcfiles, file);
|
p = findnode (srcfiles, file);
|
||||||
if (p == NULL || (rcsfile = (RCSNode *) p->data) == NULL)
|
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)
|
if (!really_quiet)
|
||||||
error (0, 0, "nothing known about %s", file);
|
error (0, 0, "nothing known about %s", file);
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,36 +3,34 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
/* this is slightly dangerous, since it could conflict with other systems'
|
||||||
static int find_type (Node * p);
|
* own prototype.
|
||||||
static int fmt_proc (Node * p);
|
*/
|
||||||
static int logfile_write (char *repository, char *filter, char *title,
|
#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,
|
char *message, char *revision, FILE * logfp,
|
||||||
List * changes);
|
List * changes));
|
||||||
static int rcsinfo_proc (char *repository, char *template);
|
static int rcsinfo_proc PROTO((char *repository, char *template));
|
||||||
static int title_proc (Node * p);
|
static int title_proc PROTO((Node * p, void *closure));
|
||||||
static int update_logfile_proc (char *repository, char *filter);
|
static int update_logfile_proc PROTO((char *repository, char *filter));
|
||||||
static void setup_tmpfile (FILE * xfp, char *xprefix, List * changes);
|
static void setup_tmpfile PROTO((FILE * xfp, char *xprefix, List * changes));
|
||||||
static int editinfo_proc (char *repository, char *template);
|
static int editinfo_proc PROTO((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__ */
|
|
||||||
|
|
||||||
static FILE *fp;
|
static FILE *fp;
|
||||||
static char *strlist;
|
static char *strlist;
|
||||||
@ -42,8 +40,7 @@ static Ctype type;
|
|||||||
/*
|
/*
|
||||||
* Puts a standard header on the output which is either being prepared for an
|
* 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,
|
* 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 char *prefix;
|
||||||
static int col;
|
static int col;
|
||||||
static void
|
static void
|
||||||
@ -57,30 +54,30 @@ setup_tmpfile (xfp, xprefix, changes)
|
|||||||
prefix = xprefix;
|
prefix = xprefix;
|
||||||
|
|
||||||
type = T_MODIFIED;
|
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, "%sModified Files:\n", prefix);
|
||||||
(void) fprintf (fp, "%s\t", prefix);
|
(void) fprintf (fp, "%s\t", prefix);
|
||||||
col = 8;
|
col = 8;
|
||||||
(void) walklist (changes, fmt_proc);
|
(void) walklist (changes, fmt_proc, NULL);
|
||||||
(void) fprintf (fp, "\n");
|
(void) fprintf (fp, "\n");
|
||||||
}
|
}
|
||||||
type = T_ADDED;
|
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, "%sAdded Files:\n", prefix);
|
||||||
(void) fprintf (fp, "%s\t", prefix);
|
(void) fprintf (fp, "%s\t", prefix);
|
||||||
col = 8;
|
col = 8;
|
||||||
(void) walklist (changes, fmt_proc);
|
(void) walklist (changes, fmt_proc, NULL);
|
||||||
(void) fprintf (fp, "\n");
|
(void) fprintf (fp, "\n");
|
||||||
}
|
}
|
||||||
type = T_REMOVED;
|
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, "%sRemoved Files:\n", prefix);
|
||||||
(void) fprintf (fp, "%s\t", prefix);
|
(void) fprintf (fp, "%s\t", prefix);
|
||||||
col = 8;
|
col = 8;
|
||||||
(void) walklist (changes, fmt_proc);
|
(void) walklist (changes, fmt_proc, NULL);
|
||||||
(void) fprintf (fp, "\n");
|
(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
|
* Looks for nodes of a specified type and returns 1 if found
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
find_type (p)
|
find_type (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
if (p->data == (char *) type)
|
if (p->data == (char *) type)
|
||||||
return (1);
|
return (1);
|
||||||
@ -104,8 +102,9 @@ find_type (p)
|
|||||||
* match the one we're looking for
|
* match the one we're looking for
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
fmt_proc (p)
|
fmt_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
if (p->data == (char *) type)
|
if (p->data == (char *) type)
|
||||||
{
|
{
|
||||||
@ -131,41 +130,40 @@ fmt_proc (p)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
do_editor (dir, message, repository, changes)
|
do_editor (dir, messagep, repository, changes)
|
||||||
char *dir;
|
char *dir;
|
||||||
char *message;
|
char **messagep;
|
||||||
char *repository;
|
char *repository;
|
||||||
List *changes;
|
List *changes;
|
||||||
{
|
{
|
||||||
static int reuse_log_message = 0;
|
static int reuse_log_message = 0;
|
||||||
char line[MAXLINELEN], fname[L_tmpnam+1];
|
char line[MAXLINELEN], fname[L_tmpnam+1];
|
||||||
char *orig_message;
|
|
||||||
struct stat pre_stbuf, post_stbuf;
|
struct stat pre_stbuf, post_stbuf;
|
||||||
int retcode = 0;
|
int retcode = 0;
|
||||||
|
char *p;
|
||||||
|
|
||||||
if (noexec || reuse_log_message)
|
if (noexec || reuse_log_message)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
orig_message = xstrdup (message); /* save it for later */
|
|
||||||
|
|
||||||
/* Create a temporary file */
|
/* Create a temporary file */
|
||||||
(void) tmpnam (fname);
|
(void) tmpnam (fname);
|
||||||
again:
|
again:
|
||||||
if ((fp = fopen (fname, "w+")) == NULL)
|
if ((fp = fopen (fname, "w+")) == NULL)
|
||||||
error (1, 0, "cannot create temporary file %s", fname);
|
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 (*messagep)
|
||||||
if (*orig_message)
|
|
||||||
{
|
{
|
||||||
(void) fprintf (fp, "%s", orig_message);
|
(void) fprintf (fp, "%s", *messagep);
|
||||||
if (orig_message[strlen (orig_message) - 1] != '\n')
|
|
||||||
|
if ((*messagep)[strlen (*messagep) - 1] != '\n')
|
||||||
(void) fprintf (fp, "\n");
|
(void) fprintf (fp, "\n");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(void) fprintf (fp, "\n");
|
(void) fprintf (fp, "\n");
|
||||||
|
|
||||||
/* tack templates on if necessary */
|
if (repository != NULL)
|
||||||
(void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, 1);
|
/* tack templates on if necessary */
|
||||||
|
(void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, 1);
|
||||||
|
|
||||||
(void) fprintf (fp,
|
(void) fprintf (fp,
|
||||||
"%s----------------------------------------------------------------------\n",
|
"%s----------------------------------------------------------------------\n",
|
||||||
@ -176,7 +174,8 @@ do_editor (dir, message, repository, changes)
|
|||||||
if (dir != NULL)
|
if (dir != NULL)
|
||||||
(void) fprintf (fp, "%sCommitting in %s\n%s\n", CVSEDITPREFIX,
|
(void) fprintf (fp, "%sCommitting in %s\n%s\n", CVSEDITPREFIX,
|
||||||
dir, CVSEDITPREFIX);
|
dir, CVSEDITPREFIX);
|
||||||
setup_tmpfile (fp, CVSEDITPREFIX, changes);
|
if (changes != NULL)
|
||||||
|
setup_tmpfile (fp, CVSEDITPREFIX, changes);
|
||||||
(void) fprintf (fp,
|
(void) fprintf (fp,
|
||||||
"%s----------------------------------------------------------------------\n",
|
"%s----------------------------------------------------------------------\n",
|
||||||
CVSEDITPREFIX);
|
CVSEDITPREFIX);
|
||||||
@ -189,7 +188,8 @@ do_editor (dir, message, repository, changes)
|
|||||||
if (editinfo_editor)
|
if (editinfo_editor)
|
||||||
free (editinfo_editor);
|
free (editinfo_editor);
|
||||||
editinfo_editor = (char *) NULL;
|
editinfo_editor = (char *) NULL;
|
||||||
(void) Parse_Info (CVSROOTADM_EDITINFO, repository, editinfo_proc, 0);
|
if (repository != NULL)
|
||||||
|
(void) Parse_Info (CVSROOTADM_EDITINFO, repository, editinfo_proc, 0);
|
||||||
|
|
||||||
/* run the editor */
|
/* run the editor */
|
||||||
run_setup ("%s", editinfo_editor ? editinfo_editor : Editor);
|
run_setup ("%s", editinfo_editor ? editinfo_editor : Editor);
|
||||||
@ -200,29 +200,47 @@ do_editor (dir, message, repository, changes)
|
|||||||
editinfo_editor ? "Logfile verification failed" :
|
editinfo_editor ? "Logfile verification failed" :
|
||||||
"warning: editor session 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");
|
fp = open_file (fname, "r");
|
||||||
*message = '\0';
|
|
||||||
while (fgets (line, sizeof (line), fp) != NULL)
|
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
|
||||||
{
|
{
|
||||||
if (strncmp (line, CVSEDITPREFIX, sizeof (CVSEDITPREFIX) - 1) == 0)
|
*messagep = (char *) xmalloc (post_stbuf.st_size);
|
||||||
continue;
|
*messagep[0] = '\0';
|
||||||
if (((int) strlen (message) + (int) strlen (line)) >= MAXMESGLEN)
|
}
|
||||||
|
|
||||||
|
/* !!! XXX FIXME: fgets is broken. This should not have any line
|
||||||
|
length limits. */
|
||||||
|
|
||||||
|
if (*messagep)
|
||||||
|
{
|
||||||
|
p = *messagep;
|
||||||
|
while (fgets (line, sizeof (line), fp) != NULL)
|
||||||
{
|
{
|
||||||
error (0, 0, "warning: log message truncated!");
|
if (strncmp (line, CVSEDITPREFIX, sizeof (CVSEDITPREFIX) - 1) == 0)
|
||||||
break;
|
continue;
|
||||||
|
(void) strcpy (p, line);
|
||||||
|
p += strlen (line);
|
||||||
}
|
}
|
||||||
(void) strcat (message, line);
|
|
||||||
}
|
}
|
||||||
(void) fclose (fp);
|
(void) fclose (fp);
|
||||||
if ((stat (fname, &post_stbuf) == 0 &&
|
if (pre_stbuf.st_mtime == post_stbuf.st_mtime ||
|
||||||
pre_stbuf.st_mtime == post_stbuf.st_mtime) ||
|
*messagep == NULL ||
|
||||||
(*message == '\0' || strcmp (message, "\n") == 0))
|
strcmp (*messagep, "\n") == 0)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
(void) printf ("\nLog message unchanged or not specified\n");
|
(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) printf ("Action: (continue) ");
|
||||||
(void) fflush (stdout);
|
(void) fflush (stdout);
|
||||||
*line = '\0';
|
*line = '\0';
|
||||||
@ -241,7 +259,6 @@ do_editor (dir, message, repository, changes)
|
|||||||
(void) printf ("Unknown input\n");
|
(void) printf ("Unknown input\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free (orig_message);
|
|
||||||
(void) unlink_file (fname);
|
(void) unlink_file (fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,6 +320,10 @@ Update_Logfile (repository, xmessage, xrevision, xlogfp, xchanges)
|
|||||||
{
|
{
|
||||||
char *srepos;
|
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 */
|
/* set up static vars for update_logfile_proc */
|
||||||
message = xmessage;
|
message = xmessage;
|
||||||
revision = xrevision;
|
revision = xrevision;
|
||||||
@ -318,13 +339,13 @@ Update_Logfile (repository, xmessage, xrevision, xlogfp, xchanges)
|
|||||||
strlist[0] = '\0';
|
strlist[0] = '\0';
|
||||||
|
|
||||||
type = T_TITLE;
|
type = T_TITLE;
|
||||||
(void) walklist (changes, title_proc);
|
(void) walklist (changes, title_proc, NULL);
|
||||||
type = T_ADDED;
|
type = T_ADDED;
|
||||||
(void) walklist (changes, title_proc);
|
(void) walklist (changes, title_proc, NULL);
|
||||||
type = T_MODIFIED;
|
type = T_MODIFIED;
|
||||||
(void) walklist (changes, title_proc);
|
(void) walklist (changes, title_proc, NULL);
|
||||||
type = T_REMOVED;
|
type = T_REMOVED;
|
||||||
(void) walklist (changes, title_proc);
|
(void) walklist (changes, title_proc, NULL);
|
||||||
title = xmalloc (strlen (srepos) + strlen (strlist) + 1 + 2); /* for 's */
|
title = xmalloc (strlen (srepos) + strlen (strlist) + 1 + 2); /* for 's */
|
||||||
(void) sprintf (title, "'%s%s'", srepos, strlist);
|
(void) sprintf (title, "'%s%s'", srepos, strlist);
|
||||||
|
|
||||||
@ -355,8 +376,9 @@ update_logfile_proc (repository, filter)
|
|||||||
* concatenate each name onto strlist
|
* concatenate each name onto strlist
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
title_proc (p)
|
title_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
if (p->data == (char *) type)
|
if (p->data == (char *) type)
|
||||||
{
|
{
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License
|
* 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.
|
||||||
*
|
*
|
||||||
* This is the main C driver for the CVS system.
|
* This is the main C driver for the CVS system.
|
||||||
*
|
*
|
||||||
@ -35,7 +35,10 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
#include "patchlevel.h"
|
#include "patchlevel.h"
|
||||||
|
|
||||||
char rcsid[] = "@(#)main.c 1.64 92/03/31\n";
|
#ifndef lint
|
||||||
|
char rcsid[] = "$CVSid: @(#)main.c 1.78 94/10/07 $\n";
|
||||||
|
USE(rcsid)
|
||||||
|
#endif
|
||||||
|
|
||||||
extern char *getenv ();
|
extern char *getenv ();
|
||||||
|
|
||||||
@ -43,6 +46,7 @@ char *program_name;
|
|||||||
char *command_name = "";
|
char *command_name = "";
|
||||||
|
|
||||||
int use_editor = TRUE;
|
int use_editor = TRUE;
|
||||||
|
int use_cvsrc = TRUE;
|
||||||
int cvswrite = !CVSREAD_DFLT;
|
int cvswrite = !CVSREAD_DFLT;
|
||||||
int really_quiet = FALSE;
|
int really_quiet = FALSE;
|
||||||
int quiet = FALSE;
|
int quiet = FALSE;
|
||||||
@ -58,40 +62,28 @@ char *CurDir;
|
|||||||
char *Rcsbin = RCSBIN_DFLT;
|
char *Rcsbin = RCSBIN_DFLT;
|
||||||
char *Editor = EDITOR_DFLT;
|
char *Editor = EDITOR_DFLT;
|
||||||
char *CVSroot = CVSROOT_DFLT;
|
char *CVSroot = CVSROOT_DFLT;
|
||||||
|
#ifdef CVSADM_ROOT
|
||||||
|
/*
|
||||||
|
* The path found in CVS/Root must match $CVSROOT and/or 'cvs -d root'
|
||||||
|
*/
|
||||||
|
char *CVSADM_Root = CVSROOT_DFLT;
|
||||||
|
#endif /* CVSADM_ROOT */
|
||||||
|
|
||||||
#if __STDC__
|
int add PROTO((int argc, char **argv));
|
||||||
int add (int argc, char **argv);
|
int admin PROTO((int argc, char **argv));
|
||||||
int admin (int argc, char **argv);
|
int checkout PROTO((int argc, char **argv));
|
||||||
int checkout (int argc, char **argv);
|
int commit PROTO((int argc, char **argv));
|
||||||
int commit (int argc, char **argv);
|
int diff PROTO((int argc, char **argv));
|
||||||
int diff (int argc, char **argv);
|
int history PROTO((int argc, char **argv));
|
||||||
int history (int argc, char **argv);
|
int import PROTO((int argc, char **argv));
|
||||||
int import (int argc, char **argv);
|
int cvslog PROTO((int argc, char **argv));
|
||||||
int cvslog (int argc, char **argv);
|
int patch PROTO((int argc, char **argv));
|
||||||
int patch (int argc, char **argv);
|
int release PROTO((int argc, char **argv));
|
||||||
int release (int argc, char **argv);
|
int cvsremove PROTO((int argc, char **argv));
|
||||||
int cvsremove (int argc, char **argv);
|
int rtag PROTO((int argc, char **argv));
|
||||||
int rtag (int argc, char **argv);
|
int status PROTO((int argc, char **argv));
|
||||||
int status (int argc, char **argv);
|
int tag PROTO((int argc, char **argv));
|
||||||
int tag (int argc, char **argv);
|
int update PROTO((int argc, char **argv));
|
||||||
int update (int argc, char **argv);
|
|
||||||
#else
|
|
||||||
int add ();
|
|
||||||
int admin ();
|
|
||||||
int checkout ();
|
|
||||||
int commit ();
|
|
||||||
int diff ();
|
|
||||||
int history ();
|
|
||||||
int import ();
|
|
||||||
int cvslog ();
|
|
||||||
int patch ();
|
|
||||||
int release ();
|
|
||||||
int cvsremove ();
|
|
||||||
int rtag ();
|
|
||||||
int status ();
|
|
||||||
int tag ();
|
|
||||||
int update ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
struct cmd
|
struct cmd
|
||||||
{
|
{
|
||||||
@ -137,6 +129,7 @@ static char *usg[] =
|
|||||||
" -b bindir Find RCS programs in 'bindir'\n",
|
" -b bindir Find RCS programs in 'bindir'\n",
|
||||||
" -e editor Use 'editor' for editing log information\n",
|
" -e editor Use 'editor' for editing log information\n",
|
||||||
" -d CVS_root Overrides $CVSROOT as the root of the CVS tree\n",
|
" -d CVS_root Overrides $CVSROOT as the root of the CVS tree\n",
|
||||||
|
" -f Do not use the ~/.cvsrc file\n",
|
||||||
"\n",
|
"\n",
|
||||||
" and where 'command' is:\n",
|
" and where 'command' is:\n",
|
||||||
" add Adds a new file/directory to the repository\n",
|
" add Adds a new file/directory to the repository\n",
|
||||||
@ -158,7 +151,7 @@ static char *usg[] =
|
|||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static SIGTYPE
|
static RETSIGTYPE
|
||||||
main_cleanup ()
|
main_cleanup ()
|
||||||
{
|
{
|
||||||
exit (1);
|
exit (1);
|
||||||
@ -173,13 +166,13 @@ main (argc, argv)
|
|||||||
char *cp;
|
char *cp;
|
||||||
struct cmd *cm;
|
struct cmd *cm;
|
||||||
int c, help = FALSE, err = 0;
|
int c, help = FALSE, err = 0;
|
||||||
int rcsbin_update_env, cvs_update_env;
|
int rcsbin_update_env, cvs_update_env = 0;
|
||||||
char tmp[PATH_MAX];
|
char tmp[PATH_MAX];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Just save the last component of the path for error messages
|
* 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];
|
program_name = argv[0];
|
||||||
else
|
else
|
||||||
program_name++;
|
program_name++;
|
||||||
@ -193,12 +186,15 @@ main (argc, argv)
|
|||||||
* they can be overridden by command line arguments
|
* they can be overridden by command line arguments
|
||||||
*/
|
*/
|
||||||
rcsbin_update_env = *Rcsbin; /* RCSBIN_DFLT must be set */
|
rcsbin_update_env = *Rcsbin; /* RCSBIN_DFLT must be set */
|
||||||
|
cvs_update_env = 0;
|
||||||
if ((cp = getenv (RCSBIN_ENV)) != NULL)
|
if ((cp = getenv (RCSBIN_ENV)) != NULL)
|
||||||
{
|
{
|
||||||
Rcsbin = cp;
|
Rcsbin = cp;
|
||||||
rcsbin_update_env = 0; /* it's already there */
|
rcsbin_update_env = 0; /* it's already there */
|
||||||
}
|
}
|
||||||
if ((cp = getenv (EDITOR_ENV)) != NULL)
|
if ((cp = getenv (EDITOR1_ENV)) != NULL)
|
||||||
|
Editor = cp;
|
||||||
|
else if ((cp = getenv (EDITOR2_ENV)) != NULL)
|
||||||
Editor = cp;
|
Editor = cp;
|
||||||
if ((cp = getenv (CVSROOT_ENV)) != NULL)
|
if ((cp = getenv (CVSROOT_ENV)) != NULL)
|
||||||
{
|
{
|
||||||
@ -209,7 +205,7 @@ main (argc, argv)
|
|||||||
cvswrite = FALSE;
|
cvswrite = FALSE;
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "Qqrwtnlvb:e:d:H")) != -1)
|
while ((c = getopt (argc, argv, "Qqrwtnlvb:e:d:Hf")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -234,11 +230,10 @@ main (argc, argv)
|
|||||||
logoff = TRUE;
|
logoff = TRUE;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
(void) fputs (rcsid, stdout);
|
|
||||||
(void) fputs (version_string, stdout);
|
(void) fputs (version_string, stdout);
|
||||||
(void) sprintf (tmp, "Patch Level: %d\n", PATCHLEVEL);
|
(void) sprintf (tmp, "Patch Level: %d\n", PATCHLEVEL);
|
||||||
(void) fputs (tmp, stdout);
|
(void) fputs (tmp, stdout);
|
||||||
(void) fputs ("\nCopyright (c) 1992, Brian Berliner and Jeff Polk\nCopyright (c) 1989-1992, Brian Berliner\n\nCVS may be copied only under the terms of the GNU General Public License,\na copy of which can be found with the CVS 1.3 distribution kit.\n", stdout);
|
(void) fputs ("\nCopyright (c) 1993-1994 Brian Berliner\nCopyright (c) 1993-1994 david d `zoo' zuhn\nCopyright (c) 1992, Brian Berliner and Jeff Polk\nCopyright (c) 1989-1992, Brian Berliner\n\nCVS may be copied only under the terms of the GNU General Public License,\na copy of which can be found with the CVS distribution kit.\n", stdout);
|
||||||
exit (0);
|
exit (0);
|
||||||
break;
|
break;
|
||||||
case 'b':
|
case 'b':
|
||||||
@ -253,8 +248,12 @@ main (argc, argv)
|
|||||||
cvs_update_env = 1; /* need to update environment */
|
cvs_update_env = 1; /* need to update environment */
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
|
use_cvsrc = FALSE; /* this ensure that cvs -H works */
|
||||||
help = TRUE;
|
help = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
use_cvsrc = FALSE;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage (usg);
|
usage (usg);
|
||||||
@ -265,25 +264,49 @@ main (argc, argv)
|
|||||||
if (argc < 1)
|
if (argc < 1)
|
||||||
usage (usg);
|
usage (usg);
|
||||||
|
|
||||||
|
#ifdef CVSADM_ROOT
|
||||||
/*
|
/*
|
||||||
* XXX - Compatibility. This can be removed in the release after CVS 1.3.
|
* See if we are able to find a 'better' value for CVSroot in the
|
||||||
* Try to rename the CVSROOT.adm file to CVSROOT, unless there already is
|
* CVSADM_ROOT directory.
|
||||||
* a CVSROOT directory.
|
|
||||||
*/
|
*/
|
||||||
if (CVSroot != NULL)
|
CVSADM_Root = Name_Root((char *) NULL, (char *) NULL);
|
||||||
|
if (CVSADM_Root != NULL)
|
||||||
{
|
{
|
||||||
char rootadm[PATH_MAX];
|
if (CVSroot == NULL)
|
||||||
char orootadm[PATH_MAX];
|
{
|
||||||
|
CVSroot = CVSADM_Root;
|
||||||
(void) sprintf (rootadm, "%s/%s", CVSroot, CVSROOTADM);
|
cvs_update_env = 1; /* need to update environment */
|
||||||
if (!isdir (rootadm))
|
}
|
||||||
{
|
else
|
||||||
(void) sprintf (orootadm, "%s/%s", CVSroot, OCVSROOTADM);
|
{
|
||||||
if (isdir (orootadm))
|
/*
|
||||||
(void) rename (orootadm, rootadm);
|
* Now for the hard part, compare the two directories. If they
|
||||||
}
|
* are not identical, then abort this command.
|
||||||
strip_path (CVSroot);
|
*/
|
||||||
|
if ((strcmp (CVSroot, CVSADM_Root) != 0) &&
|
||||||
|
!same_directories(CVSroot, CVSADM_Root))
|
||||||
|
{
|
||||||
|
error (0, 0, "%s value for CVS Root found in %s",
|
||||||
|
CVSADM_Root, CVSADM_ROOT);
|
||||||
|
if (cvs_update_env)
|
||||||
|
{
|
||||||
|
error (0, 0, "does not match command line -d %s setting",
|
||||||
|
CVSroot);
|
||||||
|
error (1, 0,
|
||||||
|
"you may wish to try the cvs command again without the -d option ");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
error (0, 0,
|
||||||
|
"does not match CVSROOT environment value of %s",
|
||||||
|
CVSroot);
|
||||||
|
error (1, 0,
|
||||||
|
"you may wish to unsetenv CVSROOT and try again");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif /* CVSADM_ROOT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Specifying just the '-H' flag to the sub-command causes a Usage
|
* Specifying just the '-H' flag to the sub-command causes a Usage
|
||||||
@ -326,7 +349,7 @@ main (argc, argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PUTENV_MISSING
|
#ifdef HAVE_PUTENV
|
||||||
/* Now, see if we should update the environment with the Rcsbin value */
|
/* Now, see if we should update the environment with the Rcsbin value */
|
||||||
if (cvs_update_env)
|
if (cvs_update_env)
|
||||||
{
|
{
|
||||||
@ -387,7 +410,7 @@ main (argc, argv)
|
|||||||
(void) SIG_register (SIGPIPE, main_cleanup);
|
(void) SIG_register (SIGPIPE, main_cleanup);
|
||||||
(void) SIG_register (SIGTERM, main_cleanup);
|
(void) SIG_register (SIGTERM, main_cleanup);
|
||||||
|
|
||||||
#ifndef SETVBUF_MISSING
|
#ifdef HAVE_SETVBUF
|
||||||
/*
|
/*
|
||||||
* Make stdout line buffered, so 'tail -f' can monitor progress.
|
* Make stdout line buffered, so 'tail -f' can monitor progress.
|
||||||
* Patch creates too much output to monitor and it runs slowly.
|
* Patch creates too much output to monitor and it runs slowly.
|
||||||
@ -396,7 +419,11 @@ main (argc, argv)
|
|||||||
(void) setvbuf (stdout, (char *) NULL, _IOLBF, 0);
|
(void) setvbuf (stdout, (char *) NULL, _IOLBF, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (use_cvsrc)
|
||||||
|
read_cvsrc(&argc, &argv);
|
||||||
|
|
||||||
err = (*(cm->func)) (argc, argv);
|
err = (*(cm->func)) (argc, argv);
|
||||||
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* If the command's error count is modulo 256, we need to change it
|
* If the command's error count is modulo 256, we need to change it
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License
|
* 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
|
* Modules
|
||||||
*
|
*
|
||||||
@ -23,7 +23,8 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
struct sortrec
|
struct sortrec
|
||||||
@ -34,13 +35,8 @@ struct sortrec
|
|||||||
char *comment;
|
char *comment;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if __STDC__
|
static int sort_order PROTO((CONST PTR l, CONST PTR r));
|
||||||
static int sort_order (CONST PTR l, CONST PTR r);
|
static void save_d PROTO((char *k, int ks, char *d, int ds));
|
||||||
static void save_d (char *k, int ks, char *d, int ds);
|
|
||||||
#else
|
|
||||||
static int sort_order ();
|
|
||||||
static void save_d ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -117,6 +113,13 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
|||||||
if (getwd (cwd) == NULL)
|
if (getwd (cwd) == NULL)
|
||||||
error (1, 0, "cannot get current working directory: %s", cwd);
|
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 extra stuff from the module name */
|
||||||
strip_path (mname);
|
strip_path (mname);
|
||||||
|
|
||||||
@ -142,12 +145,20 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
|||||||
val.dptr[val.dsize] = '\0';
|
val.dptr[val.dsize] = '\0';
|
||||||
|
|
||||||
/* If the line ends in a comment, strip it off */
|
/* If the line ends in a comment, strip it off */
|
||||||
if ((cp = index (val.dptr, '#')) != NULL)
|
if ((cp = strchr (val.dptr, '#')) != NULL)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
*cp-- = '\0';
|
*cp-- = '\0';
|
||||||
while (isspace (*cp));
|
while (isspace (*cp));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Always strip trailing spaces */
|
||||||
|
cp = strchr (val.dptr, '\0');
|
||||||
|
while (cp > val.dptr && isspace(*--cp))
|
||||||
|
*cp = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
value = val.dptr;
|
value = val.dptr;
|
||||||
mwhere = xstrdup (mname);
|
mwhere = xstrdup (mname);
|
||||||
goto found;
|
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 */
|
/* check to see if mname is a directory or file */
|
||||||
|
|
||||||
(void) sprintf (file, "%s/%s", CVSroot, mname);
|
(void) sprintf (file, "%s/%s", CVSroot, mname);
|
||||||
if ((acp = rindex (mname, '/')) != NULL)
|
if ((acp = strrchr (mname, '/')) != NULL)
|
||||||
{
|
{
|
||||||
*acp = '\0';
|
*acp = '\0';
|
||||||
(void) sprintf (attic_file, "%s/%s/%s/%s%s", CVSroot, mname,
|
(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 (isfile (file) || isfile (attic_file))
|
||||||
{
|
{
|
||||||
/* if mname was a file, we have to split it into "dir 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;
|
char *slashp;
|
||||||
|
|
||||||
/* put the ' ' in a copy so we don't mess up the original */
|
/* put the ' ' in a copy so we don't mess up the original */
|
||||||
value = strcpy (xvalue, mname);
|
value = strcpy (xvalue, mname);
|
||||||
slashp = rindex (value, '/');
|
slashp = strrchr (value, '/');
|
||||||
*slashp = ' ';
|
*slashp = ' ';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -218,7 +229,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* look up everything to the first / as a module */
|
/* 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 */
|
/* Make the slash the new end of the string temporarily */
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
@ -240,7 +251,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
|||||||
val.dptr[val.dsize] = '\0';
|
val.dptr[val.dsize] = '\0';
|
||||||
|
|
||||||
/* If the line ends in a comment, strip it off */
|
/* If the line ends in a comment, strip it off */
|
||||||
if ((cp2 = index (val.dptr, '#')) != NULL)
|
if ((cp2 = strchr (val.dptr, '#')) != NULL)
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
*cp2-- = '\0';
|
*cp2-- = '\0';
|
||||||
@ -282,7 +293,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
|||||||
value = zvalue;
|
value = zvalue;
|
||||||
|
|
||||||
/* search the value for the special delimiter and save for later */
|
/* 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 */
|
*cp = '\0'; /* null out the special char */
|
||||||
spec_opt = cp + 1; /* save the options for later */
|
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);
|
CVSROOTADM, CVSNULLREPOS);
|
||||||
if (!isfile (nullrepos))
|
if (!isfile (nullrepos))
|
||||||
(void) mkdir (nullrepos, 0777);
|
(void) mkdir (nullrepos, 0777);
|
||||||
|
if (!isdir (nullrepos))
|
||||||
|
error (1, 0, "there is no repository %s", nullrepos);
|
||||||
|
|
||||||
Create_Admin (".", nullrepos, (char *) NULL, (char *) NULL);
|
Create_Admin (".", nullrepos, (char *) NULL, (char *) NULL);
|
||||||
if (!noexec)
|
if (!noexec)
|
||||||
{
|
{
|
||||||
@ -363,7 +377,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
|||||||
|
|
||||||
/* parse the args */
|
/* parse the args */
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (modargc, modargv, CVSMODULE_OPTS)) != -1)
|
while ((c = getopt (modargc, modargv, CVSMODULE_OPTS)) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -417,9 +431,16 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < modargc; i++)
|
for (i = 0; i < modargc; i++)
|
||||||
err += do_module (db, modargv[i], m_type, msg, callback_proc,
|
{
|
||||||
where, shorten, local_specified,
|
if (strcmp (mname, modargv[i]) == 0)
|
||||||
run_module_prog, extra_arg);
|
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)
|
if (mwhere)
|
||||||
free (mwhere);
|
free (mwhere);
|
||||||
free (zvalue);
|
free (zvalue);
|
||||||
@ -445,7 +466,7 @@ do_module (db, mname, m_type, msg, callback_proc, where,
|
|||||||
{
|
{
|
||||||
char *next_opt;
|
char *next_opt;
|
||||||
|
|
||||||
cp = index (spec_opt, CVSMODULE_SPEC);
|
cp = strchr (spec_opt, CVSMODULE_SPEC);
|
||||||
if (cp != NULL)
|
if (cp != NULL)
|
||||||
{
|
{
|
||||||
/* save the beginning of the next arg */
|
/* save the beginning of the next arg */
|
||||||
@ -648,7 +669,7 @@ save_d (k, ks, d, ds)
|
|||||||
s_rec->status = def_status;
|
s_rec->status = def_status;
|
||||||
|
|
||||||
/* Minor kluge, but general enough to maintain */
|
/* 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) == ' ')
|
if (*(cp2 + 1) == 's' && *(cp2 + 2) == ' ')
|
||||||
{
|
{
|
||||||
@ -665,7 +686,7 @@ save_d (k, ks, d, ds)
|
|||||||
cp = s_rec->rest;
|
cp = s_rec->rest;
|
||||||
|
|
||||||
/* Find comment field, clean up on all three sides & compress blanks */
|
/* 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 == ' ')
|
if (*--cp2 == ' ')
|
||||||
*cp2 = '\0';
|
*cp2 = '\0';
|
||||||
@ -748,13 +769,13 @@ cat_module (status)
|
|||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
wid = 0;
|
wid = 0;
|
||||||
while ((c = gnu_getopt (argc, argv, CVSMODULE_OPTS)) != -1)
|
while ((c = getopt (argc, argv, CVSMODULE_OPTS)) != -1)
|
||||||
{
|
{
|
||||||
if (!status)
|
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 */
|
wid += 3; /* Could just set it to 3 */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* No Difference
|
||||||
*
|
*
|
||||||
@ -17,14 +17,17 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
No_Difference (file, vers, entries)
|
No_Difference (file, vers, entries, repository, update_dir)
|
||||||
char *file;
|
char *file;
|
||||||
Vers_TS *vers;
|
Vers_TS *vers;
|
||||||
List *entries;
|
List *entries;
|
||||||
|
char *repository;
|
||||||
|
char *update_dir;
|
||||||
{
|
{
|
||||||
Node *p;
|
Node *p;
|
||||||
char tmp[L_tmpnam+1];
|
char tmp[L_tmpnam+1];
|
||||||
@ -58,7 +61,7 @@ No_Difference (file, vers, entries)
|
|||||||
ts = time_stamp (file);
|
ts = time_stamp (file);
|
||||||
Register (entries, file,
|
Register (entries, file,
|
||||||
vers->vn_user ? vers->vn_user : vers->vn_rcs, ts,
|
vers->vn_user ? vers->vn_user : vers->vn_rcs, ts,
|
||||||
options, vers->tag, vers->date);
|
options, vers->tag, vers->date, (char *) 0);
|
||||||
free (ts);
|
free (ts);
|
||||||
|
|
||||||
/* update the entdata pointer in the vers_ts structure */
|
/* update the entdata pointer in the vers_ts structure */
|
||||||
@ -72,14 +75,21 @@ No_Difference (file, vers, entries)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error (0, retcode == -1 ? errno : 0,
|
if (update_dir[0] == '\0')
|
||||||
"could not check out revision %s of %s", vers->vn_user, file);
|
error (0, retcode == -1 ? errno : 0,
|
||||||
|
"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 */
|
ret = -1; /* different since we couldn't tell */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trace)
|
if (trace)
|
||||||
(void) fprintf (stderr, "-> unlink(%s)\n", tmp);
|
(void) fprintf (stderr, "-> unlink(%s)\n", tmp);
|
||||||
(void) unlink (tmp);
|
if (unlink (tmp) < 0)
|
||||||
|
error (0, errno, "could not remove %s", tmp);
|
||||||
free (options);
|
free (options);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,14 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -87,7 +88,7 @@ Parse_Info (infofile, repository, callproc, all)
|
|||||||
value = cp;
|
value = cp;
|
||||||
|
|
||||||
/* strip the newline off the end of the value */
|
/* strip the newline off the end of the value */
|
||||||
if ((cp = rindex (value, '\n')) != NULL)
|
if ((cp = strrchr (value, '\n')) != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
||||||
*
|
*
|
||||||
* Patch
|
* Patch
|
||||||
*
|
*
|
||||||
@ -15,24 +15,17 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)patch.c 1.50 92/04/10";
|
static char rcsid[] = "$CVSid: @(#)patch.c 1.57 94/09/30 $";
|
||||||
|
USE(rcsid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static RETSIGTYPE patch_cleanup PROTO((void));
|
||||||
static SIGTYPE patch_cleanup (void);
|
static Dtype patch_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||||
static Dtype patch_dirproc (char *dir, char *repos, char *update_dir);
|
static int patch_fileproc PROTO((char *file, char *update_dir, char *repository,
|
||||||
static int patch_fileproc (char *file, char *update_dir, char *repository,
|
List * entries, List * srcfiles));
|
||||||
List * entries, List * srcfiles);
|
static int patch_proc PROTO((int *pargc, char *argv[], char *xwhere,
|
||||||
static int patch_proc (int *pargc, char *argv[], char *xwhere,
|
|
||||||
char *mwhere, char *mfile, int shorten,
|
char *mwhere, char *mfile, int shorten,
|
||||||
int local_specified, char *mname, char *msg);
|
int local_specified, char *mname, char *msg));
|
||||||
#else
|
|
||||||
static int patch_proc ();
|
|
||||||
static int patch_fileproc ();
|
|
||||||
static Dtype patch_dirproc ();
|
|
||||||
static SIGTYPE patch_cleanup ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static int force_tag_match = 1;
|
static int force_tag_match = 1;
|
||||||
static int patch_short = 0;
|
static int patch_short = 0;
|
||||||
@ -77,7 +70,7 @@ patch (argc, argv)
|
|||||||
usage (patch_usage);
|
usage (patch_usage);
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "V:k:cuftsQqlRD:r:")) != -1)
|
while ((c = getopt (argc, argv, "V:k:cuftsQqlRD:r:")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -218,7 +211,7 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
|
|||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
|
||||||
/* if the portion of the module is a path, put the dir part on repos */
|
/* 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';
|
*cp = '\0';
|
||||||
(void) strcat (repository, "/");
|
(void) strcat (repository, "/");
|
||||||
@ -264,7 +257,7 @@ patch_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
|
|||||||
/* start the recursion processor */
|
/* start the recursion processor */
|
||||||
err = start_recursion (patch_fileproc, (int (*) ()) NULL, patch_dirproc,
|
err = start_recursion (patch_fileproc, (int (*) ()) NULL, patch_dirproc,
|
||||||
(int (*) ()) NULL, *pargc - 1, argv + 1, local,
|
(int (*) ()) NULL, *pargc - 1, argv + 1, local,
|
||||||
which, 0, 1, where, 1);
|
which, 0, 1, where, 1, 1);
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
@ -282,6 +275,7 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
List *entries;
|
List *entries;
|
||||||
List *srcfiles;
|
List *srcfiles;
|
||||||
{
|
{
|
||||||
|
struct utimbuf t;
|
||||||
char *vers_tag, *vers_head;
|
char *vers_tag, *vers_head;
|
||||||
char rcsspace[PATH_MAX];
|
char rcsspace[PATH_MAX];
|
||||||
char *rcs = rcsspace;
|
char *rcs = rcsspace;
|
||||||
@ -296,7 +290,6 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
char *cp1, *cp2, *commap;
|
char *cp1, *cp2, *commap;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
|
|
||||||
/* find the parsed rcs file */
|
/* find the parsed rcs file */
|
||||||
p = findnode (srcfiles, file);
|
p = findnode (srcfiles, file);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
@ -374,6 +367,10 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
memset ((char *) &t, 0, sizeof (t));
|
||||||
|
if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_tag,
|
||||||
|
(char *) 0, 0)) != -1)
|
||||||
|
(void) utime (tmpfile1, &t);
|
||||||
}
|
}
|
||||||
else if (toptwo_diffs)
|
else if (toptwo_diffs)
|
||||||
{
|
{
|
||||||
@ -392,6 +389,9 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
ret = 1;
|
ret = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if ((t.actime = t.modtime = RCS_getrevtime (rcsfile, vers_head,
|
||||||
|
(char *) 0, 0)) != -1)
|
||||||
|
(void) utime (tmpfile2, &t);
|
||||||
}
|
}
|
||||||
run_setup ("%s -%c", DIFF, unidiff ? 'u' : 'c');
|
run_setup ("%s -%c", DIFF, unidiff ? 'u' : 'c');
|
||||||
run_arg (tmpfile1);
|
run_arg (tmpfile1);
|
||||||
@ -409,6 +409,15 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
* lines of the diff output file, and munge them to include more
|
* lines of the diff output file, and munge them to include more
|
||||||
* reasonable file names that "patch" will understand.
|
* reasonable file names that "patch" will understand.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Output an "Index:" line for patch to use */
|
||||||
|
(void) fflush (stdout);
|
||||||
|
if (update_dir[0])
|
||||||
|
(void) printf ("Index: %s/%s\n", update_dir, file);
|
||||||
|
else
|
||||||
|
(void) printf ("Index: %s\n", file);
|
||||||
|
(void) fflush (stdout);
|
||||||
|
|
||||||
fp = open_file (tmpfile3, "r");
|
fp = open_file (tmpfile3, "r");
|
||||||
if (fgets (line1, sizeof (line1), fp) == NULL ||
|
if (fgets (line1, sizeof (line1), fp) == NULL ||
|
||||||
fgets (line2, sizeof (line2), fp) == NULL)
|
fgets (line2, sizeof (line2), fp) == NULL)
|
||||||
@ -423,8 +432,8 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
{
|
{
|
||||||
if (strncmp (line1, "*** ", 4) != 0 ||
|
if (strncmp (line1, "*** ", 4) != 0 ||
|
||||||
strncmp (line2, "--- ", 4) != 0 ||
|
strncmp (line2, "--- ", 4) != 0 ||
|
||||||
(cp1 = index (line1, '\t')) == NULL ||
|
(cp1 = strchr (line1, '\t')) == NULL ||
|
||||||
(cp2 = index (line2, '\t')) == NULL)
|
(cp2 = strchr (line2, '\t')) == NULL)
|
||||||
{
|
{
|
||||||
error (0, 0, "invalid diff header for %s", rcs);
|
error (0, 0, "invalid diff header for %s", rcs);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -436,8 +445,8 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
{
|
{
|
||||||
if (strncmp (line1, "--- ", 4) != 0 ||
|
if (strncmp (line1, "--- ", 4) != 0 ||
|
||||||
strncmp (line2, "+++ ", 4) != 0 ||
|
strncmp (line2, "+++ ", 4) != 0 ||
|
||||||
(cp1 = index (line1, '\t')) == NULL ||
|
(cp1 = strchr (line1, '\t')) == NULL ||
|
||||||
(cp2 = index (line2, '\t')) == NULL)
|
(cp2 = strchr (line2, '\t')) == NULL)
|
||||||
{
|
{
|
||||||
error (0, 0, "invalid unidiff header for %s", rcs);
|
error (0, 0, "invalid unidiff header for %s", rcs);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
@ -451,7 +460,7 @@ patch_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
(void) strcpy (strippath, REPOS_STRIP);
|
(void) strcpy (strippath, REPOS_STRIP);
|
||||||
if (strncmp (rcs, strippath, strlen (strippath)) == 0)
|
if (strncmp (rcs, strippath, strlen (strippath)) == 0)
|
||||||
rcs += strlen (strippath);
|
rcs += strlen (strippath);
|
||||||
commap = rindex (rcs, ',');
|
commap = strrchr (rcs, ',');
|
||||||
*commap = '\0';
|
*commap = '\0';
|
||||||
if (vers_tag != NULL)
|
if (vers_tag != NULL)
|
||||||
{
|
{
|
||||||
@ -511,7 +520,7 @@ patch_dirproc (dir, repos, update_dir)
|
|||||||
/*
|
/*
|
||||||
* Clean up temporary files
|
* Clean up temporary files
|
||||||
*/
|
*/
|
||||||
static SIGTYPE
|
static RETSIGTYPE
|
||||||
patch_cleanup ()
|
patch_cleanup ()
|
||||||
{
|
{
|
||||||
if (tmpfile1[0] != '\0')
|
if (tmpfile1[0] != '\0')
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* The routines contained in this file do all the rcs file parsing and
|
||||||
* manipulation
|
* manipulation
|
||||||
@ -11,36 +11,53 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, char *rcsfile));
|
||||||
static char *RCS_getbranch (RCSNode * rcs, char *tag, int force_tag_match);
|
static char *RCS_getdatebranch PROTO((RCSNode * rcs, char *date, char *branch));
|
||||||
static char *RCS_getdatebranch (RCSNode * rcs, char *date, char *branch);
|
static int getrcskey PROTO((FILE * fp, char **keyp, char **valp));
|
||||||
static int getrcskey (FILE * fp, char **keyp, char **valp);
|
static int parse_rcs_proc PROTO((Node * file, void *closure));
|
||||||
static int parse_rcs_proc (Node * file);
|
static int checkmagic_proc PROTO((Node *p, void *closure));
|
||||||
static int checkmagic_proc (Node *p);
|
static void do_branches PROTO((List * list, char *val));
|
||||||
static void do_branches (List * list, char *val);
|
static void do_symbols PROTO((List * list, char *val));
|
||||||
static void do_symbols (List * list, char *val);
|
static void null_delproc PROTO((Node * p));
|
||||||
static void null_delproc (Node * p);
|
static void rcsnode_delproc PROTO((Node * p));
|
||||||
static void rcsnode_delproc (Node * p);
|
static void rcsvers_delproc PROTO((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 List *rcslist;
|
static List *rcslist;
|
||||||
static char *repository;
|
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
|
* Parse all the rcs files specified and return a list
|
||||||
*/
|
*/
|
||||||
@ -54,7 +71,7 @@ RCS_parsefiles (files, xrepos)
|
|||||||
rcslist = getlist ();
|
rcslist = getlist ();
|
||||||
|
|
||||||
/* walk the list parsing files */
|
/* 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 */
|
/* free the list and return NULL on error */
|
||||||
dellist (&rcslist);
|
dellist (&rcslist);
|
||||||
@ -69,10 +86,10 @@ RCS_parsefiles (files, xrepos)
|
|||||||
* Parse an rcs file into a node on the rcs list
|
* Parse an rcs file into a node on the rcs list
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
parse_rcs_proc (file)
|
parse_rcs_proc (file, closure)
|
||||||
Node *file;
|
Node *file;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
Node *p;
|
|
||||||
RCSNode *rdata;
|
RCSNode *rdata;
|
||||||
|
|
||||||
/* parse the rcs file into 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 we got a valid RCSNode back, put it on the list */
|
||||||
if (rdata != (RCSNode *) NULL)
|
if (rdata != (RCSNode *) NULL)
|
||||||
{
|
RCS_addnode (file->key, rdata, rcslist);
|
||||||
p = getnode ();
|
|
||||||
p->key = xstrdup (file->key);
|
|
||||||
p->delproc = rcsnode_delproc;
|
|
||||||
p->type = RCSNODE;
|
|
||||||
p->data = (char *) rdata;
|
|
||||||
(void) addnode (rcslist, p);
|
|
||||||
}
|
|
||||||
return (0);
|
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
|
* Parse an rcsfile given a user file name and a repository
|
||||||
*/
|
*/
|
||||||
@ -100,43 +132,46 @@ RCS_parse (file, repos)
|
|||||||
char *repos;
|
char *repos;
|
||||||
{
|
{
|
||||||
RCSNode *rcs;
|
RCSNode *rcs;
|
||||||
|
FILE *fp;
|
||||||
char rcsfile[PATH_MAX];
|
char rcsfile[PATH_MAX];
|
||||||
|
|
||||||
(void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT);
|
(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,
|
rcs = RCS_parsercsfile_i(fp, rcsfile);
|
||||||
file, RCSEXT);
|
if (rcs != NULL)
|
||||||
if (!isreadable (rcsfile))
|
rcs->flags |= VALID;
|
||||||
return (NULL);
|
|
||||||
rcs = RCS_parsercsfile (rcsfile);
|
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)
|
if (rcs != NULL)
|
||||||
{
|
{
|
||||||
rcs->flags |= INATTIC;
|
rcs->flags |= INATTIC;
|
||||||
rcs->flags |= VALID;
|
rcs->flags |= VALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fclose (fp);
|
||||||
return (rcs);
|
return (rcs);
|
||||||
}
|
}
|
||||||
rcs = RCS_parsercsfile (rcsfile);
|
|
||||||
if (rcs != NULL)
|
return (NULL);
|
||||||
rcs->flags |= VALID;
|
|
||||||
return (rcs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do the real work of parsing an RCS file
|
* Parse a specific rcsfile.
|
||||||
*/
|
*/
|
||||||
RCSNode *
|
RCSNode *
|
||||||
RCS_parsercsfile (rcsfile)
|
RCS_parsercsfile (rcsfile)
|
||||||
char *rcsfile;
|
char *rcsfile;
|
||||||
{
|
{
|
||||||
Node *q, *r;
|
|
||||||
RCSNode *rdata;
|
|
||||||
RCSVers *vnode;
|
|
||||||
int n;
|
|
||||||
char *cp;
|
|
||||||
char *key, *value;
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
RCSNode *rcs;
|
||||||
|
|
||||||
/* open the rcsfile */
|
/* open the rcsfile */
|
||||||
if ((fp = fopen (rcsfile, "r")) == NULL)
|
if ((fp = fopen (rcsfile, "r")) == NULL)
|
||||||
@ -145,9 +180,30 @@ RCS_parsercsfile (rcsfile)
|
|||||||
return (NULL);
|
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 */
|
/* make a node */
|
||||||
rdata = (RCSNode *) xmalloc (sizeof (RCSNode));
|
rdata = (RCSNode *) xmalloc (sizeof (RCSNode));
|
||||||
bzero ((char *) rdata, sizeof (RCSNode));
|
memset ((char *) rdata, 0, sizeof (RCSNode));
|
||||||
rdata->refcount = 1;
|
rdata->refcount = 1;
|
||||||
rdata->path = xstrdup (rcsfile);
|
rdata->path = xstrdup (rcsfile);
|
||||||
rdata->versions = getlist ();
|
rdata->versions = getlist ();
|
||||||
@ -161,14 +217,24 @@ RCS_parsercsfile (rcsfile)
|
|||||||
{
|
{
|
||||||
/* get the next key/value pair */
|
/* 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 (getrcskey (fp, &key, &value) == -1 || key == NULL)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
error (0, 0, "`%s' does not appear to be a valid rcs file",
|
{
|
||||||
rcsfile);
|
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);
|
freercsnode (&rdata);
|
||||||
(void) fclose (fp);
|
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +250,7 @@ RCS_parsercsfile (rcsfile)
|
|||||||
if ((numdots (rdata->branch) & 1) != 0)
|
if ((numdots (rdata->branch) & 1) != 0)
|
||||||
{
|
{
|
||||||
/* turn it into a branch if it's a revision */
|
/* turn it into a branch if it's a revision */
|
||||||
cp = rindex (rdata->branch, '.');
|
cp = strrchr (rdata->branch, '.');
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -193,9 +259,7 @@ RCS_parsercsfile (rcsfile)
|
|||||||
{
|
{
|
||||||
if (value != NULL)
|
if (value != NULL)
|
||||||
{
|
{
|
||||||
/* if there are tags, set up the tag list */
|
rdata->symbols_data = xstrdup(value);
|
||||||
rdata->symbols = getlist ();
|
|
||||||
do_symbols (rdata->symbols, value);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -225,7 +289,7 @@ RCS_parsercsfile (rcsfile)
|
|||||||
|
|
||||||
/* grab the value of the date from value */
|
/* grab the value of the date from value */
|
||||||
valp = value + strlen (RCSDATE);/* skip the "date" keyword */
|
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++;
|
valp++;
|
||||||
(void) strcpy (date, valp);
|
(void) strcpy (date, valp);
|
||||||
|
|
||||||
@ -237,7 +301,7 @@ RCS_parsercsfile (rcsfile)
|
|||||||
q->delproc = rcsvers_delproc;
|
q->delproc = rcsvers_delproc;
|
||||||
r->delproc = null_delproc;
|
r->delproc = null_delproc;
|
||||||
q->data = r->data = xmalloc (sizeof (RCSVers));
|
q->data = r->data = xmalloc (sizeof (RCSVers));
|
||||||
bzero (q->data, sizeof (RCSVers));
|
memset (q->data, 0, sizeof (RCSVers));
|
||||||
vnode = (RCSVers *) q->data;
|
vnode = (RCSVers *) q->data;
|
||||||
|
|
||||||
/* fill in the version before we forget it */
|
/* fill in the version before we forget it */
|
||||||
@ -290,7 +354,6 @@ RCS_parsercsfile (rcsfile)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) fclose (fp);
|
|
||||||
return (rdata);
|
return (rdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,6 +388,8 @@ freercsnode (rnodep)
|
|||||||
dellist (&(*rnodep)->dates);
|
dellist (&(*rnodep)->dates);
|
||||||
if ((*rnodep)->symbols != (List *) NULL)
|
if ((*rnodep)->symbols != (List *) NULL)
|
||||||
dellist (&(*rnodep)->symbols);
|
dellist (&(*rnodep)->symbols);
|
||||||
|
if ((*rnodep)->symbols_data != (char *) NULL)
|
||||||
|
free ((*rnodep)->symbols_data);
|
||||||
if ((*rnodep)->head != (char *) NULL)
|
if ((*rnodep)->head != (char *) NULL)
|
||||||
free ((*rnodep)->head);
|
free ((*rnodep)->head);
|
||||||
if ((*rnodep)->branch != (char *) NULL)
|
if ((*rnodep)->branch != (char *) NULL)
|
||||||
@ -405,14 +470,14 @@ getrcskey (fp, keyp, valp)
|
|||||||
*valp = (char *) NULL;
|
*valp = (char *) NULL;
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
if (!isspace (c))
|
if (!whitespace (c))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fill in key */
|
/* fill in key */
|
||||||
cur = key;
|
cur = key;
|
||||||
max = key + keysize;
|
max = key + keysize;
|
||||||
while (!isspace (c) && c != ';')
|
while (!whitespace (c) && c != ';')
|
||||||
{
|
{
|
||||||
if (cur < max)
|
if (cur < max)
|
||||||
*cur++ = c;
|
*cur++ = c;
|
||||||
@ -432,6 +497,14 @@ getrcskey (fp, keyp, valp)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (cur >= max)
|
||||||
|
{
|
||||||
|
key = xrealloc (key, keysize + ALLOCINCR);
|
||||||
|
cur = key + keysize;
|
||||||
|
keysize += ALLOCINCR;
|
||||||
|
max = key + keysize;
|
||||||
|
}
|
||||||
|
|
||||||
*cur = '\0';
|
*cur = '\0';
|
||||||
|
|
||||||
/* if we got "desc", we are done with the file */
|
/* 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 */
|
/* whitespace with white set means compress it out */
|
||||||
if (white && isspace (c))
|
if (white && whitespace (c))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (isspace (c))
|
if (whitespace (c))
|
||||||
{
|
{
|
||||||
/* make c a space and set white */
|
/* make c a space and set white */
|
||||||
white = 1;
|
white = 1;
|
||||||
@ -568,7 +641,16 @@ getrcskey (fp, keyp, valp)
|
|||||||
|
|
||||||
/* terminate the string */
|
/* terminate the string */
|
||||||
if (cur)
|
if (cur)
|
||||||
|
{
|
||||||
|
if (cur >= max)
|
||||||
|
{
|
||||||
|
value = xrealloc (value, valsize + ALLOCINCR);
|
||||||
|
cur = value + valsize;
|
||||||
|
valsize += ALLOCINCR;
|
||||||
|
max = value + valsize;
|
||||||
|
}
|
||||||
*cur = '\0';
|
*cur = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
/* if the string is empty, make it null */
|
/* if the string is empty, make it null */
|
||||||
if (value && *value != '\0')
|
if (value && *value != '\0')
|
||||||
@ -594,7 +676,7 @@ do_symbols (list, val)
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* skip leading whitespace */
|
/* skip leading whitespace */
|
||||||
while (isspace (*cp))
|
while (whitespace (*cp))
|
||||||
cp++;
|
cp++;
|
||||||
|
|
||||||
/* if we got to the end, we are done */
|
/* if we got to the end, we are done */
|
||||||
@ -603,10 +685,10 @@ do_symbols (list, val)
|
|||||||
|
|
||||||
/* split it up into tag and rev */
|
/* split it up into tag and rev */
|
||||||
tag = cp;
|
tag = cp;
|
||||||
cp = index (cp, ':');
|
cp = strchr (cp, ':');
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
rev = cp;
|
rev = cp;
|
||||||
while (!isspace (*cp) && *cp != '\0')
|
while (!whitespace (*cp) && *cp != '\0')
|
||||||
cp++;
|
cp++;
|
||||||
if (*cp != '\0')
|
if (*cp != '\0')
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
@ -634,7 +716,7 @@ do_branches (list, val)
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* skip leading whitespace */
|
/* skip leading whitespace */
|
||||||
while (isspace (*cp))
|
while (whitespace (*cp))
|
||||||
cp++;
|
cp++;
|
||||||
|
|
||||||
/* if we got to the end, we are done */
|
/* if we got to the end, we are done */
|
||||||
@ -643,7 +725,7 @@ do_branches (list, val)
|
|||||||
|
|
||||||
/* find the end of this branch */
|
/* find the end of this branch */
|
||||||
branch = cp;
|
branch = cp;
|
||||||
while (!isspace (*cp) && *cp != '\0')
|
while (!whitespace (*cp) && *cp != '\0')
|
||||||
cp++;
|
cp++;
|
||||||
if (*cp != '\0')
|
if (*cp != '\0')
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
@ -686,7 +768,7 @@ RCS_getversion (rcs, tag, date, force_tag_match)
|
|||||||
if (tagrev == NULL)
|
if (tagrev == NULL)
|
||||||
return ((char *) NULL);
|
return ((char *) NULL);
|
||||||
|
|
||||||
if ((cp = rindex (tagrev, '.')) != NULL)
|
if ((cp = strrchr (tagrev, '.')) != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
rev = RCS_getdatebranch (rcs, date, tagrev);
|
rev = RCS_getdatebranch (rcs, date, tagrev);
|
||||||
free (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 we got a symbolic tag, resolve it to a numeric */
|
||||||
if (rcs == NULL)
|
if (rcs == NULL)
|
||||||
p = NULL;
|
p = NULL;
|
||||||
else
|
else {
|
||||||
p = findnode (rcs->symbols, tag);
|
p = findnode (RCS_symbols(rcs), tag);
|
||||||
|
}
|
||||||
if (p != NULL)
|
if (p != NULL)
|
||||||
{
|
{
|
||||||
int dots;
|
int dots;
|
||||||
@ -750,7 +833,7 @@ RCS_gettag (rcs, tag, force_tag_match)
|
|||||||
dots = numdots (tag);
|
dots = numdots (tag);
|
||||||
if (dots > 2 && (dots & 1) != 0)
|
if (dots > 2 && (dots & 1) != 0)
|
||||||
{
|
{
|
||||||
branch = rindex (tag, '.');
|
branch = strrchr (tag, '.');
|
||||||
cp = branch++ - 1;
|
cp = branch++ - 1;
|
||||||
while (*cp != '.')
|
while (*cp != '.')
|
||||||
cp--;
|
cp--;
|
||||||
@ -874,7 +957,7 @@ RCS_magicrev (rcs, rev)
|
|||||||
(void) sprintf (xrev, "%s.%d.%d", rev, RCS_MAGIC_BRANCH, rev_num);
|
(void) sprintf (xrev, "%s.%d.%d", rev, RCS_MAGIC_BRANCH, rev_num);
|
||||||
|
|
||||||
/* walk the symbols list to see if a magic one already exists */
|
/* 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;
|
continue;
|
||||||
|
|
||||||
/* we found a free magic branch. Claim it as ours */
|
/* 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.
|
* Returns 0 if the symbol does not match, 1 if it does.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
checkmagic_proc (p)
|
checkmagic_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
if (strcmp (check_rev, p->data) == 0)
|
if (strcmp (check_rev, p->data) == 0)
|
||||||
return (1);
|
return (1);
|
||||||
@ -897,9 +981,9 @@ checkmagic_proc (p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns non-zero if the specified revision number or symbolic tag
|
* Given a list of RCSNodes, returns non-zero if the specified
|
||||||
* resolves to a "branch" within the rcs file. We do take into account
|
* revision number or symbolic tag resolves to a "branch" within the
|
||||||
* any magic branches as well.
|
* rcs file.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
RCS_isbranch (file, rev, srcfiles)
|
RCS_isbranch (file, rev, srcfiles)
|
||||||
@ -907,7 +991,6 @@ RCS_isbranch (file, rev, srcfiles)
|
|||||||
char *rev;
|
char *rev;
|
||||||
List *srcfiles;
|
List *srcfiles;
|
||||||
{
|
{
|
||||||
int dots;
|
|
||||||
Node *p;
|
Node *p;
|
||||||
RCSNode *rcs;
|
RCSNode *rcs;
|
||||||
|
|
||||||
@ -922,7 +1005,27 @@ RCS_isbranch (file, rev, srcfiles)
|
|||||||
|
|
||||||
/* now, look for a match in the symbols list */
|
/* now, look for a match in the symbols list */
|
||||||
rcs = (RCSNode *) p->data;
|
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)
|
if (p == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
dots = numdots (p->data);
|
dots = numdots (p->data);
|
||||||
@ -933,7 +1036,7 @@ RCS_isbranch (file, rev, srcfiles)
|
|||||||
if (dots > 2)
|
if (dots > 2)
|
||||||
{
|
{
|
||||||
char *magic;
|
char *magic;
|
||||||
char *branch = rindex (p->data, '.');
|
char *branch = strrchr (p->data, '.');
|
||||||
char *cp = branch - 1;
|
char *cp = branch - 1;
|
||||||
while (*cp != '.')
|
while (*cp != '.')
|
||||||
cp--;
|
cp--;
|
||||||
@ -972,7 +1075,7 @@ RCS_whatbranch (file, rev, srcfiles)
|
|||||||
|
|
||||||
/* now, look for a match in the symbols list */
|
/* now, look for a match in the symbols list */
|
||||||
rcs = (RCSNode *) p->data;
|
rcs = (RCSNode *) p->data;
|
||||||
p = findnode (rcs->symbols, rev);
|
p = findnode (RCS_symbols(rcs), rev);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
return ((char *) NULL);
|
return ((char *) NULL);
|
||||||
dots = numdots (p->data);
|
dots = numdots (p->data);
|
||||||
@ -983,7 +1086,7 @@ RCS_whatbranch (file, rev, srcfiles)
|
|||||||
if (dots > 2)
|
if (dots > 2)
|
||||||
{
|
{
|
||||||
char *magic;
|
char *magic;
|
||||||
char *branch = rindex (p->data, '.');
|
char *branch = strrchr (p->data, '.');
|
||||||
char *cp = branch++ - 1;
|
char *cp = branch++ - 1;
|
||||||
while (*cp != '.')
|
while (*cp != '.')
|
||||||
cp--;
|
cp--;
|
||||||
@ -1008,7 +1111,7 @@ RCS_whatbranch (file, rev, srcfiles)
|
|||||||
* Get the head of the specified branch. If the branch does not exist,
|
* Get the head of the specified branch. If the branch does not exist,
|
||||||
* return NULL or RCS_head depending on force_tag_match
|
* return NULL or RCS_head depending on force_tag_match
|
||||||
*/
|
*/
|
||||||
static char *
|
char *
|
||||||
RCS_getbranch (rcs, tag, force_tag_match)
|
RCS_getbranch (rcs, tag, force_tag_match)
|
||||||
RCSNode *rcs;
|
RCSNode *rcs;
|
||||||
char *tag;
|
char *tag;
|
||||||
@ -1025,7 +1128,7 @@ RCS_getbranch (rcs, tag, force_tag_match)
|
|||||||
return ((char *) NULL);
|
return ((char *) NULL);
|
||||||
|
|
||||||
/* find out if the tag contains a dot, or is on the trunk */
|
/* 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 */
|
/* trunk processing is the special case */
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
@ -1237,7 +1340,7 @@ RCS_getdatebranch (rcs, date, branch)
|
|||||||
|
|
||||||
/* look up the first revision on the branch */
|
/* look up the first revision on the branch */
|
||||||
xrev = xstrdup (branch);
|
xrev = xstrdup (branch);
|
||||||
cp = rindex (xrev, '.');
|
cp = strrchr (xrev, '.');
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
{
|
{
|
||||||
free (xrev);
|
free (xrev);
|
||||||
@ -1374,6 +1477,20 @@ RCS_getrevtime (rcs, rev, date, fudge)
|
|||||||
return (revdate);
|
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
|
* 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
|
* command line. This function returns malloc'ed space that can be used
|
||||||
@ -1439,7 +1556,7 @@ RCS_check_tag (tag)
|
|||||||
if (!isgraph (*cp))
|
if (!isgraph (*cp))
|
||||||
error (1, 0, "tag `%s' has non-visible graphic characters",
|
error (1, 0, "tag `%s' has non-visible graphic characters",
|
||||||
tag);
|
tag);
|
||||||
if (index (invalid, *cp))
|
if (strchr (invalid, *cp))
|
||||||
error (1, 0, "tag `%s' must not contain the characters `%s'",
|
error (1, 0, "tag `%s' must not contain the characters `%s'",
|
||||||
tag, invalid);
|
tag, invalid);
|
||||||
}
|
}
|
||||||
@ -1447,3 +1564,4 @@ RCS_check_tag (tag)
|
|||||||
else
|
else
|
||||||
error (1, 0, "tag `%s' must start with a letter", tag);
|
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) 1992, Brian Berliner and Jeff Polk
|
||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* RCS source control definitions needed by rcs.c and friends
|
||||||
*/
|
*/
|
||||||
@ -19,6 +19,7 @@
|
|||||||
#define RCS_RCSMERGE "rcsmerge"
|
#define RCS_RCSMERGE "rcsmerge"
|
||||||
#define RCS_MERGE_PAT "^>>>>>>> " /* runs "grep" with this pattern */
|
#define RCS_MERGE_PAT "^>>>>>>> " /* runs "grep" with this pattern */
|
||||||
#define RCSEXT ",v"
|
#define RCSEXT ",v"
|
||||||
|
#define RCSPAT "*,v"
|
||||||
#define RCSHEAD "head"
|
#define RCSHEAD "head"
|
||||||
#define RCSBRANCH "branch"
|
#define RCSBRANCH "branch"
|
||||||
#define RCSSYMBOLS "symbols"
|
#define RCSSYMBOLS "symbols"
|
||||||
@ -39,6 +40,7 @@ struct rcsnode
|
|||||||
char *path;
|
char *path;
|
||||||
char *head;
|
char *head;
|
||||||
char *branch;
|
char *branch;
|
||||||
|
char *symbols_data;
|
||||||
List *symbols;
|
List *symbols;
|
||||||
List *versions;
|
List *versions;
|
||||||
List *dates;
|
List *dates;
|
||||||
@ -66,37 +68,23 @@ typedef struct rcsversnode RCSVers;
|
|||||||
/*
|
/*
|
||||||
* exported interfaces
|
* exported interfaces
|
||||||
*/
|
*/
|
||||||
#if __STDC__
|
List *RCS_parsefiles PROTO((List * files, char *xrepos));
|
||||||
List *RCS_parsefiles (List * files, char *xrepos);
|
RCSNode *RCS_parse PROTO((char *file, char *repos));
|
||||||
RCSNode *RCS_parse (char *file, char *repos);
|
RCSNode *RCS_parsercsfile PROTO((char *rcsfile));
|
||||||
RCSNode *RCS_parsercsfile (char *rcsfile);
|
char *RCS_check_kflag PROTO((char *arg));
|
||||||
char *RCS_check_kflag (char *arg);
|
char *RCS_getdate PROTO((RCSNode * rcs, char *date, int force_tag_match));
|
||||||
char *RCS_getdate (RCSNode * rcs, char *date, int force_tag_match);
|
char *RCS_gettag PROTO((RCSNode * rcs, char *tag, int force_tag_match));
|
||||||
char *RCS_gettag (RCSNode * rcs, char *tag, int force_tag_match);
|
char *RCS_getversion PROTO((RCSNode * rcs, char *tag, char *date,
|
||||||
char *RCS_getversion (RCSNode * rcs, char *tag, char *date,
|
int force_tag_match));
|
||||||
int force_tag_match);
|
char *RCS_magicrev PROTO((RCSNode *rcs, char *rev));
|
||||||
char *RCS_magicrev (RCSNode *rcs, char *rev);
|
int RCS_isbranch PROTO((char *file, char *rev, List *srcfiles));
|
||||||
int RCS_isbranch (char *file, char *rev, List *srcfiles);
|
int RCS_nodeisbranch PROTO((char *rev, RCSNode *rcs));
|
||||||
char *RCS_whatbranch (char *file, char *tag, List *srcfiles);
|
char *RCS_whatbranch PROTO((char *file, char *tag, List *srcfiles));
|
||||||
char *RCS_head (RCSNode * rcs);
|
char *RCS_head PROTO((RCSNode * rcs));
|
||||||
int RCS_datecmp (char *date1, char *date2);
|
int RCS_datecmp PROTO((char *date1, char *date2));
|
||||||
time_t RCS_getrevtime (RCSNode * rcs, char *rev, char *date, int fudge);
|
time_t RCS_getrevtime PROTO((RCSNode * rcs, char *rev, char *date, int fudge));
|
||||||
void RCS_check_tag (char *tag);
|
List *RCS_symbols PROTO((RCSNode *rcs));
|
||||||
void freercsnode (RCSNode ** rnodep);
|
void RCS_check_tag PROTO((char *tag));
|
||||||
#else
|
void freercsnode PROTO((RCSNode ** rnodep));
|
||||||
List *RCS_parsefiles ();
|
void RCS_addnode PROTO((char *file, RCSNode *rcs, List *list));
|
||||||
RCSNode *RCS_parse ();
|
char *RCS_getbranch PROTO((RCSNode * rcs, char *tag, int force_tag_match));
|
||||||
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__ */
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* General recursion handler
|
||||||
*
|
*
|
||||||
@ -11,18 +11,15 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static int do_dir_proc PROTO((Node * p, void *closure));
|
||||||
static int do_dir_proc (Node * p);
|
static int do_file_proc PROTO((Node * p, void *closure));
|
||||||
static int do_file_proc (Node * p);
|
static void addlist PROTO((List ** listp, char *key));
|
||||||
static void addlist (List ** listp, char *key);
|
static int unroll_files_proc PROTO((Node *p, void *closure));
|
||||||
#else
|
static void addfile PROTO((List **listp, char *dir, char *file));
|
||||||
static int do_file_proc ();
|
|
||||||
static int do_dir_proc ();
|
|
||||||
static void addlist ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -41,17 +38,35 @@ static char update_dir[PATH_MAX];
|
|||||||
static char *repository = NULL;
|
static char *repository = NULL;
|
||||||
static List *entries = NULL;
|
static List *entries = NULL;
|
||||||
static List *srcfiles = 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
|
* Called to start a recursive command.
|
||||||
* if present, otherwise the local directory is processed.
|
*
|
||||||
|
* 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
|
int
|
||||||
start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
||||||
argc, argv, local, which, aflag, readlock,
|
argc, argv, local, which, aflag, readlock,
|
||||||
update_preload, dosrcs)
|
update_preload, dosrcs, wd_is_repos)
|
||||||
int (*fileproc) ();
|
int (*fileproc) ();
|
||||||
int (*filesdoneproc) ();
|
int (*filesdoneproc) ();
|
||||||
Dtype (*direntproc) ();
|
Dtype (*direntproc) ();
|
||||||
@ -64,9 +79,12 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
|||||||
int readlock;
|
int readlock;
|
||||||
char *update_preload;
|
char *update_preload;
|
||||||
int dosrcs;
|
int dosrcs;
|
||||||
|
int wd_is_repos; /* Set if caller has already cd'd to the repository */
|
||||||
{
|
{
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
Dtype flags;
|
Dtype flags;
|
||||||
|
List *files_by_dir = NULL;
|
||||||
|
struct recursion_frame frame;
|
||||||
|
|
||||||
if (update_preload == NULL)
|
if (update_preload == NULL)
|
||||||
update_dir[0] = '\0';
|
update_dir[0] = '\0';
|
||||||
@ -89,7 +107,8 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
|||||||
if (srcfiles)
|
if (srcfiles)
|
||||||
dellist (&srcfiles);
|
dellist (&srcfiles);
|
||||||
if (filelist)
|
if (filelist)
|
||||||
dellist (&filelist);
|
dellist (&filelist); /* FIXME-krp: no longer correct. */
|
||||||
|
/* FIXME-krp: clean up files_by_dir */
|
||||||
if (dirlist)
|
if (dirlist)
|
||||||
dellist (&dirlist);
|
dellist (&dirlist);
|
||||||
|
|
||||||
@ -111,139 +130,128 @@ start_recursion (fileproc, filesdoneproc, direntproc, dirleaveproc,
|
|||||||
err += do_recursion (fileproc, filesdoneproc, direntproc,
|
err += do_recursion (fileproc, filesdoneproc, direntproc,
|
||||||
dirleaveproc, flags, which, aflag,
|
dirleaveproc, flags, which, aflag,
|
||||||
readlock, dosrcs);
|
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.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++)
|
||||||
{
|
{
|
||||||
|
/* if this argument is a directory, then add it to the list of
|
||||||
|
directories. */
|
||||||
|
|
||||||
/*
|
if (isdir(argv[i]))
|
||||||
* There were arguments, so we have to handle them by hand. To do
|
addlist (&dirlist, argv[i]);
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* look for args with /-s in them */
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
if (index (argv[i], '/') != NULL)
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* 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
|
|
||||||
{
|
|
||||||
if (isdir (CVSADM) || isdir (OCVSADM))
|
|
||||||
{
|
|
||||||
char *repos;
|
|
||||||
char tmp[PATH_MAX];
|
|
||||||
|
|
||||||
repos = Name_Repository ((char *) NULL, update_dir);
|
|
||||||
(void) sprintf (tmp, "%s/%s", repos, argv[i]);
|
|
||||||
if (isdir (tmp))
|
|
||||||
addlist (&dirlist, argv[i]);
|
|
||||||
else
|
|
||||||
addlist (&filelist, argv[i]);
|
|
||||||
free (repos);
|
|
||||||
}
|
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
char *cp;
|
/* otherwise, split argument into directory and component names. */
|
||||||
char *dir = (char *) NULL;
|
char *dir;
|
||||||
char *comp = (char *) NULL;
|
char *comp;
|
||||||
char *oldupdate = (char *) NULL;
|
char tmp[PATH_MAX];
|
||||||
char savewd[PATH_MAX];
|
char *file_to_try;
|
||||||
|
|
||||||
if (getwd (savewd) == NULL)
|
dir = xstrdup (argv[i]);
|
||||||
error (1, 0, "could not get working directory: %s", savewd);
|
if ((comp = strrchr (dir, '/')) == NULL)
|
||||||
|
|
||||||
for (i = 0; i < argc; i++)
|
|
||||||
{
|
{
|
||||||
/* split the arg into the dir and component parts */
|
/* no dir component. What we have is an implied "./" */
|
||||||
dir = xstrdup (argv[i]);
|
comp = dir;
|
||||||
if ((cp = rindex (dir, '/')) != NULL)
|
dir = xstrdup(".");
|
||||||
{
|
|
||||||
*cp = '\0';
|
|
||||||
comp = xstrdup (cp + 1);
|
|
||||||
oldupdate = xstrdup (update_dir);
|
|
||||||
if (update_dir[0] != '\0')
|
|
||||||
(void) strcat (update_dir, "/");
|
|
||||||
(void) strcat (update_dir, dir);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
comp = xstrdup (dir);
|
|
||||||
if (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)
|
else
|
||||||
free (dir);
|
{
|
||||||
if (comp)
|
char *p = comp;
|
||||||
free (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;
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
addfile (&files_by_dir, dir, comp);
|
||||||
|
|
||||||
|
(void) sprintf (update_dir, "%s", save_update_dir);
|
||||||
|
free (save_update_dir);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
addfile (&files_by_dir, dir, comp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
error (1, 0, "no such directory `%s'", dir);
|
||||||
|
|
||||||
|
free (dir);
|
||||||
|
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);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +368,7 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
|
|||||||
srcfiles = (List *) NULL;
|
srcfiles = (List *) NULL;
|
||||||
|
|
||||||
/* process the files */
|
/* process the files */
|
||||||
err += walklist (filelist, do_file_proc);
|
err += walklist (filelist, do_file_proc, NULL);
|
||||||
|
|
||||||
/* unlock it */
|
/* unlock it */
|
||||||
if (readlock)
|
if (readlock)
|
||||||
@ -378,7 +386,7 @@ do_recursion (xfileproc, xfilesdoneproc, xdirentproc, xdirleaveproc,
|
|||||||
|
|
||||||
/* process the directories (if necessary) */
|
/* process the directories (if necessary) */
|
||||||
if (dirlist != NULL)
|
if (dirlist != NULL)
|
||||||
err += walklist (dirlist, do_dir_proc);
|
err += walklist (dirlist, do_dir_proc, NULL);
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
else if (dirleaveproc != NULL)
|
else if (dirleaveproc != NULL)
|
||||||
err += dirleaveproc(".", err, ".");
|
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
|
* Process each of the files in the list with the callback proc
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
do_file_proc (p)
|
do_file_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
if (fileproc != NULL)
|
if (fileproc != NULL)
|
||||||
return (fileproc (p->key, update_dir, repository, entries, srcfiles));
|
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)
|
* Process each of the directories in the list (recursing as we go)
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
do_dir_proc (p)
|
do_dir_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
char *dir = p->key;
|
char *dir = p->key;
|
||||||
char savewd[PATH_MAX];
|
char savewd[PATH_MAX];
|
||||||
@ -508,7 +518,7 @@ do_dir_proc (p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* put back update_dir */
|
/* put back update_dir */
|
||||||
if ((cp = rindex (update_dir, '/')) != NULL)
|
if ((cp = strrchr (update_dir, '/')) != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
else
|
else
|
||||||
update_dir[0] = '\0';
|
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
|
static void
|
||||||
addlist (listp, key)
|
addlist (listp, key)
|
||||||
@ -531,5 +541,87 @@ addlist (listp, key)
|
|||||||
p = getnode ();
|
p = getnode ();
|
||||||
p->type = FILES;
|
p->type = FILES;
|
||||||
p->key = xstrdup (key);
|
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);
|
||||||
}
|
}
|
||||||
|
@ -12,14 +12,11 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)release.c 1.21 92/02/29";
|
static char rcsid[] = "$CVSid: @(#)release.c 1.23 94/09/21 $";
|
||||||
|
USE(rcsid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static void release_delete PROTO((char *dir));
|
||||||
static void release_delete (char *dir);
|
|
||||||
#else
|
|
||||||
static void release_delete ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char *release_usage[] =
|
static char *release_usage[] =
|
||||||
{
|
{
|
||||||
@ -49,7 +46,7 @@ release (argc, argv)
|
|||||||
if (argc == -1)
|
if (argc == -1)
|
||||||
usage (release_usage);
|
usage (release_usage);
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "Qdq")) != -1)
|
while ((c = getopt (argc, argv, "Qdq")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -116,7 +113,7 @@ release (argc, argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
val.dptr[val.dsize] = '\0';
|
val.dptr[val.dsize] = '\0';
|
||||||
if ((cp = index (val.dptr, '#')) != NULL) /* Strip out a comment */
|
if ((cp = strchr (val.dptr, '#')) != NULL) /* Strip out a comment */
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -128,7 +125,7 @@ release (argc, argv)
|
|||||||
margv = modargv;
|
margv = modargv;
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while (gnu_getopt (margc, margv, CVSMODULE_OPTS) != -1)
|
while (getopt (margc, margv, CVSMODULE_OPTS) != -1)
|
||||||
/* do nothing */ ;
|
/* do nothing */ ;
|
||||||
margc -= optind;
|
margc -= optind;
|
||||||
margv += optind;
|
margv += optind;
|
||||||
@ -159,7 +156,7 @@ release (argc, argv)
|
|||||||
c = 0;
|
c = 0;
|
||||||
while (fgets (line, sizeof (line), fp))
|
while (fgets (line, sizeof (line), fp))
|
||||||
{
|
{
|
||||||
if (index ("MARCZ", *line))
|
if (strchr ("MARCZ", *line))
|
||||||
c++;
|
c++;
|
||||||
(void) printf (line);
|
(void) printf (line);
|
||||||
}
|
}
|
||||||
@ -211,7 +208,11 @@ release_delete (dir)
|
|||||||
"Parent dir on a different disk, delete of %s aborted", dir);
|
"Parent dir on a different disk, delete of %s aborted", dir);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
run_setup ("%s -r", RM);
|
/*
|
||||||
|
* XXX - shouldn't this just delete the CVS-controlled files and, perhaps,
|
||||||
|
* the files that would normally be ignored and leave everything else?
|
||||||
|
*/
|
||||||
|
run_setup ("%s -fr", RM);
|
||||||
run_arg (dir);
|
run_arg (dir);
|
||||||
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
|
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
|
||||||
error (0, retcode == -1 ? errno : 0,
|
error (0, retcode == -1 ? errno : 0,
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Remove a File
|
||||||
*
|
*
|
||||||
@ -18,26 +18,24 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static int remove_fileproc PROTO((char *file, char *update_dir,
|
||||||
static int remove_fileproc (char *file, char *update_dir,
|
|
||||||
char *repository, List *entries,
|
char *repository, List *entries,
|
||||||
List *srcfiles);
|
List *srcfiles));
|
||||||
static Dtype remove_dirproc (char *dir, char *repos, char *update_dir);
|
static Dtype remove_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||||
#else
|
|
||||||
static Dtype remove_dirproc ();
|
|
||||||
static int remove_fileproc ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
static int force;
|
||||||
static int local;
|
static int local;
|
||||||
static int removed_files;
|
static int removed_files;
|
||||||
static int auto_removed_files;
|
static int existing_files;
|
||||||
|
|
||||||
static char *remove_usage[] =
|
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-l\tProcess this directory only (not recursive).\n",
|
||||||
"\t-R\tProcess directories recursively.\n",
|
"\t-R\tProcess directories recursively.\n",
|
||||||
NULL
|
NULL
|
||||||
@ -54,10 +52,13 @@ cvsremove (argc, argv)
|
|||||||
usage (remove_usage);
|
usage (remove_usage);
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "lR")) != -1)
|
while ((c = getopt (argc, argv, "flR")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
|
case 'f':
|
||||||
|
force = 1;
|
||||||
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
local = 1;
|
local = 1;
|
||||||
break;
|
break;
|
||||||
@ -76,15 +77,18 @@ cvsremove (argc, argv)
|
|||||||
/* start the recursion processor */
|
/* start the recursion processor */
|
||||||
err = start_recursion (remove_fileproc, (int (*) ()) NULL, remove_dirproc,
|
err = start_recursion (remove_fileproc, (int (*) ()) NULL, remove_dirproc,
|
||||||
(int (*) ()) NULL, argc, argv, local,
|
(int (*) ()) NULL, argc, argv, local,
|
||||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
W_LOCAL, 0, 1, (char *) NULL, 1, 0);
|
||||||
|
|
||||||
if (removed_files)
|
if (removed_files)
|
||||||
error (0, 0, "use '%s commit' to remove %s permanently", program_name,
|
error (0, 0, "use '%s commit' to remove %s permanently", program_name,
|
||||||
(removed_files == 1) ? "this file" : "these files");
|
(removed_files == 1) ? "this file" : "these files");
|
||||||
else
|
|
||||||
if (!auto_removed_files)
|
if (existing_files)
|
||||||
error (0, 0, "no files removed; use `%s' to remove the file first",
|
error (0, 0,
|
||||||
RM);
|
((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);
|
return (err);
|
||||||
}
|
}
|
||||||
@ -104,24 +108,28 @@ remove_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
char fname[PATH_MAX];
|
char fname[PATH_MAX];
|
||||||
Vers_TS *vers;
|
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,
|
vers = Version_TS (repository, (char *) NULL, (char *) NULL, (char *) NULL,
|
||||||
file, 0, 0, entries, srcfiles);
|
file, 0, 0, entries, srcfiles);
|
||||||
|
|
||||||
if (vers->ts_user != NULL)
|
if (vers->ts_user != NULL)
|
||||||
{
|
{
|
||||||
freevers_ts (&vers);
|
existing_files++;
|
||||||
return (0);
|
if (!quiet)
|
||||||
|
error (0, 0, "file `%s' still in working directory", file);
|
||||||
}
|
}
|
||||||
|
else if (vers->vn_user == NULL)
|
||||||
if (vers->vn_user == NULL)
|
|
||||||
{
|
{
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
error (0, 0, "nothing known about %s", file);
|
error (0, 0, "nothing known about `%s'", file);
|
||||||
freevers_ts (&vers);
|
|
||||||
return (0);
|
|
||||||
}
|
}
|
||||||
|
else if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
|
||||||
if (vers->vn_user[0] == '0' && vers->vn_user[1] == '\0')
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* It's a file that has been added, but not commited yet. So,
|
* 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) sprintf (fname, "%s/%s%s", CVSADM, file, CVSEXT_LOG);
|
||||||
(void) unlink_file (fname);
|
(void) unlink_file (fname);
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
error (0, 0, "removed `%s'.", file);
|
error (0, 0, "removed `%s'", file);
|
||||||
auto_removed_files++;
|
|
||||||
}
|
}
|
||||||
else if (vers->vn_user[0] == '-')
|
else if (vers->vn_user[0] == '-')
|
||||||
{
|
{
|
||||||
freevers_ts (&vers);
|
if (!quiet)
|
||||||
return (0);
|
error (0, 0, "file `%s' already scheduled for removal", file);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -148,12 +155,10 @@ remove_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
(void) strcpy (fname, "-");
|
(void) strcpy (fname, "-");
|
||||||
(void) strcat (fname, vers->vn_user);
|
(void) strcat (fname, vers->vn_user);
|
||||||
Register (entries, file, fname, vers->ts_rcs, vers->options,
|
Register (entries, file, fname, vers->ts_rcs, vers->options,
|
||||||
vers->tag, vers->date);
|
vers->tag, vers->date, vers->ts_conflict);
|
||||||
if (!quiet)
|
if (!quiet)
|
||||||
{
|
error (0, 0, "scheduling `%s' for removal", file);
|
||||||
error (0, 0, "scheduling %s for removal", file);
|
removed_files++;
|
||||||
removed_files++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Name of Repository
|
||||||
*
|
*
|
||||||
@ -13,7 +13,8 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
char *
|
char *
|
||||||
@ -112,7 +113,7 @@ Name_Repository (dir, update_dir)
|
|||||||
error (1, errno, "cannot read %s", CVSADM_REP);
|
error (1, errno, "cannot read %s", CVSADM_REP);
|
||||||
}
|
}
|
||||||
(void) fclose (fpin);
|
(void) fclose (fpin);
|
||||||
if ((cp = rindex (repos, '\n')) != NULL)
|
if ((cp = strrchr (repos, '\n')) != NULL)
|
||||||
*cp = '\0'; /* strip the newline */
|
*cp = '\0'; /* strip the newline */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Rtag
|
||||||
*
|
*
|
||||||
@ -14,24 +14,18 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static Dtype rtag_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||||
static Dtype rtag_dirproc (char *dir, char *repos, char *update_dir);
|
static int rtag_fileproc PROTO((char *file, char *update_dir,
|
||||||
static int rtag_fileproc (char *file, char *update_dir,
|
|
||||||
char *repository, List * entries,
|
char *repository, List * entries,
|
||||||
List * srcfiles);
|
List * srcfiles));
|
||||||
static int rtag_proc (int *pargc, char *argv[], char *xwhere,
|
static int rtag_proc PROTO((int *pargc, char *argv[], char *xwhere,
|
||||||
char *mwhere, char *mfile, int shorten,
|
char *mwhere, char *mfile, int shorten,
|
||||||
int local_specified, char *mname, char *msg);
|
int local_specified, char *mname, char *msg));
|
||||||
static int rtag_delete (RCSNode *rcsfile);
|
static int rtag_delete PROTO((RCSNode *rcsfile));
|
||||||
#else
|
|
||||||
static int rtag_proc ();
|
|
||||||
static int rtag_fileproc ();
|
|
||||||
static Dtype rtag_dirproc ();
|
|
||||||
static int rtag_delete ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char *symtag;
|
static char *symtag;
|
||||||
static char *numtag;
|
static char *numtag;
|
||||||
@ -41,10 +35,11 @@ static int branch_mode; /* make an automagic "branch" tag */
|
|||||||
static char *date;
|
static char *date;
|
||||||
static int local; /* recursive by default */
|
static int local; /* recursive by default */
|
||||||
static int force_tag_match = 1; /* force 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[] =
|
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-Q\tReally quiet.\n",
|
||||||
"\t-a\tClear tag from removed files that would not otherwise be tagged.\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",
|
"\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-d\tDelete the given Tag.\n",
|
||||||
"\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
|
"\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
|
||||||
"\t-[rD]\tExisting tag or Date.\n",
|
"\t-[rD]\tExisting tag or Date.\n",
|
||||||
|
"\t-F\tMove tag if it already exists\n",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -73,7 +69,7 @@ rtag (argc, argv)
|
|||||||
usage (rtag_usage);
|
usage (rtag_usage);
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "anfQqlRdbr:D:")) != -1)
|
while ((c = getopt (argc, argv, "FanfQqlRdbr:D:")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -112,6 +108,9 @@ rtag (argc, argv)
|
|||||||
free (date);
|
free (date);
|
||||||
date = Make_Date (optarg);
|
date = Make_Date (optarg);
|
||||||
break;
|
break;
|
||||||
|
case 'F':
|
||||||
|
force_tag_move = 1;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage (rtag_usage);
|
usage (rtag_usage);
|
||||||
@ -178,7 +177,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
|
|||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
|
||||||
/* if the portion of the module is a path, put the dir part on repos */
|
/* 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';
|
*cp = '\0';
|
||||||
(void) strcat (repository, "/");
|
(void) strcat (repository, "/");
|
||||||
@ -224,7 +223,7 @@ rtag_proc (pargc, argv, xwhere, mwhere, mfile, shorten, local_specified,
|
|||||||
/* start the recursion processor */
|
/* start the recursion processor */
|
||||||
err = start_recursion (rtag_fileproc, (int (*) ()) NULL, rtag_dirproc,
|
err = start_recursion (rtag_fileproc, (int (*) ()) NULL, rtag_dirproc,
|
||||||
(int (*) ()) NULL, *pargc - 1, argv + 1, local,
|
(int (*) ()) NULL, *pargc - 1, argv + 1, local,
|
||||||
which, 0, 1, where, 1);
|
which, 0, 1, where, 1, 1);
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
@ -304,40 +303,60 @@ rtag_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char *oversion;
|
char *oversion;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As an enhancement for the case where a tag is being re-applied to
|
||||||
|
* a large body of a module, make one extra call to Version_Number to
|
||||||
|
* see if the tag is already set in the RCS file. If so, check to
|
||||||
|
* see if it needs to be moved. If not, do nothing. This will
|
||||||
|
* likely save a lot of 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 (rcsfile, version) : version;
|
||||||
|
oversion = RCS_getversion (rcsfile, symtag, (char *) 0, 1);
|
||||||
|
if (oversion != NULL)
|
||||||
|
{
|
||||||
|
int isbranch = RCS_isbranch (file, symtag, srcfiles);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* As an enhancement for the case where a tag is being re-applied to
|
* if versions the same and neither old or new are branches don't
|
||||||
* a large body of a module, make one extra call to Version_Number to
|
* have to do anything
|
||||||
* see if the tag is already set in the RCS file. If so, check to
|
*/
|
||||||
* see if it needs to be moved. If not, do nothing. This will
|
if (strcmp (version, oversion) == 0 && !branch_mode && !isbranch)
|
||||||
* likely save a lot of time when simply moving the tag to the
|
{
|
||||||
* "current" head revisions of a module -- which I have found to be a
|
free (oversion);
|
||||||
* typical tagging operation.
|
free (version);
|
||||||
*/
|
return (0);
|
||||||
oversion = RCS_getversion (rcsfile, symtag, (char *) 0, 1);
|
}
|
||||||
if (oversion != NULL)
|
|
||||||
{
|
if (!force_tag_move) { /* we're NOT going to move the tag */
|
||||||
if (strcmp (version, oversion) == 0)
|
if (update_dir[0])
|
||||||
{
|
(void) printf ("W %s/%s", update_dir, file);
|
||||||
free (version);
|
else
|
||||||
free (oversion);
|
(void) printf ("W %s", file);
|
||||||
return (0);
|
|
||||||
}
|
(void) printf (" : %s already exists on %s %s",
|
||||||
free (oversion);
|
symtag, isbranch ? "branch" : "version", oversion);
|
||||||
}
|
(void) printf (" : NOT MOVING tag to %s %s\n",
|
||||||
rev = branch_mode ? RCS_magicrev (rcsfile, version) : version;
|
branch_mode ? "branch" : "version", rev);
|
||||||
run_setup ("%s%s -q -N%s:%s", Rcsbin, RCS, symtag, rev);
|
free (oversion);
|
||||||
|
free (version);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
free (oversion);
|
||||||
|
}
|
||||||
|
run_setup ("%s%s -q -N%s:%s", Rcsbin, RCS, symtag, rev);
|
||||||
}
|
}
|
||||||
run_arg (rcsfile->path);
|
run_arg (rcsfile->path);
|
||||||
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
|
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
|
||||||
{
|
{
|
||||||
if (!quiet)
|
error (1, retcode == -1 ? errno : 0,
|
||||||
error (0, retcode == -1 ? errno : 0,
|
"failed to set tag `%s' to revision `%s' in `%s'",
|
||||||
"failed to set tag `%s' to revision `%s' in `%s'",
|
symtag, rev, rcsfile->path);
|
||||||
symtag, rev, rcsfile->path);
|
free (version);
|
||||||
free (version);
|
return (1);
|
||||||
return (1);
|
|
||||||
}
|
}
|
||||||
free (version);
|
free (version);
|
||||||
return (0);
|
return (0);
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Status Information
|
||||||
*/
|
*/
|
||||||
@ -11,23 +11,20 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static Dtype status_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||||
static Dtype status_dirproc (char *dir, char *repos, char *update_dir);
|
static int status_fileproc PROTO((char *file, char *update_dir,
|
||||||
static int status_fileproc (char *file, char *update_dir,
|
|
||||||
char *repository, List * entries,
|
char *repository, List * entries,
|
||||||
List * srcfiles);
|
List * srcfiles));
|
||||||
static int tag_list_proc (Node * p);
|
static int tag_list_proc PROTO((Node * p, void *closure));
|
||||||
#else
|
|
||||||
static int tag_list_proc ();
|
|
||||||
static int status_fileproc ();
|
|
||||||
static Dtype status_dirproc ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static int local = 0;
|
static int local = 0;
|
||||||
static int long_format = 0;
|
static int long_format = 0;
|
||||||
|
static char *xfile;
|
||||||
|
static List *xsrcfiles;
|
||||||
|
|
||||||
static char *status_usage[] =
|
static char *status_usage[] =
|
||||||
{
|
{
|
||||||
@ -50,7 +47,7 @@ status (argc, argv)
|
|||||||
usage (status_usage);
|
usage (status_usage);
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "vlR")) != -1)
|
while ((c = getopt (argc, argv, "vlR")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -75,7 +72,7 @@ status (argc, argv)
|
|||||||
/* start the recursion processor */
|
/* start the recursion processor */
|
||||||
err = start_recursion (status_fileproc, (int (*) ()) NULL, status_dirproc,
|
err = start_recursion (status_fileproc, (int (*) ()) NULL, status_dirproc,
|
||||||
(int (*) ()) NULL, argc, argv, local,
|
(int (*) ()) NULL, argc, argv, local,
|
||||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
W_LOCAL, 0, 1, (char *) NULL, 1, 0);
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
@ -97,7 +94,8 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
Vers_TS *vers;
|
Vers_TS *vers;
|
||||||
|
|
||||||
status = Classify_File (file, (char *) NULL, (char *) NULL, (char *) NULL,
|
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)
|
switch (status)
|
||||||
{
|
{
|
||||||
case T_UNKNOWN:
|
case T_UNKNOWN:
|
||||||
@ -116,7 +114,10 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
sstat = "Locally Removed";
|
sstat = "Locally Removed";
|
||||||
break;
|
break;
|
||||||
case T_MODIFIED:
|
case T_MODIFIED:
|
||||||
sstat = "Locally Modified";
|
if (vers->ts_conflict)
|
||||||
|
sstat = "Unresolved Conflict";
|
||||||
|
else
|
||||||
|
sstat = "Locally Modified";
|
||||||
break;
|
break;
|
||||||
case T_REMOVE_ENTRY:
|
case T_REMOVE_ENTRY:
|
||||||
sstat = "Entry Invalid";
|
sstat = "Entry Invalid";
|
||||||
@ -136,20 +137,20 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
if (vers->ts_user == NULL)
|
if (vers->ts_user == NULL)
|
||||||
(void) printf ("File: no file %s\t\tStatus: %s\n\n", file, sstat);
|
(void) printf ("File: no file %s\t\tStatus: %s\n\n", file, sstat);
|
||||||
else
|
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)
|
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')
|
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
|
else
|
||||||
(void) printf (" Version:\t\t%s\t%s\n", vers->vn_user,
|
(void) printf (" Working revision:\t%s\t%s\n", vers->vn_user,
|
||||||
&vers->ts_rcs[25]);
|
vers->ts_rcs);
|
||||||
|
|
||||||
if (vers->vn_rcs == NULL)
|
if (vers->vn_rcs == NULL)
|
||||||
(void) printf (" RCS Version:\tNo revision control file\n");
|
(void) printf (" Repository revision:\tNo revision control file\n");
|
||||||
else
|
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);
|
vers->srcfile->path);
|
||||||
|
|
||||||
if (vers->entdata)
|
if (vers->entdata)
|
||||||
@ -161,36 +162,49 @@ status_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
{
|
{
|
||||||
if (vers->vn_rcs == NULL)
|
if (vers->vn_rcs == NULL)
|
||||||
(void) printf (
|
(void) printf (
|
||||||
" Sticky Tag:\t\t%s - MISSING from RCS file!\n",
|
" Sticky Tag:\t\t%s - MISSING from RCS file!\n",
|
||||||
edata->tag);
|
edata->tag);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (isdigit (edata->tag[0]))
|
if (isdigit (edata->tag[0]))
|
||||||
(void) printf (" Sticky Tag:\t\t%s\n", edata->tag);
|
(void) printf (" Sticky Tag:\t\t%s\n", edata->tag);
|
||||||
else
|
else
|
||||||
(void) printf (" Sticky Tag:\t\t%s (%s: %s)\n",
|
{
|
||||||
edata->tag, numdots (vers->vn_rcs) % 2 ?
|
int isbranch = RCS_isbranch (file, edata->tag, srcfiles);
|
||||||
"revision" : "branch", vers->vn_rcs);
|
|
||||||
|
(void) printf (" Sticky Tag:\t\t%s (%s: %s)\n",
|
||||||
|
edata->tag,
|
||||||
|
isbranch ? "branch" : "revision",
|
||||||
|
isbranch ?
|
||||||
|
RCS_whatbranch(file, edata->tag, srcfiles) :
|
||||||
|
vers->vn_rcs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
(void) printf (" Sticky Tag:\t\t(none)\n");
|
(void) printf (" Sticky Tag:\t\t(none)\n");
|
||||||
|
|
||||||
if (edata->date)
|
if (edata->date)
|
||||||
(void) printf (" Sticky Date:\t%s\n", edata->date);
|
(void) printf (" Sticky Date:\t\t%s\n", edata->date);
|
||||||
else
|
else
|
||||||
(void) printf (" Sticky Date:\t(none)\n");
|
(void) printf (" Sticky Date:\t\t(none)\n");
|
||||||
|
|
||||||
if (edata->options && edata->options[0])
|
if (edata->options && edata->options[0])
|
||||||
(void) printf (" Sticky Options:\t%s\n", edata->options);
|
(void) printf (" Sticky Options:\t%s\n", edata->options);
|
||||||
else
|
else
|
||||||
(void) printf (" Sticky Options:\t(none)\n");
|
(void) printf (" Sticky Options:\t(none)\n");
|
||||||
|
|
||||||
if (long_format && vers->srcfile)
|
if (long_format && vers->srcfile)
|
||||||
{
|
{
|
||||||
(void) printf ("\n Existing Tags:\n");
|
List *symbols = RCS_symbols(vers->srcfile);
|
||||||
if (vers->srcfile->symbols)
|
|
||||||
(void) walklist (vers->srcfile->symbols, tag_list_proc);
|
(void) printf ("\n Existing Tags:\n");
|
||||||
|
if (symbols)
|
||||||
|
{
|
||||||
|
xfile = file;
|
||||||
|
xsrcfiles = srcfiles;
|
||||||
|
(void) walklist (symbols, tag_list_proc, NULL);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
(void) printf ("\tNo Tags Exist\n");
|
(void) printf ("\tNo Tags Exist\n");
|
||||||
}
|
}
|
||||||
@ -220,11 +234,15 @@ status_dirproc (dir, repos, update_dir)
|
|||||||
* Print out a tag and its type
|
* Print out a tag and its type
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
tag_list_proc (p)
|
tag_list_proc (p, closure)
|
||||||
Node *p;
|
Node *p;
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
|
int isbranch = RCS_isbranch (xfile, p->key, xsrcfiles);
|
||||||
|
|
||||||
(void) printf ("\t%-25.25s\t(%s: %s)\n", p->key,
|
(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);
|
p->data);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* Tag
|
||||||
*
|
*
|
||||||
@ -14,33 +14,31 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static Dtype tag_dirproc PROTO((char *dir, char *repos, char *update_dir));
|
||||||
static Dtype tag_dirproc (char *dir, char *repos, char *update_dir);
|
static int tag_fileproc PROTO((char *file, char *update_dir,
|
||||||
static int tag_fileproc (char *file, char *update_dir,
|
|
||||||
char *repository, List * entries,
|
char *repository, List * entries,
|
||||||
List * srcfiles);
|
List * srcfiles));
|
||||||
#else
|
|
||||||
static int tag_fileproc ();
|
|
||||||
static Dtype tag_dirproc ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char *symtag;
|
static char *symtag;
|
||||||
static int delete; /* adding a tag by default */
|
static int delete; /* adding a tag by default */
|
||||||
static int branch_mode; /* make an automagic "branch" tag */
|
static int branch_mode; /* make an automagic "branch" tag */
|
||||||
static int local; /* recursive by default */
|
static int local; /* recursive by default */
|
||||||
|
static int force_tag_move; /* don't force tag to move by default */
|
||||||
|
|
||||||
static char *tag_usage[] =
|
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-Q\tReally quiet.\n",
|
||||||
"\t-l\tLocal directory only, not recursive.\n",
|
"\t-l\tLocal directory only, not recursive.\n",
|
||||||
"\t-R\tProcess directories recursively.\n",
|
"\t-R\tProcess directories recursively.\n",
|
||||||
"\t-q\tSomewhat quiet.\n",
|
"\t-q\tSomewhat quiet.\n",
|
||||||
"\t-d\tDelete the given Tag.\n",
|
"\t-d\tDelete the given Tag.\n",
|
||||||
"\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
|
"\t-b\tMake the tag a \"branch\" tag, allowing concurrent development.\n",
|
||||||
|
"\t-F\tMove tag if it already exists\n",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -56,7 +54,7 @@ tag (argc, argv)
|
|||||||
usage (tag_usage);
|
usage (tag_usage);
|
||||||
|
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "QqlRdb")) != -1)
|
while ((c = getopt (argc, argv, "FQqlRdb")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -78,6 +76,9 @@ tag (argc, argv)
|
|||||||
case 'b':
|
case 'b':
|
||||||
branch_mode = 1;
|
branch_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'F':
|
||||||
|
force_tag_move = 1;
|
||||||
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
default:
|
default:
|
||||||
usage (tag_usage);
|
usage (tag_usage);
|
||||||
@ -100,7 +101,7 @@ tag (argc, argv)
|
|||||||
/* start the recursion processor */
|
/* start the recursion processor */
|
||||||
err = start_recursion (tag_fileproc, (int (*) ()) NULL, tag_dirproc,
|
err = start_recursion (tag_fileproc, (int (*) ()) NULL, tag_dirproc,
|
||||||
(int (*) ()) NULL, argc, argv, local,
|
(int (*) ()) NULL, argc, argv, local,
|
||||||
W_LOCAL, 0, 1, (char *) NULL, 1);
|
W_LOCAL, 0, 1, (char *) NULL, 1, 0);
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,26 +211,47 @@ tag_fileproc (file, update_dir, repository, entries, srcfiles)
|
|||||||
* time when simply moving the tag to the "current" head revisions of a
|
* time when simply moving the tag to the "current" head revisions of a
|
||||||
* module -- which I have found to be a typical tagging operation.
|
* 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);
|
oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1);
|
||||||
if (oversion != NULL)
|
if (oversion != NULL)
|
||||||
{
|
{
|
||||||
if (strcmp (version, oversion) == 0)
|
int isbranch = RCS_isbranch (file, symtag, srcfiles);
|
||||||
{
|
|
||||||
free (oversion);
|
/*
|
||||||
freevers_ts (&vers);
|
* if versions the same and neither old or new are branches don't have
|
||||||
return (0);
|
* to do anything
|
||||||
}
|
*/
|
||||||
free (oversion);
|
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_setup ("%s%s -q -N%s:%s", Rcsbin, RCS, symtag, rev);
|
||||||
run_arg (vers->srcfile->path);
|
run_arg (vers->srcfile->path);
|
||||||
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
|
if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)) != 0)
|
||||||
{
|
{
|
||||||
if (!quiet)
|
error (1, retcode == -1 ? errno : 0,
|
||||||
error (0, retcode == -1 ? errno : 0,
|
"failed to set tag %s to revision %s in %s",
|
||||||
"failed to set tag %s to revision %s in %s",
|
symtag, rev, vers->srcfile->path);
|
||||||
symtag, rev, vers->srcfile->path);
|
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
||||||
*
|
*
|
||||||
* "update" updates the version in the present directory with respect to the RCS
|
* "update" updates the version in the present directory with respect to the RCS
|
||||||
* repository. The present version must have been created by "checkout". The
|
* repository. The present version must have been created by "checkout". The
|
||||||
@ -36,39 +36,26 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)update.c 1.83 92/04/10";
|
static char rcsid[] = "$CVSid: @(#)update.c 1.95 94/10/22 $";
|
||||||
|
USE(rcsid)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static int checkout_file PROTO((char *file, char *repository, List *entries,
|
||||||
static int checkout_file (char *file, char *repository, List *entries,
|
List *srcfiles, Vers_TS *vers_ts, char *update_dir));
|
||||||
List *srcfiles, Vers_TS *vers_ts, char *update_dir);
|
static int isemptydir PROTO((char *dir));
|
||||||
static int isemptydir (char *dir);
|
static int merge_file PROTO((char *file, char *repository, List *entries,
|
||||||
static int merge_file (char *file, char *repository, List *entries,
|
Vers_TS *vers, char *update_dir));
|
||||||
Vers_TS *vers, char *update_dir);
|
static int scratch_file PROTO((char *file, char *repository, List * entries,
|
||||||
static int scratch_file (char *file, char *repository, List * entries,
|
char *update_dir));
|
||||||
char *update_dir);
|
static Dtype update_dirent_proc PROTO((char *dir, char *repository, char *update_dir));
|
||||||
static Dtype update_dirent_proc (char *dir, char *repository, char *update_dir);
|
static int update_dirleave_proc PROTO((char *dir, int err, char *update_dir));
|
||||||
static int update_dirleave_proc (char *dir, int err, char *update_dir);
|
static int update_file_proc PROTO((char *file, char *update_dir, char *repository,
|
||||||
static int update_file_proc (char *file, char *update_dir, char *repository,
|
List * entries, List * srcfiles));
|
||||||
List * entries, List * srcfiles);
|
static int update_filesdone_proc PROTO((int err, char *repository, char *update_dir));
|
||||||
static int update_filesdone_proc (int err, char *repository, char *update_dir);
|
static int write_letter PROTO((char *file, int letter, char *update_dir));
|
||||||
static int write_letter (char *file, int letter, char *update_dir);
|
static void ignore_files PROTO((List * ilist, char *update_dir));
|
||||||
static void ignore_files (List * ilist, char *update_dir);
|
static void join_file PROTO((char *file, List *srcfiles, Vers_TS *vers_ts,
|
||||||
static void join_file (char *file, List *srcfiles, Vers_TS *vers_ts,
|
char *update_dir, List *entries));
|
||||||
char *update_dir);
|
|
||||||
#else
|
|
||||||
static int update_file_proc ();
|
|
||||||
static int update_filesdone_proc ();
|
|
||||||
static Dtype update_dirent_proc ();
|
|
||||||
static int update_dirleave_proc ();
|
|
||||||
static int isemptydir ();
|
|
||||||
static int scratch_file ();
|
|
||||||
static int checkout_file ();
|
|
||||||
static int write_letter ();
|
|
||||||
static int merge_file ();
|
|
||||||
static void ignore_files ();
|
|
||||||
static void join_file ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
static char *options = NULL;
|
static char *options = NULL;
|
||||||
static char *tag = NULL;
|
static char *tag = NULL;
|
||||||
@ -81,7 +68,7 @@ static int update_build_dirs = 0;
|
|||||||
static int update_prune_dirs = 0;
|
static int update_prune_dirs = 0;
|
||||||
static int pipeout = 0;
|
static int pipeout = 0;
|
||||||
static List *ignlist = (List *) NULL;
|
static List *ignlist = (List *) NULL;
|
||||||
|
static time_t last_register_time;
|
||||||
static char *update_usage[] =
|
static char *update_usage[] =
|
||||||
{
|
{
|
||||||
"Usage:\n %s %s [-APQdflRpq] [-k kopt] [-r rev|-D date] [-j rev] [-I ign] [files...]\n",
|
"Usage:\n %s %s [-APQdflRpq] [-k kopt] [-r rev|-D date] [-j rev] [-I ign] [files...]\n",
|
||||||
@ -121,7 +108,7 @@ update (argc, argv)
|
|||||||
|
|
||||||
/* parse the args */
|
/* parse the args */
|
||||||
optind = 1;
|
optind = 1;
|
||||||
while ((c = gnu_getopt (argc, argv, "ApPflRQqdk:r:D:j:I:")) != -1)
|
while ((c = getopt (argc, argv, "ApPflRQqdk:r:D:j:I:")) != -1)
|
||||||
{
|
{
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
@ -192,7 +179,10 @@ update (argc, argv)
|
|||||||
if (argc <= 0 && !pipeout)
|
if (argc <= 0 && !pipeout)
|
||||||
{
|
{
|
||||||
if (update_build_dirs)
|
if (update_build_dirs)
|
||||||
(void) unlink_file (CVSADM_ENTSTAT);
|
{
|
||||||
|
if (unlink_file (CVSADM_ENTSTAT) < 0 && errno != ENOENT)
|
||||||
|
error (1, errno, "cannot remove file %s", CVSADM_ENTSTAT);
|
||||||
|
}
|
||||||
|
|
||||||
/* keep the CVS/Tag file current with the specified arguments */
|
/* keep the CVS/Tag file current with the specified arguments */
|
||||||
if (aflag || tag || date)
|
if (aflag || tag || date)
|
||||||
@ -256,14 +246,14 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
|
|||||||
/* setup the join support */
|
/* setup the join support */
|
||||||
join_rev1 = xjoin_rev1;
|
join_rev1 = xjoin_rev1;
|
||||||
join_rev2 = xjoin_rev2;
|
join_rev2 = xjoin_rev2;
|
||||||
if (join_rev1 && (cp = index (join_rev1, ':')) != NULL)
|
if (join_rev1 && (cp = strchr (join_rev1, ':')) != NULL)
|
||||||
{
|
{
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
date_rev1 = Make_Date (cp);
|
date_rev1 = Make_Date (cp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
date_rev1 = (char *) NULL;
|
date_rev1 = (char *) NULL;
|
||||||
if (join_rev2 && (cp = index (join_rev2, ':')) != NULL)
|
if (join_rev2 && (cp = strchr (join_rev2, ':')) != NULL)
|
||||||
{
|
{
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
date_rev2 = Make_Date (cp);
|
date_rev2 = Make_Date (cp);
|
||||||
@ -275,7 +265,18 @@ do_update (argc, argv, xoptions, xtag, xdate, xforce, local, xbuild, xaflag,
|
|||||||
err = start_recursion (update_file_proc, update_filesdone_proc,
|
err = start_recursion (update_file_proc, update_filesdone_proc,
|
||||||
update_dirent_proc, update_dirleave_proc,
|
update_dirent_proc, update_dirleave_proc,
|
||||||
argc, argv, local, which, aflag, 1,
|
argc, argv, local, which, aflag, 1,
|
||||||
preload_update_dir, 1);
|
preload_update_dir, 1, 0);
|
||||||
|
|
||||||
|
/* see if we need to sleep before returning */
|
||||||
|
if (last_register_time)
|
||||||
|
{
|
||||||
|
time_t now;
|
||||||
|
|
||||||
|
(void) time (&now);
|
||||||
|
if (now == last_register_time)
|
||||||
|
sleep (1); /* to avoid time-stamp races */
|
||||||
|
}
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,7 +304,8 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
|
|||||||
Vers_TS *vers;
|
Vers_TS *vers;
|
||||||
|
|
||||||
status = Classify_File (file, tag, date, options, force_tag_match,
|
status = Classify_File (file, tag, date, options, force_tag_match,
|
||||||
aflag, repository, entries, srcfiles, &vers);
|
aflag, repository, entries, srcfiles, &vers,
|
||||||
|
update_dir, pipeout);
|
||||||
if (pipeout)
|
if (pipeout)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -351,13 +353,65 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
|
|||||||
break;
|
break;
|
||||||
case T_CONFLICT: /* old punt-type errors */
|
case T_CONFLICT: /* old punt-type errors */
|
||||||
retval = 1;
|
retval = 1;
|
||||||
|
(void) write_letter (file, 'C', update_dir);
|
||||||
break;
|
break;
|
||||||
case T_NEEDS_MERGE: /* needs merging */
|
case T_NEEDS_MERGE: /* needs merging */
|
||||||
retval = merge_file (file, repository, entries,
|
retval = merge_file (file, repository, entries,
|
||||||
vers, update_dir);
|
vers, update_dir);
|
||||||
break;
|
break;
|
||||||
case T_MODIFIED: /* locally modified */
|
case T_MODIFIED: /* locally modified */
|
||||||
retval = write_letter (file, 'M', update_dir);
|
retval = 0;
|
||||||
|
if (vers->ts_conflict)
|
||||||
|
{
|
||||||
|
char *filestamp;
|
||||||
|
int retcode;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the timestamp has changed and no conflict indicators
|
||||||
|
* are found, it isn't a 'C' any more.
|
||||||
|
*/
|
||||||
|
filestamp = time_stamp (file);
|
||||||
|
retcode = strcmp (vers->ts_conflict, filestamp);
|
||||||
|
free (filestamp);
|
||||||
|
|
||||||
|
if (retcode)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* If the timestamps differ, look for Conflict
|
||||||
|
* indicators to see if 'C' 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!retcode)
|
||||||
|
{
|
||||||
|
(void) write_letter (file, 'C', update_dir);
|
||||||
|
retval = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Reregister to clear conflict flag. */
|
||||||
|
Register (entries, file, vers->vn_rcs, vers->ts_rcs,
|
||||||
|
vers->options, vers->tag,
|
||||||
|
vers->date, (char *)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!retval)
|
||||||
|
retval = write_letter (file, 'M', update_dir);
|
||||||
break;
|
break;
|
||||||
case T_CHECKOUT: /* needs checkout */
|
case T_CHECKOUT: /* needs checkout */
|
||||||
retval = checkout_file (file, repository, entries, srcfiles,
|
retval = checkout_file (file, repository, entries, srcfiles,
|
||||||
@ -382,7 +436,7 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
|
|||||||
|
|
||||||
/* only try to join if things have gone well thus far */
|
/* only try to join if things have gone well thus far */
|
||||||
if (retval == 0 && join_rev1)
|
if (retval == 0 && join_rev1)
|
||||||
join_file (file, srcfiles, vers, update_dir);
|
join_file (file, srcfiles, vers, update_dir, entries);
|
||||||
|
|
||||||
/* if this directory has an ignore list, add this file to it */
|
/* if this directory has an ignore list, add this file to it */
|
||||||
if (ignlist)
|
if (ignlist)
|
||||||
@ -392,7 +446,8 @@ update_file_proc (file, update_dir, repository, entries, srcfiles)
|
|||||||
p = getnode ();
|
p = getnode ();
|
||||||
p->type = FILES;
|
p->type = FILES;
|
||||||
p->key = xstrdup (file);
|
p->key = xstrdup (file);
|
||||||
(void) addnode (ignlist, p);
|
if (addnode (ignlist, p) != 0)
|
||||||
|
freenode (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
freevers_ts (&vers);
|
freevers_ts (&vers);
|
||||||
@ -423,6 +478,14 @@ update_filesdone_proc (err, repository, update_dir)
|
|||||||
run_arg (CVSADM);
|
run_arg (CVSADM);
|
||||||
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
||||||
}
|
}
|
||||||
|
#ifdef CVSADM_ROOT
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If there is no CVS/Root file, add one */
|
||||||
|
if (!isfile (CVSADM_ROOT))
|
||||||
|
Create_Root( (char *) NULL, CVSroot );
|
||||||
|
}
|
||||||
|
#endif /* CVSADM_ROOT */
|
||||||
|
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
@ -441,6 +504,14 @@ update_dirent_proc (dir, repository, update_dir)
|
|||||||
char *repository;
|
char *repository;
|
||||||
char *update_dir;
|
char *update_dir;
|
||||||
{
|
{
|
||||||
|
if (ignore_directory (update_dir))
|
||||||
|
{
|
||||||
|
/* print the warm fuzzy message */
|
||||||
|
if (!quiet)
|
||||||
|
error (0, 0, "Ignoring %s", update_dir);
|
||||||
|
return R_SKIP_ALL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!isdir (dir))
|
if (!isdir (dir))
|
||||||
{
|
{
|
||||||
/* if we aren't building dirs, blow it off */
|
/* if we aren't building dirs, blow it off */
|
||||||
@ -472,7 +543,8 @@ update_dirent_proc (dir, repository, update_dir)
|
|||||||
char tmp[PATH_MAX];
|
char tmp[PATH_MAX];
|
||||||
|
|
||||||
(void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT);
|
(void) sprintf (tmp, "%s/%s", dir, CVSADM_ENTSTAT);
|
||||||
(void) unlink_file (tmp);
|
if (unlink_file (tmp) < 0 && errno != ENOENT)
|
||||||
|
error (1, errno, "cannot remove file %s", tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* keep the CVS/Tag file current with the specified arguments */
|
/* keep the CVS/Tag file current with the specified arguments */
|
||||||
@ -515,7 +587,7 @@ update_dirleave_proc (dir, err, update_dir)
|
|||||||
repository = Name_Repository ((char *) NULL, update_dir);
|
repository = Name_Repository ((char *) NULL, update_dir);
|
||||||
if (fgets (line, sizeof (line), fp) != NULL)
|
if (fgets (line, sizeof (line), fp) != NULL)
|
||||||
{
|
{
|
||||||
if ((cp = rindex (line, '\n')) != NULL)
|
if ((cp = strrchr (line, '\n')) != NULL)
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
run_setup ("%s %s", line, repository);
|
run_setup ("%s %s", line, repository);
|
||||||
(void) printf ("%s %s: Executing '", program_name, command_name);
|
(void) printf ("%s %s: Executing '", program_name, command_name);
|
||||||
@ -534,6 +606,35 @@ update_dirleave_proc (dir, err, update_dir)
|
|||||||
run_arg (CVSADM);
|
run_arg (CVSADM);
|
||||||
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
(void) run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
||||||
}
|
}
|
||||||
|
#ifdef CVSADM_ROOT
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* If there is no CVS/Root file, add one */
|
||||||
|
if (!isreadable (CVSADM_ROOT))
|
||||||
|
{
|
||||||
|
if (isfile (CVSADM_ROOT))
|
||||||
|
{
|
||||||
|
error (0, 0, "bad permissions %s/%s deleteing it", update_dir,
|
||||||
|
CVSADM_ROOT);
|
||||||
|
if (unlink_file (CVSADM_ROOT) == -1)
|
||||||
|
{
|
||||||
|
error (0, errno, "delete failed for %s/%s",
|
||||||
|
update_dir, CVSADM_ROOT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Create_Root( (char *) NULL, CVSroot );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *root = Name_Root( (char *) NULL, update_dir);
|
||||||
|
|
||||||
|
if (root == NULL)
|
||||||
|
Create_Root( (char *) NULL, CVSroot );
|
||||||
|
else
|
||||||
|
free (root); /* all is well, release the storage */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* CVSADM_ROOT */
|
||||||
|
|
||||||
/* Prune empty dirs on the way out - if necessary */
|
/* Prune empty dirs on the way out - if necessary */
|
||||||
(void) chdir ("..");
|
(void) chdir ("..");
|
||||||
@ -556,7 +657,7 @@ isemptydir (dir)
|
|||||||
char *dir;
|
char *dir;
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct direct *dp;
|
struct dirent *dp;
|
||||||
|
|
||||||
if ((dirp = opendir (dir)) == NULL)
|
if ((dirp = opendir (dir)) == NULL)
|
||||||
{
|
{
|
||||||
@ -671,8 +772,12 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
|
|||||||
force_tag_match, set_time, entries, srcfiles);
|
force_tag_match, set_time, entries, srcfiles);
|
||||||
if (strcmp (xvers_ts->options, "-V4") == 0)
|
if (strcmp (xvers_ts->options, "-V4") == 0)
|
||||||
xvers_ts->options[0] = '\0';
|
xvers_ts->options[0] = '\0';
|
||||||
|
|
||||||
|
(void) time (&last_register_time);
|
||||||
|
|
||||||
Register (entries, file, xvers_ts->vn_rcs, xvers_ts->ts_user,
|
Register (entries, file, xvers_ts->vn_rcs, xvers_ts->ts_user,
|
||||||
xvers_ts->options, xvers_ts->tag, xvers_ts->date);
|
xvers_ts->options, xvers_ts->tag, xvers_ts->date,
|
||||||
|
(char *)0); /* Clear conflict flag on fresh checkout */
|
||||||
|
|
||||||
/* fix up the vers structure, in case it is used by join */
|
/* fix up the vers structure, in case it is used by join */
|
||||||
if (join_rev1)
|
if (join_rev1)
|
||||||
@ -727,7 +832,7 @@ checkout_file (file, repository, entries, srcfiles, vers_ts, update_dir)
|
|||||||
static int
|
static int
|
||||||
write_letter (file, letter, update_dir)
|
write_letter (file, letter, update_dir)
|
||||||
char *file;
|
char *file;
|
||||||
char letter;
|
int letter;
|
||||||
char *update_dir;
|
char *update_dir;
|
||||||
{
|
{
|
||||||
if (!really_quiet)
|
if (!really_quiet)
|
||||||
@ -791,11 +896,20 @@ merge_file (file, repository, entries, vers, update_dir)
|
|||||||
rename_file (backup, file);
|
rename_file (backup, file);
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
/* XXX - Might want to make sure that rcsmerge changed the file */
|
|
||||||
if (strcmp (vers->options, "-V4") == 0)
|
if (strcmp (vers->options, "-V4") == 0)
|
||||||
vers->options[0] = '\0';
|
vers->options[0] = '\0';
|
||||||
Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options,
|
(void) time (&last_register_time);
|
||||||
vers->tag, vers->date);
|
{
|
||||||
|
char *cp = 0;
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
cp = time_stamp (file);
|
||||||
|
Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options,
|
||||||
|
vers->tag, vers->date, cp);
|
||||||
|
if (cp)
|
||||||
|
free (cp);
|
||||||
|
}
|
||||||
|
|
||||||
/* fix up the vers structure, in case it is used by join */
|
/* fix up the vers structure, in case it is used by join */
|
||||||
if (join_rev1)
|
if (join_rev1)
|
||||||
@ -805,6 +919,14 @@ merge_file (file, repository, entries, vers, update_dir)
|
|||||||
vers->vn_user = xstrdup (vers->vn_rcs);
|
vers->vn_user = xstrdup (vers->vn_rcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!xcmp (backup, file))
|
||||||
|
{
|
||||||
|
printf ("%s already contains the differences between %s and %s\n",
|
||||||
|
user, vers->vn_user, vers->vn_rcs);
|
||||||
|
history_write ('G', update_dir, vers->vn_rcs, file, repository);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* possibly run GREP to see if there appear to be conflicts in the file */
|
/* possibly run GREP to see if there appear to be conflicts in the file */
|
||||||
run_setup ("%s -s", GREP);
|
run_setup ("%s -s", GREP);
|
||||||
run_arg (RCS_MERGE_PAT);
|
run_arg (RCS_MERGE_PAT);
|
||||||
@ -839,98 +961,216 @@ merge_file (file, repository, entries, vers, update_dir)
|
|||||||
* (-j option)
|
* (-j option)
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
join_file (file, srcfiles, vers, update_dir)
|
join_file (file, srcfiles, vers, update_dir, entries)
|
||||||
char *file;
|
char *file;
|
||||||
List *srcfiles;
|
List *srcfiles;
|
||||||
Vers_TS *vers;
|
Vers_TS *vers;
|
||||||
char *update_dir;
|
char *update_dir;
|
||||||
|
List *entries;
|
||||||
{
|
{
|
||||||
char user[PATH_MAX];
|
char user[PATH_MAX];
|
||||||
char backup[PATH_MAX];
|
char backup[PATH_MAX];
|
||||||
char *rev, *baserev;
|
|
||||||
char *options;
|
char *options;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
char *rev1;
|
||||||
|
char *rev2;
|
||||||
|
char *jrev1;
|
||||||
|
char *jrev2;
|
||||||
|
char *jdate1;
|
||||||
|
char *jdate2;
|
||||||
|
|
||||||
|
jrev1 = join_rev1;
|
||||||
|
jrev2 = join_rev2;
|
||||||
|
jdate1 = date_rev1;
|
||||||
|
jdate2 = date_rev2;
|
||||||
|
|
||||||
/* determine if we need to do anything at all */
|
/* determine if we need to do anything at all */
|
||||||
if (vers->vn_user == NULL || vers->srcfile == NULL ||
|
if (vers->srcfile == NULL ||
|
||||||
vers->srcfile->path == NULL)
|
vers->srcfile->path == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* special handling when two revisions are specified */
|
/* in all cases, use two revs. */
|
||||||
if (join_rev1 && join_rev2)
|
|
||||||
|
/* if only one rev is specified, it becomes the second rev */
|
||||||
|
if (jrev2 == NULL)
|
||||||
{
|
{
|
||||||
rev = RCS_getversion (vers->srcfile, join_rev2, date_rev2, 1);
|
jrev2 = jrev1;
|
||||||
if (rev == NULL)
|
jrev1 = NULL;
|
||||||
|
jdate2 = jdate1;
|
||||||
|
jdate1 = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* convert the second rev spec, walking branches and dates. */
|
||||||
|
|
||||||
|
rev2 = RCS_getversion (vers->srcfile, jrev2, jdate2, 1);
|
||||||
|
if (rev2 == NULL)
|
||||||
|
{
|
||||||
|
if (!quiet)
|
||||||
{
|
{
|
||||||
if (!quiet && date_rev2 == NULL)
|
if (jdate2 != NULL)
|
||||||
error (0, 0,
|
error (0, 0,
|
||||||
"cannot find revision %s in file %s", join_rev2, file);
|
"cannot find revision %s as of %s in file %s",
|
||||||
|
jrev2, jdate2, file);
|
||||||
|
else
|
||||||
|
error (0, 0,
|
||||||
|
"cannot find revision %s in file %s",
|
||||||
|
jrev2, file);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* skip joining identical revs */
|
||||||
|
if (strcmp (rev2, vers->vn_user) == 0) /* no merge necessary */
|
||||||
|
{
|
||||||
|
free (rev2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
baserev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1);
|
if (jrev1 == NULL)
|
||||||
if (baserev == NULL)
|
{
|
||||||
|
char *tst;
|
||||||
|
/* if the first rev is missing, then it is implied to be the
|
||||||
|
greatest common ancestor of both the join rev, and the
|
||||||
|
checked out rev. */
|
||||||
|
|
||||||
|
tst = vers->vn_user;
|
||||||
|
if (*tst == '!')
|
||||||
{
|
{
|
||||||
if (!quiet && date_rev1 == NULL)
|
/* file was dead. merge anyway and pretend it's been
|
||||||
error (0, 0,
|
added. */
|
||||||
"cannot find revision %s in file %s", join_rev1, file);
|
++tst;
|
||||||
free (rev);
|
Register (entries, file, "0", vers->ts_user, vers->options,
|
||||||
return;
|
vers->tag, (char *) 0, (char *) 0);
|
||||||
|
}
|
||||||
|
rev1 = gca (tst, rev2);
|
||||||
|
if (rev1 == NULL)
|
||||||
|
{
|
||||||
|
/* this should not be possible */
|
||||||
|
error (0, 0, "bad gca");
|
||||||
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
tst = RCS_gettag (vers->srcfile, rev2, 1);
|
||||||
* nothing to do if:
|
if (tst == NULL)
|
||||||
* second revision matches our BASE revision (vn_user) &&
|
|
||||||
* both revisions are on the same branch
|
|
||||||
*/
|
|
||||||
if (strcmp (vers->vn_user, rev) == 0 &&
|
|
||||||
numdots (baserev) == numdots (rev))
|
|
||||||
{
|
{
|
||||||
/* might be the same branch. take a real look */
|
/* this should not be possible. */
|
||||||
char *dot = rindex (baserev, '.');
|
error (0, 0, "cannot find gca");
|
||||||
int len = (dot - baserev) + 1;
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
if (strncmp (baserev, rev, len) == 0)
|
free (tst);
|
||||||
return;
|
|
||||||
|
/* these two cases are noops */
|
||||||
|
if (strcmp (rev1, rev2) == 0)
|
||||||
|
{
|
||||||
|
free (rev1);
|
||||||
|
free (rev2);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1);
|
/* otherwise, convert the first rev spec, walking branches and
|
||||||
if (rev == NULL)
|
dates. */
|
||||||
return;
|
|
||||||
if (strcmp (rev, vers->vn_user) == 0) /* no merge necessary */
|
|
||||||
{
|
|
||||||
free (rev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
baserev = RCS_whatbranch (file, join_rev1, srcfiles);
|
rev1 = RCS_getversion (vers->srcfile, jrev1, jdate1, 1);
|
||||||
if (baserev)
|
if (rev1 == NULL
|
||||||
|
&& !quiet)
|
||||||
{
|
{
|
||||||
char *cp;
|
if (jdate1 != NULL)
|
||||||
|
error (0, 0,
|
||||||
/* we get a branch -- turn it into a revision, or NULL if trunk */
|
"cannot find revision %s as of %s in file %s",
|
||||||
if ((cp = rindex (baserev, '.')) == NULL)
|
jrev1, jdate1, file);
|
||||||
{
|
|
||||||
free (baserev);
|
|
||||||
baserev = (char *) NULL;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
*cp = '\0';
|
error (0, 0,
|
||||||
|
"cannot find revision %s in file %s",
|
||||||
|
jrev1, file);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (baserev && strcmp (baserev, rev) == 0)
|
|
||||||
{
|
|
||||||
/* they match -> nothing to do */
|
|
||||||
free (rev);
|
|
||||||
free (baserev);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* OK, so we have a revision and possibly a base revision; continue on */
|
/* do the join */
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
dome {
|
||||||
|
/* special handling when two revisions are specified */
|
||||||
|
if (join_rev1 && join_rev2)
|
||||||
|
{
|
||||||
|
rev = RCS_getversion (vers->srcfile, join_rev2, date_rev2, 1);
|
||||||
|
if (rev == NULL)
|
||||||
|
{
|
||||||
|
if (!quiet && date_rev2 == NULL)
|
||||||
|
error (0, 0,
|
||||||
|
"cannot find revision %s in file %s", join_rev2, file);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
baserev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1);
|
||||||
|
if (baserev == NULL)
|
||||||
|
{
|
||||||
|
if (!quiet && date_rev1 == NULL)
|
||||||
|
error (0, 0,
|
||||||
|
"cannot find revision %s in file %s", join_rev1, file);
|
||||||
|
free (rev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* nothing to do if:
|
||||||
|
* second revision matches our BASE revision (vn_user) &&
|
||||||
|
* both revisions are on the same branch
|
||||||
|
*/
|
||||||
|
if (strcmp (vers->vn_user, rev) == 0 &&
|
||||||
|
numdots (baserev) == numdots (rev))
|
||||||
|
{
|
||||||
|
/* might be the same branch. take a real look */
|
||||||
|
char *dot = strrchr (baserev, '.');
|
||||||
|
int len = (dot - baserev) + 1;
|
||||||
|
|
||||||
|
if (strncmp (baserev, rev, len) == 0)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rev = RCS_getversion (vers->srcfile, join_rev1, date_rev1, 1);
|
||||||
|
if (rev == NULL)
|
||||||
|
return;
|
||||||
|
if (strcmp (rev, vers->vn_user) == 0) /* no merge necessary */
|
||||||
|
{
|
||||||
|
free (rev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
baserev = RCS_whatbranch (file, join_rev1, srcfiles);
|
||||||
|
if (baserev)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
/* we get a branch -- turn it into a revision, or NULL if trunk */
|
||||||
|
if ((cp = strrchr (baserev, '.')) == NULL)
|
||||||
|
{
|
||||||
|
free (baserev);
|
||||||
|
baserev = (char *) NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*cp = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (baserev && strcmp (baserev, rev) == 0)
|
||||||
|
{
|
||||||
|
/* they match -> nothing to do */
|
||||||
|
free (rev);
|
||||||
|
free (baserev);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* OK, so we have two revisions; continue on */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The users currently modified file is moved to a backup file name
|
* The users currently modified file is moved to a backup file name
|
||||||
@ -951,13 +1191,15 @@ join_file (file, srcfiles, vers, update_dir)
|
|||||||
|
|
||||||
options = vers->options;
|
options = vers->options;
|
||||||
#ifdef HAVE_RCS5
|
#ifdef HAVE_RCS5
|
||||||
|
#if 0
|
||||||
if (*options == '\0')
|
if (*options == '\0')
|
||||||
options = "-kk"; /* to ignore keyword expansions */
|
options = "-kk"; /* to ignore keyword expansions */
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* XXX - Do merge by hand instead of using rcsmerge, due to -k handling */
|
/* XXX - Do merge by hand instead of using rcsmerge, due to -k handling */
|
||||||
run_setup ("%s%s %s %s%s -r%s", Rcsbin, RCS_RCSMERGE, options,
|
run_setup ("%s%s %s -r%s -r%s", Rcsbin, RCS_RCSMERGE, options,
|
||||||
baserev ? "-r" : "", baserev ? baserev : "", rev);
|
rev1, rev2);
|
||||||
run_arg (vers->srcfile->path);
|
run_arg (vers->srcfile->path);
|
||||||
status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
status = run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL);
|
||||||
if (status != 0
|
if (status != 0
|
||||||
@ -967,14 +1209,28 @@ join_file (file, srcfiles, vers, update_dir)
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
error (0, status == -1 ? errno : 0,
|
error (0, status == -1 ? errno : 0,
|
||||||
"could not merge revision %s of %s", rev, user);
|
"could not merge revision %s of %s", rev2, user);
|
||||||
error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
|
error (status == -1 ? 1 : 0, 0, "restoring %s from backup file %s",
|
||||||
user, backup);
|
user, backup);
|
||||||
rename_file (backup, file);
|
rename_file (backup, file);
|
||||||
}
|
}
|
||||||
free (rev);
|
free (rev1);
|
||||||
if (baserev)
|
free (rev2);
|
||||||
free (baserev);
|
|
||||||
|
#ifdef HAVE_RCS5
|
||||||
|
if (status == 1)
|
||||||
|
{
|
||||||
|
char *cp = 0;
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
cp = time_stamp (file);
|
||||||
|
Register (entries, file, vers->vn_rcs, vers->ts_rcs, vers->options,
|
||||||
|
vers->tag, vers->date, cp);
|
||||||
|
if (cp)
|
||||||
|
free(cp);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -988,7 +1244,7 @@ ignore_files (ilist, update_dir)
|
|||||||
char *update_dir;
|
char *update_dir;
|
||||||
{
|
{
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
struct direct *dp;
|
struct dirent *dp;
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
char *file;
|
char *file;
|
||||||
char *xdir;
|
char *xdir;
|
||||||
@ -1011,18 +1267,47 @@ ignore_files (ilist, update_dir)
|
|||||||
continue;
|
continue;
|
||||||
if (findnode (ilist, file) != NULL)
|
if (findnode (ilist, file) != NULL)
|
||||||
continue;
|
continue;
|
||||||
if (lstat (file, &sb) != -1)
|
|
||||||
{
|
if (
|
||||||
if (S_ISDIR (sb.st_mode))
|
#ifdef DT_DIR
|
||||||
continue;
|
dp->d_type != DT_UNKNOWN ||
|
||||||
#ifdef S_IFLNK
|
|
||||||
if (S_ISLNK (sb.st_mode))
|
|
||||||
continue;
|
|
||||||
#endif
|
#endif
|
||||||
}
|
lstat(file, &sb) != -1)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (
|
||||||
|
#ifdef DT_DIR
|
||||||
|
dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN &&
|
||||||
|
#endif
|
||||||
|
S_ISDIR(sb.st_mode))
|
||||||
|
{
|
||||||
|
char temp[PATH_MAX];
|
||||||
|
|
||||||
|
(void) sprintf (temp, "%s/%s", file, CVSADM);
|
||||||
|
if (isdir (temp))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifdef S_ISLNK
|
||||||
|
else if (
|
||||||
|
#ifdef DT_DIR
|
||||||
|
dp->d_type == DT_LNK || dp->d_type == DT_UNKNOWN &&
|
||||||
|
#endif
|
||||||
|
S_ISLNK(sb.st_mode))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
if (ign_name (file))
|
if (ign_name (file))
|
||||||
continue;
|
continue;
|
||||||
(void) write_letter (file, '?', xdir);
|
(void) write_letter (file, '?', xdir);
|
||||||
}
|
}
|
||||||
(void) closedir (dirp);
|
(void) closedir (dirp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
joining ()
|
||||||
|
{
|
||||||
|
return (join_rev1 != NULL);
|
||||||
|
}
|
||||||
|
@ -3,16 +3,17 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#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
|
* 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 */
|
/* get a new Vers_TS struct */
|
||||||
vers_ts = (Vers_TS *) xmalloc (sizeof (Vers_TS));
|
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
|
* 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->vn_user = xstrdup (entdata->version);
|
||||||
vers_ts->ts_rcs = xstrdup (entdata->timestamp);
|
vers_ts->ts_rcs = xstrdup (entdata->timestamp);
|
||||||
|
vers_ts->ts_conflict = xstrdup (entdata->conflict);
|
||||||
if (!tag)
|
if (!tag)
|
||||||
{
|
{
|
||||||
if (!(sdtp && sdtp->aflag))
|
if (!(sdtp && sdtp->aflag))
|
||||||
@ -124,8 +126,10 @@ Version_TS (repository, options, tag, date, user, force_tag_match,
|
|||||||
else
|
else
|
||||||
rcsdata = NULL;
|
rcsdata = NULL;
|
||||||
}
|
}
|
||||||
else
|
else if (repository != NULL)
|
||||||
rcsdata = RCS_parse (user, repository);
|
rcsdata = RCS_parse (user, repository);
|
||||||
|
else
|
||||||
|
rcsdata = NULL;
|
||||||
|
|
||||||
if (rcsdata != NULL)
|
if (rcsdata != NULL)
|
||||||
{
|
{
|
||||||
@ -141,7 +145,7 @@ Version_TS (repository, options, tag, date, user, force_tag_match,
|
|||||||
else
|
else
|
||||||
vers_ts->vn_rcs = RCS_getversion (rcsdata, vers_ts->tag,
|
vers_ts->vn_rcs = RCS_getversion (rcsdata, vers_ts->tag,
|
||||||
vers_ts->date, force_tag_match);
|
vers_ts->date, force_tag_match);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the source control file exists and has the requested revision,
|
* If the source control file exists and has the requested revision,
|
||||||
@ -152,16 +156,19 @@ Version_TS (repository, options, tag, date, user, force_tag_match,
|
|||||||
{
|
{
|
||||||
struct utimbuf t;
|
struct utimbuf t;
|
||||||
|
|
||||||
|
memset ((char *) &t, 0, sizeof (t));
|
||||||
if (vers_ts->vn_rcs &&
|
if (vers_ts->vn_rcs &&
|
||||||
(t.actime = t.modtime = RCS_getrevtime (rcsdata, vers_ts->vn_rcs,
|
(t.actime = t.modtime = RCS_getrevtime (rcsdata,
|
||||||
(char *) 0, 0)) != -1)
|
vers_ts->vn_rcs, (char *) 0, 0)) != -1)
|
||||||
(void) utime (user, &t);
|
(void) utime (user, &t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get user file time-stamp in ts_user */
|
/* get user file time-stamp in ts_user */
|
||||||
if (entries != (List *) NULL)
|
if (entries != (List *) NULL)
|
||||||
vers_ts->ts_user = time_stamp (user);
|
{
|
||||||
|
vers_ts->ts_user = time_stamp (user);
|
||||||
|
}
|
||||||
|
|
||||||
return (vers_ts);
|
return (vers_ts);
|
||||||
}
|
}
|
||||||
@ -184,13 +191,10 @@ time_stamp (file)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ts = xmalloc (51); /* 51 = 2 ctime strings + NULL */
|
ts = xmalloc (25);
|
||||||
cp = ctime (&sb.st_ctime); /* copy in the create time */
|
cp = asctime (gmtime (&sb.st_mtime)); /* copy in the modify time */
|
||||||
cp[24] = ' ';
|
cp[24] = 0;
|
||||||
(void) strcpy (ts, cp);
|
(void) strcpy (ts, cp);
|
||||||
cp = ctime (&sb.st_mtime); /* copy in the modify time */
|
|
||||||
cp[24] = '\0';
|
|
||||||
(void) strcat (ts, cp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (ts);
|
return (ts);
|
||||||
@ -219,6 +223,8 @@ freevers_ts (versp)
|
|||||||
free ((*versp)->tag);
|
free ((*versp)->tag);
|
||||||
if ((*versp)->date)
|
if ((*versp)->date)
|
||||||
free ((*versp)->date);
|
free ((*versp)->date);
|
||||||
|
if ((*versp)->ts_conflict)
|
||||||
|
free ((*versp)->ts_conflict);
|
||||||
free ((char *) *versp);
|
free ((char *) *versp);
|
||||||
*versp = (Vers_TS *) NULL;
|
*versp = (Vers_TS *) NULL;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,18 @@
|
|||||||
|
#! /bin/sh
|
||||||
:
|
:
|
||||||
#
|
#
|
||||||
# Copyright (c) 1992, Brian Berliner
|
# Copyright (c) 1992, Brian Berliner
|
||||||
#
|
#
|
||||||
# You may distribute under the terms of the GNU General Public License as
|
# 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.
|
||||||
#
|
#
|
||||||
# @(#)cvsinit 1.1 92/03/31
|
# $CVSid: @(#)cvsinit.sh 1.1 94/10/22 $
|
||||||
#
|
#
|
||||||
# This script should be run once to help you setup your site for CVS.
|
# This script should be run once to help you setup your site for CVS.
|
||||||
|
|
||||||
|
# this line is edited by Makefile when creating cvsinit.inst
|
||||||
|
CVSLIB="xLIBDIRx"
|
||||||
|
|
||||||
# Make sure that the CVSROOT variable is set
|
# Make sure that the CVSROOT variable is set
|
||||||
if [ "x$CVSROOT" = x ]; then
|
if [ "x$CVSROOT" = x ]; then
|
||||||
echo "The CVSROOT environment variable is not set."
|
echo "The CVSROOT environment variable is not set."
|
||||||
@ -155,9 +159,9 @@ else
|
|||||||
for perlpath in `echo $PATH | sed -e 's/:/ /g'` x; do
|
for perlpath in `echo $PATH | sed -e 's/:/ /g'` x; do
|
||||||
if [ -f $perlpath/perl ]; then
|
if [ -f $perlpath/perl ]; then
|
||||||
echo "#!$perlpath/perl" > $CVSROOT/CVSROOT/log.pl
|
echo "#!$perlpath/perl" > $CVSROOT/CVSROOT/log.pl
|
||||||
cat contrib/log.pl >> $CVSROOT/CVSROOT/log.pl
|
cat $CVSLIB/contrib/log.pl >> $CVSROOT/CVSROOT/log.pl
|
||||||
chmod 755 $CVSROOT/CVSROOT/log.pl
|
chmod 755 $CVSROOT/CVSROOT/log.pl
|
||||||
cp examples/loginfo $CVSROOT/CVSROOT/loginfo
|
cp $CVSLIB/examples/loginfo $CVSROOT/CVSROOT/loginfo
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@ -207,13 +211,15 @@ for info in commitinfo rcsinfo editinfo; do
|
|||||||
else
|
else
|
||||||
echo "The $CVSROOT/CVSROOT/$info file does not exist."
|
echo "The $CVSROOT/CVSROOT/$info file does not exist."
|
||||||
echo "Making a simple one for you..."
|
echo "Making a simple one for you..."
|
||||||
sed -e 's/^\([^#]\)/#\1/' examples/$info > $CVSROOT/CVSROOT/$info
|
sed -e 's/^\([^#]\)/#\1/' $CVSLIB/examples/$info > $CVSROOT/CVSROOT/$info
|
||||||
fi
|
fi
|
||||||
(cd $CVSROOT/CVSROOT; ci -q -u -t/dev/null -m"initial checkin of $info" $info)
|
(cd $CVSROOT/CVSROOT; ci -q -u -t/dev/null -m"initial checkin of $info" $info)
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
|
# XXX - also add a stub for the cvsignore file
|
||||||
|
|
||||||
# Turn on history logging by default
|
# Turn on history logging by default
|
||||||
if [ ! -f $CVSROOT/CVSROOT/history ]; then
|
if [ ! -f $CVSROOT/CVSROOT/history ]; then
|
||||||
echo "Enabling CVS history logging..."
|
echo "Enabling CVS history logging..."
|
||||||
|
@ -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 "commitinfo" file is used to control pre-commit checks.
|
||||||
# The filter on the right is invoked with the repository and a list
|
# 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
|
# The "editinfo" file is used to allow verification of logging
|
||||||
# information. It works best when a template (as specified in the
|
# 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
|
# 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
|
# 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
|
# 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:
|
# Three different line formats are valid:
|
||||||
# key -a aliases...
|
# 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
|
# The "rcsinfo" file is used to control templates with which the editor
|
||||||
# is invoked on commit and import.
|
# is invoked on commit and import.
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
|
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef emacs
|
#if defined(emacs) || defined(HAVE_CONFIG_H)
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#ifdef static
|
#ifdef static
|
||||||
/* actually, only want this if static is defined as ""
|
/* actually, only want this if static is defined as ""
|
||||||
@ -43,7 +43,7 @@ lose
|
|||||||
-- must know STACK_DIRECTION at compile-time
|
-- must know STACK_DIRECTION at compile-time
|
||||||
#endif /* STACK_DIRECTION undefined */
|
#endif /* STACK_DIRECTION undefined */
|
||||||
#endif /* static */
|
#endif /* static */
|
||||||
#endif /* emacs */
|
#endif /* emacs || HAVE_CONFIG_H*/
|
||||||
|
|
||||||
#if __STDC__
|
#if __STDC__
|
||||||
typedef void *pointer; /* generic pointer type */
|
typedef void *pointer; /* generic pointer type */
|
||||||
|
@ -17,6 +17,10 @@
|
|||||||
|
|
||||||
/* Written by David MacKenzie <djm@ai.mit.edu> */
|
/* Written by David MacKenzie <djm@ai.mit.edu> */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
last edit: 11-Feb-1987 D A Gwyn
|
last edit: 11-Feb-1987 D A Gwyn
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
@ -19,9 +19,13 @@
|
|||||||
/* Brian Berliner added support for CVS */
|
/* Brian Berliner added support for CVS */
|
||||||
|
|
||||||
#ifndef lint
|
#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 */
|
#endif /* not lint */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* turn on CVS support by default, since this is the CVS distribution */
|
/* turn on CVS support by default, since this is the CVS distribution */
|
||||||
@ -35,7 +39,7 @@ void Lock_Cleanup();
|
|||||||
#endif /* __STDC__ */
|
#endif /* __STDC__ */
|
||||||
#endif /* CVS_SUPPORT */
|
#endif /* CVS_SUPPORT */
|
||||||
|
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
|
|
||||||
#if __STDC__
|
#if __STDC__
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
@ -47,7 +51,7 @@ void Lock_Cleanup();
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#ifndef DOPRNT_MISSING
|
#ifdef HAVE_DOPRNT
|
||||||
#define va_alist args
|
#define va_alist args
|
||||||
#define va_dcl int args;
|
#define va_dcl int args;
|
||||||
#else
|
#else
|
||||||
@ -57,7 +61,7 @@ void Lock_Cleanup();
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef STDC_HEADERS
|
#if STDC_HEADERS
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#else
|
#else
|
||||||
@ -68,19 +72,7 @@ void exit ();
|
|||||||
#endif /* __STDC__ */
|
#endif /* __STDC__ */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef STRERROR_MISSING
|
extern char *strerror ();
|
||||||
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 */
|
|
||||||
|
|
||||||
/* Print the program name and error message MESSAGE, which is a printf-style
|
/* Print the program name and error message MESSAGE, which is a printf-style
|
||||||
format string with optional args.
|
format string with optional args.
|
||||||
@ -88,7 +80,7 @@ strerror (errnum)
|
|||||||
Exit with status STATUS if it is nonzero. */
|
Exit with status STATUS if it is nonzero. */
|
||||||
/* VARARGS */
|
/* VARARGS */
|
||||||
void
|
void
|
||||||
#if !defined (VPRINTF_MISSING) && __STDC__
|
#if defined (HAVE_VPRINTF) && __STDC__
|
||||||
error (int status, int errnum, char *message, ...)
|
error (int status, int errnum, char *message, ...)
|
||||||
#else
|
#else
|
||||||
error (status, errnum, message, va_alist)
|
error (status, errnum, message, va_alist)
|
||||||
@ -102,7 +94,7 @@ error (status, errnum, message, va_alist)
|
|||||||
#ifdef CVS_SUPPORT
|
#ifdef CVS_SUPPORT
|
||||||
extern char *command_name;
|
extern char *command_name;
|
||||||
#endif
|
#endif
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
va_list args;
|
va_list args;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -117,12 +109,12 @@ error (status, errnum, message, va_alist)
|
|||||||
#else
|
#else
|
||||||
fprintf (stderr, "%s: ", program_name);
|
fprintf (stderr, "%s: ", program_name);
|
||||||
#endif
|
#endif
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
VA_START (args, message);
|
VA_START (args, message);
|
||||||
vfprintf (stderr, message, args);
|
vfprintf (stderr, message, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
#else
|
#else
|
||||||
#ifndef DOPRNT_MISSING
|
#ifdef HAVE_DOPRNT
|
||||||
_doprnt (message, &args, stderr);
|
_doprnt (message, &args, stderr);
|
||||||
#else
|
#else
|
||||||
fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8);
|
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. */
|
Exit with status STATUS if it is nonzero. */
|
||||||
/* VARARGS */
|
/* VARARGS */
|
||||||
void
|
void
|
||||||
#if !defined (VPRINTF_MISSING) && __STDC__
|
#if defined (HAVE_VPRINTF) && __STDC__
|
||||||
fperror (FILE *fp, int status, int errnum, char *message, ...)
|
fperror (FILE *fp, int status, int errnum, char *message, ...)
|
||||||
#else
|
#else
|
||||||
fperror (fp, status, errnum, message, va_alist)
|
fperror (fp, status, errnum, message, va_alist)
|
||||||
@ -161,17 +153,17 @@ fperror (fp, status, errnum, message, va_alist)
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
extern char *program_name;
|
extern char *program_name;
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
va_list args;
|
va_list args;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fprintf (fp, "%s: ", program_name);
|
fprintf (fp, "%s: ", program_name);
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
VA_START (args, message);
|
VA_START (args, message);
|
||||||
vfprintf (fp, message, args);
|
vfprintf (fp, message, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
#else
|
#else
|
||||||
#ifndef DOPRNT_MISSING
|
#ifdef HAVE_DOPRNT
|
||||||
_doprnt (message, &args, fp);
|
_doprnt (message, &args, fp);
|
||||||
#else
|
#else
|
||||||
fprintf (fp, message, a1, a2, a3, a4, a5, a6, a7, a8);
|
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 */
|
/* Modified slightly by Brian Berliner <berliner@sun.com> for CVS use */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/* IGNORE(@ */
|
/* IGNORE(@ */
|
||||||
/* #include <ansidecl.h> */
|
/* #include <ansidecl.h> */
|
||||||
/* @) */
|
/* @) */
|
||||||
@ -28,10 +32,6 @@ Cambridge, MA 02139, USA. */
|
|||||||
extern int errno;
|
extern int errno;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !__STDC__
|
|
||||||
#define const
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||||
it matches, nonzero if not. */
|
it matches, nonzero if not. */
|
||||||
int
|
int
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
/* ftruncate emulations that work on some System V's.
|
/* ftruncate emulations that work on some System V's.
|
||||||
This file is in the public domain. */
|
This file is in the public domain. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
@ -1,39 +1,110 @@
|
|||||||
%{
|
%{
|
||||||
/* 1.8
|
/*
|
||||||
** @(#)getdate.y 1.8 92/03/03
|
|
||||||
**
|
|
||||||
** Originally written by Steven M. Bellovin <smb@research.att.com> while
|
** Originally written by Steven M. Bellovin <smb@research.att.com> while
|
||||||
** at the University of North Carolina at Chapel Hill. Later tweaked by
|
** at the University of North Carolina at Chapel Hill. Later tweaked by
|
||||||
** a couple of people on Usenet. Completely overhauled by Rich $alz
|
** a couple of people on Usenet. Completely overhauled by Rich $alz
|
||||||
** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
|
** <rsalz@bbn.com> and Jim Berets <jberets@bbn.com> in August, 1990;
|
||||||
** send any email to Rich.
|
** 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.
|
** This code is in the public domain and has no copyright.
|
||||||
*/
|
*/
|
||||||
/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
|
/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
|
||||||
/* SUPPRESS 288 on yyerrlab *//* Label unused */
|
/* 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>
|
#include <ctype.h>
|
||||||
|
|
||||||
#if (!defined (__STDC__) && defined (sparc)) || defined (__sparc__)
|
/* The code at the top of get_date which figures out the offset of the
|
||||||
#ifdef __GNUC__
|
current time zone checks various CPP symbols to see if special
|
||||||
#undef alloca /* might get redefined below */
|
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
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern struct tm *localtime();
|
#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
|
#define yyparse getdate_yyparse
|
||||||
#define yylex getdate_yylex
|
#define yylex getdate_yylex
|
||||||
#define yyerror getdate_yyerror
|
#define yyerror getdate_yyerror
|
||||||
|
|
||||||
#if !defined(lint) && !defined(SABER)
|
#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) */
|
#endif /* !defined(lint) && !defined(SABER) */
|
||||||
|
|
||||||
|
static int yylex ();
|
||||||
|
static int yyerror ();
|
||||||
|
|
||||||
#define EPOCH 1970
|
#define EPOCH 1970
|
||||||
#define HOUR(x) ((time_t)(x) * 60)
|
#define HOUR(x) ((time_t)(x) * 60)
|
||||||
@ -202,6 +273,18 @@ date : tUNUMBER '/' tUNUMBER {
|
|||||||
yyDay = $3;
|
yyDay = $3;
|
||||||
yyYear = $5;
|
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 {
|
| tMONTH tUNUMBER {
|
||||||
yyMonth = $1;
|
yyMonth = $1;
|
||||||
yyDay = $2;
|
yyDay = $2;
|
||||||
@ -263,25 +346,24 @@ number : tUNUMBER {
|
|||||||
yyYear = $1;
|
yyYear = $1;
|
||||||
else {
|
else {
|
||||||
if($1>10000) {
|
if($1>10000) {
|
||||||
time_t date_part;
|
|
||||||
|
|
||||||
date_part= $1/10000;
|
|
||||||
yyHaveDate++;
|
yyHaveDate++;
|
||||||
yyDay= (date_part)%100;
|
yyDay= ($1)%100;
|
||||||
yyMonth= (date_part/100)%100;
|
yyMonth= ($1/100)%100;
|
||||||
yyYear = date_part/10000;
|
yyYear = $1/10000;
|
||||||
}
|
|
||||||
yyHaveTime++;
|
|
||||||
if ($1 < 100) {
|
|
||||||
yyHour = $1;
|
|
||||||
yyMinutes = 0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
yyHour = $1 / 100;
|
yyHaveTime++;
|
||||||
yyMinutes = $1 % 100;
|
if ($1 < 100) {
|
||||||
}
|
yyHour = $1;
|
||||||
yySeconds = 0;
|
yyMinutes = 0;
|
||||||
yyMeridian = MER24;
|
}
|
||||||
|
else {
|
||||||
|
yyHour = $1 / 100;
|
||||||
|
yyMinutes = $1 % 100;
|
||||||
|
}
|
||||||
|
yySeconds = 0;
|
||||||
|
yyMeridian = MER24;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -297,7 +379,7 @@ o_merid : /* NULL */ {
|
|||||||
%%
|
%%
|
||||||
|
|
||||||
/* Month and day table. */
|
/* Month and day table. */
|
||||||
static TABLE MonthDayTable[] = {
|
static TABLE const MonthDayTable[] = {
|
||||||
{ "january", tMONTH, 1 },
|
{ "january", tMONTH, 1 },
|
||||||
{ "february", tMONTH, 2 },
|
{ "february", tMONTH, 2 },
|
||||||
{ "march", tMONTH, 3 },
|
{ "march", tMONTH, 3 },
|
||||||
@ -326,7 +408,7 @@ static TABLE MonthDayTable[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Time units table. */
|
/* Time units table. */
|
||||||
static TABLE UnitsTable[] = {
|
static TABLE const UnitsTable[] = {
|
||||||
{ "year", tMONTH_UNIT, 12 },
|
{ "year", tMONTH_UNIT, 12 },
|
||||||
{ "month", tMONTH_UNIT, 1 },
|
{ "month", tMONTH_UNIT, 1 },
|
||||||
{ "fortnight", tMINUTE_UNIT, 14 * 24 * 60 },
|
{ "fortnight", tMINUTE_UNIT, 14 * 24 * 60 },
|
||||||
@ -341,7 +423,7 @@ static TABLE UnitsTable[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Assorted relative-time words. */
|
/* Assorted relative-time words. */
|
||||||
static TABLE OtherTable[] = {
|
static TABLE const OtherTable[] = {
|
||||||
{ "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
|
{ "tomorrow", tMINUTE_UNIT, 1 * 24 * 60 },
|
||||||
{ "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
|
{ "yesterday", tMINUTE_UNIT, -1 * 24 * 60 },
|
||||||
{ "today", tMINUTE_UNIT, 0 },
|
{ "today", tMINUTE_UNIT, 0 },
|
||||||
@ -367,7 +449,7 @@ static TABLE OtherTable[] = {
|
|||||||
|
|
||||||
/* The timezone table. */
|
/* The timezone table. */
|
||||||
/* Some of these are commented out because a time_t can't store a float. */
|
/* 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 */
|
{ "gmt", tZONE, HOUR( 0) }, /* Greenwich Mean */
|
||||||
{ "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
|
{ "ut", tZONE, HOUR( 0) }, /* Universal (Coordinated) */
|
||||||
{ "utc", tZONE, HOUR( 0) },
|
{ "utc", tZONE, HOUR( 0) },
|
||||||
@ -451,7 +533,7 @@ static TABLE TimezoneTable[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/* Military timezone table. */
|
/* Military timezone table. */
|
||||||
static TABLE MilitaryTable[] = {
|
static TABLE const MilitaryTable[] = {
|
||||||
{ "a", tZONE, HOUR( 1) },
|
{ "a", tZONE, HOUR( 1) },
|
||||||
{ "b", tZONE, HOUR( 2) },
|
{ "b", tZONE, HOUR( 2) },
|
||||||
{ "c", tZONE, HOUR( 3) },
|
{ "c", tZONE, HOUR( 3) },
|
||||||
@ -484,7 +566,7 @@ static TABLE MilitaryTable[] = {
|
|||||||
|
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
int
|
static int
|
||||||
yyerror(s)
|
yyerror(s)
|
||||||
char *s;
|
char *s;
|
||||||
{
|
{
|
||||||
@ -514,6 +596,8 @@ ToSeconds(Hours, Minutes, Seconds, Meridian)
|
|||||||
if (Hours < 1 || Hours > 12)
|
if (Hours < 1 || Hours > 12)
|
||||||
return -1;
|
return -1;
|
||||||
return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
|
return ((Hours + 12) * 60L + Minutes) * 60L + Seconds;
|
||||||
|
default:
|
||||||
|
abort ();
|
||||||
}
|
}
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
@ -530,7 +614,7 @@ Convert(Month, Day, Year, Hours, Minutes, Seconds, Meridian, DSTmode)
|
|||||||
MERIDIAN Meridian;
|
MERIDIAN Meridian;
|
||||||
DSTMODE DSTmode;
|
DSTMODE DSTmode;
|
||||||
{
|
{
|
||||||
static int DaysInMonth[12] = {
|
static int DaysInMonth[12] = {
|
||||||
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
||||||
};
|
};
|
||||||
time_t tod;
|
time_t tod;
|
||||||
@ -624,7 +708,7 @@ LookupWord(buff)
|
|||||||
{
|
{
|
||||||
register char *p;
|
register char *p;
|
||||||
register char *q;
|
register char *q;
|
||||||
register TABLE *tp;
|
register const TABLE *tp;
|
||||||
int i;
|
int i;
|
||||||
int abbrev;
|
int abbrev;
|
||||||
|
|
||||||
@ -725,7 +809,7 @@ LookupWord(buff)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
static int
|
||||||
yylex()
|
yylex()
|
||||||
{
|
{
|
||||||
register char c;
|
register char c;
|
||||||
@ -777,48 +861,62 @@ 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
|
time_t
|
||||||
get_date(p, now)
|
get_date(p, now)
|
||||||
char *p;
|
char *p;
|
||||||
struct timeb *now;
|
struct timeb *now;
|
||||||
{
|
{
|
||||||
struct tm *tm;
|
struct tm *tm, gmt;
|
||||||
struct timeb ftz;
|
struct timeb ftz;
|
||||||
time_t Start;
|
time_t Start;
|
||||||
time_t tod;
|
time_t tod;
|
||||||
|
|
||||||
yyInput = p;
|
yyInput = p;
|
||||||
if (now == NULL) {
|
if (now == NULL) {
|
||||||
now = &ftz;
|
now = &ftz;
|
||||||
#if defined(FTIME_MISSING)
|
|
||||||
(void)time(&ftz.time);
|
(void)time(&ftz.time);
|
||||||
/* Set the timezone global. */
|
|
||||||
tzset();
|
if (! (tm = gmtime (&ftz.time)))
|
||||||
#if defined(HAVE_TIMEZONE)
|
return -1;
|
||||||
tm = localtime(&ftz.time);
|
gmt = *tm; /* Make a copy, in case localtime modifies *tm. */
|
||||||
ftz.timezone = tm->tm_gmtoff / 60;
|
|
||||||
#else
|
if (! (tm = localtime (&ftz.time)))
|
||||||
#if defined(timezone)
|
return -1;
|
||||||
ftz.tzone = (int) timezone / 60;
|
|
||||||
#else
|
ftz.timezone = difftm (&gmt, tm) / 60;
|
||||||
ftz.timezone = (int) timezone / 60;
|
if(tm->tm_isdst)
|
||||||
#endif /* defined(timezone) */
|
ftz.timezone += 60;
|
||||||
#endif /* defined(HAVE_TIMEZONE) */
|
|
||||||
#else
|
|
||||||
(void)ftime(&ftz);
|
|
||||||
#endif /* defined(FTIME_MISSING) */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tm = localtime(&now->time);
|
tm = localtime(&now->time);
|
||||||
yyYear = tm->tm_year;
|
yyYear = tm->tm_year;
|
||||||
yyMonth = tm->tm_mon + 1;
|
yyMonth = tm->tm_mon + 1;
|
||||||
yyDay = tm->tm_mday;
|
yyDay = tm->tm_mday;
|
||||||
#if defined(timezone)
|
|
||||||
yyTimezone = now->tzone;
|
|
||||||
#else
|
|
||||||
yyTimezone = now->timezone;
|
yyTimezone = now->timezone;
|
||||||
#endif /* defined(timezone) */
|
|
||||||
yyDSTmode = DSTmaybe;
|
yyDSTmode = DSTmaybe;
|
||||||
yyHour = 0;
|
yyHour = 0;
|
||||||
yyMinutes = 0;
|
yyMinutes = 0;
|
||||||
@ -865,6 +963,7 @@ get_date(p, now)
|
|||||||
#if defined(TEST)
|
#if defined(TEST)
|
||||||
|
|
||||||
/* ARGSUSED */
|
/* ARGSUSED */
|
||||||
|
int
|
||||||
main(ac, av)
|
main(ac, av)
|
||||||
int ac;
|
int ac;
|
||||||
char *av[];
|
char *av[];
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
/* Getopt for GNU.
|
/* Getopt for GNU.
|
||||||
Copyright (C) 1987-1992 Free Software Foundation, Inc.
|
NOTE: getopt is now part of the C library, so if you don't know what
|
||||||
|
"Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
|
||||||
|
before changing it!
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
Copyright (C) 1987, 88, 89, 90, 91, 92, 93, 94
|
||||||
it under the terms of the GNU General Public License as published by
|
Free Software Foundation, Inc.
|
||||||
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,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
@ -13,73 +18,73 @@
|
|||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
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. */
|
||||||
|
|
||||||
#if !__STDC__
|
/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
|
||||||
|
Ditto for AIX 3.2 and <stdlib.h>. */
|
||||||
|
#ifndef _NO_PROTO
|
||||||
|
#define _NO_PROTO
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
#ifndef __STDC__
|
||||||
|
/* This is a separate conditional since some stdc systems
|
||||||
|
reject `defined (const)'. */
|
||||||
|
#ifndef const
|
||||||
#define const
|
#define const
|
||||||
#endif
|
#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__
|
||||||
|
/* Don't include stdlib.h for non-GNU C libraries because some of them
|
||||||
|
contain conflicting prototypes for getopt. */
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif /* GNU C library. */
|
||||||
|
|
||||||
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
/* This version of `getopt' appears to the caller like standard Unix `getopt'
|
||||||
but it behaves differently for the user, since it allows the user
|
but it behaves differently for the user, since it allows the user
|
||||||
to intersperse the options with the other arguments.
|
to intersperse the options with the other arguments.
|
||||||
|
|
||||||
As `getopt' works, it permutes the elements of `argv' so that,
|
As `getopt' works, it permutes the elements of ARGV so that,
|
||||||
when it is done, all the options precede everything else. Thus
|
when it is done, all the options precede everything else. Thus
|
||||||
all application programs are extended to handle flexible argument order.
|
all application programs are extended to handle flexible argument order.
|
||||||
|
|
||||||
Setting the environment variable _POSIX_OPTION_ORDER disables permutation.
|
Setting the environment variable POSIXLY_CORRECT disables permutation.
|
||||||
Then the behavior is completely standard.
|
Then the behavior is completely standard.
|
||||||
|
|
||||||
GNU application programs can use a third alternative mode in which
|
GNU application programs can use a third alternative mode in which
|
||||||
they can distinguish the relative order of options and other arguments. */
|
they can distinguish the relative order of options and other arguments. */
|
||||||
|
|
||||||
#ifndef lint
|
#ifndef lint
|
||||||
static char rcsid[] = "@(#)getopt.c 1.7 92/03/31";
|
static char rcsid[] = "$CVSid: @(#)getopt.c 1.10 94/09/21 $";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include "getopt.h"
|
||||||
|
|
||||||
#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
|
|
||||||
#include <stdlib.h>
|
|
||||||
#else /* STDC_HEADERS or __GNU_LIBRARY__ */
|
|
||||||
char *getenv ();
|
|
||||||
char *malloc ();
|
|
||||||
#endif /* STDC_HEADERS or __GNU_LIBRARY__ */
|
|
||||||
|
|
||||||
/* AIX requires this to be the first thing in the file. */
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#if !defined(bsdi) && !defined(__386BSD__)
|
|
||||||
#define alloca __builtin_alloca
|
|
||||||
#endif
|
|
||||||
#else /* not __GNUC__ */
|
|
||||||
#ifdef sparc
|
|
||||||
#include <alloca.h>
|
|
||||||
#else
|
|
||||||
#ifdef _AIX
|
|
||||||
#pragma alloca
|
|
||||||
#else
|
|
||||||
char *alloca ();
|
|
||||||
#endif
|
|
||||||
#endif /* sparc */
|
|
||||||
#endif /* not __GNUC__ */
|
|
||||||
|
|
||||||
#if defined(USG) || defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
|
|
||||||
#include <string.h>
|
|
||||||
#ifndef bcopy
|
|
||||||
#define bcopy(s, d, n) memcpy ((d), (s), (n))
|
|
||||||
#endif
|
|
||||||
#ifndef index
|
|
||||||
#define index strchr
|
|
||||||
#endif
|
|
||||||
#else /* USG or STDC_HEADERS or __GNU_LIBRARY__ */
|
|
||||||
#ifdef VMS
|
|
||||||
#include <string.h>
|
|
||||||
#else /* VMS */
|
|
||||||
#include <strings.h>
|
|
||||||
#endif /* VMS */
|
|
||||||
/* Declaring bcopy causes errors on systems whose declarations are different.
|
|
||||||
If the declaration is omitted, everything works fine. */
|
|
||||||
#endif /* USG or STDC_HEADERS or __GNU_LIBRARY__ */
|
|
||||||
|
|
||||||
/* For communication from `getopt' to the caller.
|
/* For communication from `getopt' to the caller.
|
||||||
When `getopt' finds an option that takes an argument,
|
When `getopt' finds an option that takes an argument,
|
||||||
@ -87,7 +92,7 @@ char *alloca ();
|
|||||||
Also, when `ordering' is RETURN_IN_ORDER,
|
Also, when `ordering' is RETURN_IN_ORDER,
|
||||||
each non-option ARGV-element is returned here. */
|
each non-option ARGV-element is returned here. */
|
||||||
|
|
||||||
char *optarg = 0;
|
char *optarg = NULL;
|
||||||
|
|
||||||
/* Index in ARGV of the next element to be scanned.
|
/* Index in ARGV of the next element to be scanned.
|
||||||
This is used for communication to and from the caller
|
This is used for communication to and from the caller
|
||||||
@ -101,6 +106,7 @@ char *optarg = 0;
|
|||||||
Otherwise, `optind' communicates from one call to the next
|
Otherwise, `optind' communicates from one call to the next
|
||||||
how much of ARGV has been scanned so far. */
|
how much of ARGV has been scanned so far. */
|
||||||
|
|
||||||
|
/* XXX 1003.2 says this must be 1 before any call. */
|
||||||
int optind = 0;
|
int optind = 0;
|
||||||
|
|
||||||
/* The next char to be scanned in the option-element
|
/* The next char to be scanned in the option-element
|
||||||
@ -117,17 +123,23 @@ static char *nextchar;
|
|||||||
|
|
||||||
int opterr = 1;
|
int opterr = 1;
|
||||||
|
|
||||||
|
/* Set to an option character which was unrecognized.
|
||||||
|
This must be initialized on some systems to avoid linking in the
|
||||||
|
system's own getopt implementation. */
|
||||||
|
|
||||||
|
int optopt = '?';
|
||||||
|
|
||||||
/* Describe how to deal with options that follow non-option ARGV-elements.
|
/* Describe how to deal with options that follow non-option ARGV-elements.
|
||||||
|
|
||||||
If the caller did not specify anything,
|
If the caller did not specify anything,
|
||||||
the default is REQUIRE_ORDER if the environment variable
|
the default is REQUIRE_ORDER if the environment variable
|
||||||
_POSIX_OPTION_ORDER is defined, PERMUTE otherwise.
|
POSIXLY_CORRECT is defined, PERMUTE otherwise.
|
||||||
|
|
||||||
REQUIRE_ORDER means don't recognize them as options;
|
REQUIRE_ORDER means don't recognize them as options;
|
||||||
stop option processing when the first non-option is seen.
|
stop option processing when the first non-option is seen.
|
||||||
This is what Unix does.
|
This is what Unix does.
|
||||||
This mode of operation is selected by either setting the environment
|
This mode of operation is selected by either setting the environment
|
||||||
variable POSIX_ME_HARDER, or using `+' as the first character
|
variable POSIXLY_CORRECT, or using `+' as the first character
|
||||||
of the list of option characters.
|
of the list of option characters.
|
||||||
|
|
||||||
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
PERMUTE is the default. We permute the contents of ARGV as we scan,
|
||||||
@ -151,28 +163,50 @@ static enum
|
|||||||
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
|
||||||
} ordering;
|
} ordering;
|
||||||
|
|
||||||
/* Describe the long-named options requested by the application.
|
/* Value of POSIXLY_CORRECT environment variable. */
|
||||||
_GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an
|
static char *posixly_correct;
|
||||||
element containing a name which is zero.
|
|
||||||
The field `has_arg' is 1 if the option takes an argument,
|
#ifdef __GNU_LIBRARY__
|
||||||
2 if it takes an optional argument. */
|
/* We want to avoid inclusion of string.h with non-GNU libraries
|
||||||
|
because there are many ways it can cause trouble.
|
||||||
|
On some systems, it contains special magic macros that don't work
|
||||||
|
in GCC. */
|
||||||
|
#include <string.h>
|
||||||
|
#define my_index strchr
|
||||||
|
#else
|
||||||
|
|
||||||
struct option
|
/* Avoid depending on library functions or files
|
||||||
|
whose names are inconsistent. */
|
||||||
|
|
||||||
|
char *getenv ();
|
||||||
|
|
||||||
|
static char *
|
||||||
|
my_index (str, chr)
|
||||||
|
const char *str;
|
||||||
|
int chr;
|
||||||
{
|
{
|
||||||
char *name;
|
while (*str)
|
||||||
int has_arg;
|
{
|
||||||
int *flag;
|
if (*str == chr)
|
||||||
int val;
|
return (char *) str;
|
||||||
};
|
str++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const struct option *_getopt_long_options;
|
/* If using GCC, we can safely declare strlen this way.
|
||||||
|
If not using GCC, it is ok not to declare it. */
|
||||||
|
#ifdef __GNUC__
|
||||||
|
/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
|
||||||
|
That was relevant to code that was here before. */
|
||||||
|
#ifndef __STDC__
|
||||||
|
/* gcc with -traditional declares the built-in strlen to return int,
|
||||||
|
and has done so at least since version 2.4.5. -- rms. */
|
||||||
|
extern int strlen (const char *);
|
||||||
|
#endif /* not __STDC__ */
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
int _getopt_long_only = 0;
|
#endif /* not __GNU_LIBRARY__ */
|
||||||
|
|
||||||
/* Index in _GETOPT_LONG_OPTIONS of the long-named option actually found.
|
|
||||||
Only valid when a long-named option was found. */
|
|
||||||
|
|
||||||
int option_index;
|
|
||||||
|
|
||||||
/* Handle permutation of arguments. */
|
/* Handle permutation of arguments. */
|
||||||
|
|
||||||
@ -185,32 +219,104 @@ static int last_nonopt;
|
|||||||
|
|
||||||
/* Exchange two adjacent subsequences of ARGV.
|
/* Exchange two adjacent subsequences of ARGV.
|
||||||
One subsequence is elements [first_nonopt,last_nonopt)
|
One subsequence is elements [first_nonopt,last_nonopt)
|
||||||
which contains all the non-options that have been skipped so far.
|
which contains all the non-options that have been skipped so far.
|
||||||
The other is elements [last_nonopt,optind), which contains all
|
The other is elements [last_nonopt,optind), which contains all
|
||||||
the options processed since those non-options were skipped.
|
the options processed since those non-options were skipped.
|
||||||
|
|
||||||
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
`first_nonopt' and `last_nonopt' are relocated so that they describe
|
||||||
the new indices of the non-options in ARGV after they are moved. */
|
the new indices of the non-options in ARGV after they are moved. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
exchange (argv)
|
exchange (argv)
|
||||||
char **argv;
|
char **argv;
|
||||||
{
|
{
|
||||||
int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *);
|
int bottom = first_nonopt;
|
||||||
char **temp = (char **) alloca (nonopts_size);
|
int middle = last_nonopt;
|
||||||
|
int top = optind;
|
||||||
|
char *tem;
|
||||||
|
|
||||||
/* Interchange the two blocks of data in ARGV. */
|
/* Exchange the shorter segment with the far end of the longer segment.
|
||||||
|
That puts the shorter segment into the right place.
|
||||||
|
It leaves the longer segment in the right place overall,
|
||||||
|
but it consists of two parts that need to be swapped next. */
|
||||||
|
|
||||||
bcopy (&argv[first_nonopt], temp, nonopts_size);
|
while (top > middle && middle > bottom)
|
||||||
bcopy (&argv[last_nonopt], &argv[first_nonopt],
|
{
|
||||||
(optind - last_nonopt) * sizeof (char *));
|
if (top - middle > middle - bottom)
|
||||||
bcopy (temp, &argv[first_nonopt + optind - last_nonopt], nonopts_size);
|
{
|
||||||
|
/* Bottom segment is the short one. */
|
||||||
|
int len = middle - bottom;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
/* Swap it with the top part of the top segment. */
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
tem = argv[bottom + i];
|
||||||
|
argv[bottom + i] = argv[top - (middle - bottom) + i];
|
||||||
|
argv[top - (middle - bottom) + i] = tem;
|
||||||
|
}
|
||||||
|
/* Exclude the moved bottom segment from further swapping. */
|
||||||
|
top -= len;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Top segment is the short one. */
|
||||||
|
int len = top - middle;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
/* Swap it with the bottom part of the bottom segment. */
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
tem = argv[bottom + i];
|
||||||
|
argv[bottom + i] = argv[middle + i];
|
||||||
|
argv[middle + i] = tem;
|
||||||
|
}
|
||||||
|
/* Exclude the moved top segment from further swapping. */
|
||||||
|
bottom += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Update records for the slots the non-options now occupy. */
|
/* Update records for the slots the non-options now occupy. */
|
||||||
|
|
||||||
first_nonopt += (optind - last_nonopt);
|
first_nonopt += (optind - last_nonopt);
|
||||||
last_nonopt = optind;
|
last_nonopt = optind;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the internal data when the first call is made. */
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
_getopt_initialize (optstring)
|
||||||
|
const char *optstring;
|
||||||
|
{
|
||||||
|
/* Start processing options with ARGV-element 1 (since ARGV-element 0
|
||||||
|
is the program name); the sequence of previously skipped
|
||||||
|
non-option ARGV-elements is empty. */
|
||||||
|
|
||||||
|
first_nonopt = last_nonopt = optind = 1;
|
||||||
|
|
||||||
|
nextchar = NULL;
|
||||||
|
|
||||||
|
posixly_correct = getenv ("POSIXLY_CORRECT");
|
||||||
|
|
||||||
|
/* Determine how to handle the ordering of options and nonoptions. */
|
||||||
|
|
||||||
|
if (optstring[0] == '-')
|
||||||
|
{
|
||||||
|
ordering = RETURN_IN_ORDER;
|
||||||
|
++optstring;
|
||||||
|
}
|
||||||
|
else if (optstring[0] == '+')
|
||||||
|
{
|
||||||
|
ordering = REQUIRE_ORDER;
|
||||||
|
++optstring;
|
||||||
|
}
|
||||||
|
else if (posixly_correct != NULL)
|
||||||
|
ordering = REQUIRE_ORDER;
|
||||||
|
else
|
||||||
|
ordering = PERMUTE;
|
||||||
|
|
||||||
|
return optstring;
|
||||||
|
}
|
||||||
|
|
||||||
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
/* Scan elements of ARGV (whose length is ARGC) for option characters
|
||||||
given in OPTSTRING.
|
given in OPTSTRING.
|
||||||
@ -245,78 +351,67 @@ exchange (argv)
|
|||||||
handling the non-option ARGV-elements.
|
handling the non-option ARGV-elements.
|
||||||
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
|
||||||
|
|
||||||
Long-named options begin with `+' instead of `-'.
|
Long-named options begin with `--' instead of `-'.
|
||||||
Their names may be abbreviated as long as the abbreviation is unique
|
Their names may be abbreviated as long as the abbreviation is unique
|
||||||
or is an exact match for some defined option. If they have an
|
or is an exact match for some defined option. If they have an
|
||||||
argument, it follows the option name in the same ARGV-element, separated
|
argument, it follows the option name in the same ARGV-element, separated
|
||||||
from the option name by a `=', or else the in next ARGV-element.
|
from the option name by a `=', or else the in next ARGV-element.
|
||||||
When `getopt' finds a long-named option, it returns 0 if that option's
|
When `getopt' finds a long-named option, it returns 0 if that option's
|
||||||
`flag' field is nonzero, the value of the option's `val' field
|
`flag' field is nonzero, the value of the option's `val' field
|
||||||
otherwise. */
|
if the `flag' field is zero.
|
||||||
|
|
||||||
|
The elements of ARGV aren't really const, because we permute them.
|
||||||
|
But we pretend they're const in the prototype to be compatible
|
||||||
|
with other systems.
|
||||||
|
|
||||||
|
LONGOPTS is a vector of `struct option' terminated by an
|
||||||
|
element containing a name which is zero.
|
||||||
|
|
||||||
|
LONGIND returns the index in LONGOPT of the long-named option found.
|
||||||
|
It is only valid when a long-named option has been found by the most
|
||||||
|
recent call.
|
||||||
|
|
||||||
|
If LONG_ONLY is nonzero, '-' as well as '--' can introduce
|
||||||
|
long-named options. */
|
||||||
|
|
||||||
int
|
int
|
||||||
gnu_getopt (argc, argv, optstring)
|
_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char *const *argv;
|
||||||
const char *optstring;
|
const char *optstring;
|
||||||
|
const struct option *longopts;
|
||||||
|
int *longind;
|
||||||
|
int long_only;
|
||||||
{
|
{
|
||||||
optarg = 0;
|
optarg = NULL;
|
||||||
|
|
||||||
/* Initialize the internal data when the first call is made.
|
|
||||||
Start processing options with ARGV-element 1 (since ARGV-element 0
|
|
||||||
is the program name); the sequence of previously skipped
|
|
||||||
non-option ARGV-elements is empty. */
|
|
||||||
|
|
||||||
if (optind == 0)
|
if (optind == 0)
|
||||||
|
optstring = _getopt_initialize (optstring);
|
||||||
|
|
||||||
|
if (nextchar == NULL || *nextchar == '\0')
|
||||||
{
|
{
|
||||||
first_nonopt = last_nonopt = optind = 1;
|
/* Advance to the next ARGV-element. */
|
||||||
|
|
||||||
nextchar = 0;
|
|
||||||
|
|
||||||
/* Determine how to handle the ordering of options and nonoptions. */
|
|
||||||
|
|
||||||
if (optstring[0] == '-')
|
|
||||||
{
|
|
||||||
ordering = RETURN_IN_ORDER;
|
|
||||||
++optstring;
|
|
||||||
}
|
|
||||||
else if (optstring[0] == '+')
|
|
||||||
{
|
|
||||||
ordering = REQUIRE_ORDER;
|
|
||||||
++optstring;
|
|
||||||
}
|
|
||||||
else if (getenv ("POSIX_ME_HARDER") != 0)
|
|
||||||
ordering = REQUIRE_ORDER;
|
|
||||||
else
|
|
||||||
ordering = PERMUTE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nextchar == 0 || *nextchar == 0)
|
|
||||||
{
|
|
||||||
if (ordering == PERMUTE)
|
if (ordering == PERMUTE)
|
||||||
{
|
{
|
||||||
/* If we have just processed some options following some non-options,
|
/* If we have just processed some options following some non-options,
|
||||||
exchange them so that the options come first. */
|
exchange them so that the options come first. */
|
||||||
|
|
||||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||||
exchange (argv);
|
exchange ((char **) argv);
|
||||||
else if (last_nonopt != optind)
|
else if (last_nonopt != optind)
|
||||||
first_nonopt = optind;
|
first_nonopt = optind;
|
||||||
|
|
||||||
/* Now skip any additional non-options
|
/* Skip any additional non-options
|
||||||
and extend the range of non-options previously skipped. */
|
and extend the range of non-options previously skipped. */
|
||||||
|
|
||||||
while (optind < argc
|
while (optind < argc
|
||||||
&& (argv[optind][0] != '-'
|
&& (argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||||
|| argv[optind][1] == 0)
|
|
||||||
&& (_getopt_long_options == 0
|
|
||||||
|| argv[optind][0] != '+'
|
|
||||||
|| argv[optind][1] == 0))
|
|
||||||
optind++;
|
optind++;
|
||||||
last_nonopt = optind;
|
last_nonopt = optind;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special ARGV-element `--' means premature end of options.
|
/* The special ARGV-element `--' means premature end of options.
|
||||||
Skip it like a null option,
|
Skip it like a null option,
|
||||||
then exchange with previous non-options as if it were an option,
|
then exchange with previous non-options as if it were an option,
|
||||||
then skip everything else like a non-option. */
|
then skip everything else like a non-option. */
|
||||||
@ -326,7 +421,7 @@ gnu_getopt (argc, argv, optstring)
|
|||||||
optind++;
|
optind++;
|
||||||
|
|
||||||
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
if (first_nonopt != last_nonopt && last_nonopt != optind)
|
||||||
exchange (argv);
|
exchange ((char **) argv);
|
||||||
else if (first_nonopt == last_nonopt)
|
else if (first_nonopt == last_nonopt)
|
||||||
first_nonopt = optind;
|
first_nonopt = optind;
|
||||||
last_nonopt = argc;
|
last_nonopt = argc;
|
||||||
@ -349,9 +444,7 @@ gnu_getopt (argc, argv, optstring)
|
|||||||
/* If we have come to a non-option and did not permute it,
|
/* If we have come to a non-option and did not permute it,
|
||||||
either stop the scan or describe it to the caller and pass it by. */
|
either stop the scan or describe it to the caller and pass it by. */
|
||||||
|
|
||||||
if ((argv[optind][0] != '-' || argv[optind][1] == 0)
|
if ((argv[optind][0] != '-' || argv[optind][1] == '\0'))
|
||||||
&& (_getopt_long_options == 0
|
|
||||||
|| argv[optind][0] != '+' || argv[optind][1] == 0))
|
|
||||||
{
|
{
|
||||||
if (ordering == REQUIRE_ORDER)
|
if (ordering == REQUIRE_ORDER)
|
||||||
return EOF;
|
return EOF;
|
||||||
@ -360,32 +453,48 @@ gnu_getopt (argc, argv, optstring)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We have found another option-ARGV-element.
|
/* We have found another option-ARGV-element.
|
||||||
Start decoding its characters. */
|
Skip the initial punctuation. */
|
||||||
|
|
||||||
nextchar = argv[optind] + 1;
|
nextchar = (argv[optind] + 1
|
||||||
|
+ (longopts != NULL && argv[optind][1] == '-'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_getopt_long_options != 0
|
/* Decode the current option-ARGV-element. */
|
||||||
&& (argv[optind][0] == '+'
|
|
||||||
|| (_getopt_long_only && argv[optind][0] == '-'))
|
/* Check whether the ARGV-element is a long option.
|
||||||
)
|
|
||||||
|
If long_only and the ARGV-element has the form "-f", where f is
|
||||||
|
a valid short option, don't consider it an abbreviated form of
|
||||||
|
a long option that starts with f. Otherwise there would be no
|
||||||
|
way to give the -f short option.
|
||||||
|
|
||||||
|
On the other hand, if there's a long option "fubar" and
|
||||||
|
the ARGV-element is "-fu", do consider that an abbreviation of
|
||||||
|
the long option, just like "--fu", and not "-f" with arg "u".
|
||||||
|
|
||||||
|
This distinction seems to be the most useful approach. */
|
||||||
|
|
||||||
|
if (longopts != NULL
|
||||||
|
&& (argv[optind][1] == '-'
|
||||||
|
|| (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
|
||||||
{
|
{
|
||||||
|
char *nameend;
|
||||||
const struct option *p;
|
const struct option *p;
|
||||||
char *s = nextchar;
|
const struct option *pfound = NULL;
|
||||||
int exact = 0;
|
int exact = 0;
|
||||||
int ambig = 0;
|
int ambig = 0;
|
||||||
const struct option *pfound = 0;
|
int indfound;
|
||||||
int indfound = 0;
|
int option_index;
|
||||||
|
|
||||||
while (*s && *s != '=')
|
for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
|
||||||
s++;
|
/* Do nothing. */ ;
|
||||||
|
|
||||||
/* Test all options for either exact match or abbreviated matches. */
|
/* Test all long options for either exact match
|
||||||
for (p = _getopt_long_options, option_index = 0; p->name;
|
or abbreviated matches. */
|
||||||
p++, option_index++)
|
for (p = longopts, option_index = 0; p->name; p++, option_index++)
|
||||||
if (!strncmp (p->name, nextchar, s - nextchar))
|
if (!strncmp (p->name, nextchar, nameend - nextchar))
|
||||||
{
|
{
|
||||||
if (s - nextchar == strlen (p->name))
|
if (nameend - nextchar == strlen (p->name))
|
||||||
{
|
{
|
||||||
/* Exact match found. */
|
/* Exact match found. */
|
||||||
pfound = p;
|
pfound = p;
|
||||||
@ -393,39 +502,52 @@ gnu_getopt (argc, argv, optstring)
|
|||||||
exact = 1;
|
exact = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (pfound == 0)
|
else if (pfound == NULL)
|
||||||
{
|
{
|
||||||
/* First nonexact match found. */
|
/* First nonexact match found. */
|
||||||
pfound = p;
|
pfound = p;
|
||||||
indfound = option_index;
|
indfound = option_index;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* Second nonexact match found. */
|
/* Second or later nonexact match found. */
|
||||||
ambig = 1;
|
ambig = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ambig && !exact)
|
if (ambig && !exact)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
if (opterr)
|
||||||
argv[0], argv[optind]);
|
fprintf (stderr, "%s: option `%s' is ambiguous\n",
|
||||||
|
argv[0], argv[optind]);
|
||||||
nextchar += strlen (nextchar);
|
nextchar += strlen (nextchar);
|
||||||
optind++;
|
optind++;
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pfound != 0)
|
if (pfound != NULL)
|
||||||
{
|
{
|
||||||
option_index = indfound;
|
option_index = indfound;
|
||||||
optind++;
|
optind++;
|
||||||
if (*s)
|
if (*nameend)
|
||||||
{
|
{
|
||||||
if (pfound->has_arg > 0)
|
/* Don't test has_arg with >, because some C compilers don't
|
||||||
optarg = s + 1;
|
allow it to be used on enums. */
|
||||||
|
if (pfound->has_arg)
|
||||||
|
optarg = nameend + 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf (stderr,
|
if (opterr)
|
||||||
"%s: option `%c%s' doesn't allow an argument\n",
|
{
|
||||||
argv[0], argv[optind - 1][0], pfound->name);
|
if (argv[optind - 1][1] == '-')
|
||||||
|
/* --option */
|
||||||
|
fprintf (stderr,
|
||||||
|
"%s: option `--%s' doesn't allow an argument\n",
|
||||||
|
argv[0], pfound->name);
|
||||||
|
else
|
||||||
|
/* +option or -option */
|
||||||
|
fprintf (stderr,
|
||||||
|
"%s: option `%c%s' doesn't allow an argument\n",
|
||||||
|
argv[0], argv[optind - 1][0], pfound->name);
|
||||||
|
}
|
||||||
nextchar += strlen (nextchar);
|
nextchar += strlen (nextchar);
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
@ -436,13 +558,16 @@ gnu_getopt (argc, argv, optstring)
|
|||||||
optarg = argv[optind++];
|
optarg = argv[optind++];
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
if (opterr)
|
||||||
argv[0], argv[optind - 1]);
|
fprintf (stderr, "%s: option `%s' requires an argument\n",
|
||||||
|
argv[0], argv[optind - 1]);
|
||||||
nextchar += strlen (nextchar);
|
nextchar += strlen (nextchar);
|
||||||
return '?';
|
return optstring[0] == ':' ? ':' : '?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nextchar += strlen (nextchar);
|
nextchar += strlen (nextchar);
|
||||||
|
if (longind != NULL)
|
||||||
|
*longind = option_index;
|
||||||
if (pfound->flag)
|
if (pfound->flag)
|
||||||
{
|
{
|
||||||
*(pfound->flag) = pfound->val;
|
*(pfound->flag) = pfound->val;
|
||||||
@ -450,43 +575,52 @@ gnu_getopt (argc, argv, optstring)
|
|||||||
}
|
}
|
||||||
return pfound->val;
|
return pfound->val;
|
||||||
}
|
}
|
||||||
/* Can't find it as a long option. If this is getopt_long_only,
|
|
||||||
and the option starts with '-' and is a valid short
|
/* Can't find it as a long option. If this is not getopt_long_only,
|
||||||
option, then interpret it as a short option. Otherwise it's
|
or the option starts with '--' or is not a valid short
|
||||||
an error. */
|
option, then it's an error.
|
||||||
if (_getopt_long_only == 0 || argv[optind][0] == '+' ||
|
Otherwise interpret it as a short option. */
|
||||||
index (optstring, *nextchar) == 0)
|
if (!long_only || argv[optind][1] == '-'
|
||||||
|
|| my_index (optstring, *nextchar) == NULL)
|
||||||
{
|
{
|
||||||
if (opterr != 0)
|
if (opterr)
|
||||||
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
{
|
||||||
argv[0], argv[optind][0], nextchar);
|
if (argv[optind][1] == '-')
|
||||||
nextchar += strlen (nextchar);
|
/* --option */
|
||||||
|
fprintf (stderr, "%s: unrecognized option `--%s'\n",
|
||||||
|
argv[0], nextchar);
|
||||||
|
else
|
||||||
|
/* +option or -option */
|
||||||
|
fprintf (stderr, "%s: unrecognized option `%c%s'\n",
|
||||||
|
argv[0], argv[optind][0], nextchar);
|
||||||
|
}
|
||||||
|
nextchar = (char *) "";
|
||||||
optind++;
|
optind++;
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Look at and handle the next option-character. */
|
/* Look at and handle the next short option-character. */
|
||||||
|
|
||||||
{
|
{
|
||||||
char c = *nextchar++;
|
char c = *nextchar++;
|
||||||
char *temp = index (optstring, c);
|
char *temp = my_index (optstring, c);
|
||||||
|
|
||||||
/* Increment `optind' when we start to process its last character. */
|
/* Increment `optind' when we start to process its last character. */
|
||||||
if (*nextchar == 0)
|
if (*nextchar == '\0')
|
||||||
optind++;
|
++optind;
|
||||||
|
|
||||||
if (temp == 0 || c == ':')
|
if (temp == NULL || c == ':')
|
||||||
{
|
{
|
||||||
if (opterr != 0)
|
if (opterr)
|
||||||
{
|
{
|
||||||
if (c < 040 || c >= 0177)
|
if (posixly_correct)
|
||||||
fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
|
/* 1003.2 specifies the format of this message. */
|
||||||
argv[0], c);
|
fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
|
||||||
else
|
else
|
||||||
fprintf (stderr, "%s: unrecognized option `-%c'\n",
|
fprintf (stderr, "%s: invalid option -- %c\n", argv[0], c);
|
||||||
argv[0], c);
|
|
||||||
}
|
}
|
||||||
|
optopt = c;
|
||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
if (temp[1] == ':')
|
if (temp[1] == ':')
|
||||||
@ -494,19 +628,19 @@ gnu_getopt (argc, argv, optstring)
|
|||||||
if (temp[2] == ':')
|
if (temp[2] == ':')
|
||||||
{
|
{
|
||||||
/* This is an option that accepts an argument optionally. */
|
/* This is an option that accepts an argument optionally. */
|
||||||
if (*nextchar != 0)
|
if (*nextchar != '\0')
|
||||||
{
|
{
|
||||||
optarg = nextchar;
|
optarg = nextchar;
|
||||||
optind++;
|
optind++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
optarg = 0;
|
optarg = NULL;
|
||||||
nextchar = 0;
|
nextchar = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This is an option that requires an argument. */
|
/* This is an option that requires an argument. */
|
||||||
if (*nextchar != 0)
|
if (*nextchar != '\0')
|
||||||
{
|
{
|
||||||
optarg = nextchar;
|
optarg = nextchar;
|
||||||
/* If we end this ARGV-element by taking the rest as an arg,
|
/* If we end this ARGV-element by taking the rest as an arg,
|
||||||
@ -515,21 +649,42 @@ gnu_getopt (argc, argv, optstring)
|
|||||||
}
|
}
|
||||||
else if (optind == argc)
|
else if (optind == argc)
|
||||||
{
|
{
|
||||||
if (opterr != 0)
|
if (opterr)
|
||||||
fprintf (stderr, "%s: option `-%c' requires an argument\n",
|
{
|
||||||
argv[0], c);
|
/* 1003.2 specifies the format of this message. */
|
||||||
c = '?';
|
fprintf (stderr, "%s: option requires an argument -- %c\n",
|
||||||
|
argv[0], c);
|
||||||
|
}
|
||||||
|
optopt = c;
|
||||||
|
if (optstring[0] == ':')
|
||||||
|
c = ':';
|
||||||
|
else
|
||||||
|
c = '?';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* We already incremented `optind' once;
|
/* We already incremented `optind' once;
|
||||||
increment it again when taking next ARGV-elt as argument. */
|
increment it again when taking next ARGV-elt as argument. */
|
||||||
optarg = argv[optind++];
|
optarg = argv[optind++];
|
||||||
nextchar = 0;
|
nextchar = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getopt (argc, argv, optstring)
|
||||||
|
int argc;
|
||||||
|
char *const *argv;
|
||||||
|
const char *optstring;
|
||||||
|
{
|
||||||
|
return _getopt_internal (argc, argv, optstring,
|
||||||
|
(const struct option *) 0,
|
||||||
|
(int *) 0,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
|
||||||
@ -548,7 +703,7 @@ main (argc, argv)
|
|||||||
{
|
{
|
||||||
int this_option_optind = optind ? optind : 1;
|
int this_option_optind = optind ? optind : 1;
|
||||||
|
|
||||||
c = gnu_getopt (argc, argv, "abc:d:0123456789");
|
c = getopt (argc, argv, "abc:d:0123456789");
|
||||||
if (c == EOF)
|
if (c == EOF)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
/* declarations for getopt
|
/* Declarations for getopt.
|
||||||
Copyright (C) 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
|
Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify it
|
||||||
it under the terms of the GNU General Public License as published by
|
under the terms of the GNU General Public License as published by the
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
any later version.
|
later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
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
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
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.
|
/* For communication from `getopt' to the caller.
|
||||||
When `getopt' finds an option that takes an argument,
|
When `getopt' finds an option that takes an argument,
|
||||||
@ -44,16 +51,21 @@ extern int optind;
|
|||||||
|
|
||||||
extern int opterr;
|
extern int opterr;
|
||||||
|
|
||||||
|
/* Set to an option character which was unrecognized. */
|
||||||
|
|
||||||
|
extern int optopt;
|
||||||
|
|
||||||
/* Describe the long-named options requested by the application.
|
/* Describe the long-named options requested by the application.
|
||||||
_GETOPT_LONG_OPTIONS is a vector of `struct option' terminated by an
|
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
|
||||||
element containing a name which is zero.
|
of `struct option' terminated by an element containing a name which is
|
||||||
|
zero.
|
||||||
|
|
||||||
The field `has_arg' is:
|
The field `has_arg' is:
|
||||||
0 if the option does not take an argument,
|
no_argument (or 0) if the option does not take an argument,
|
||||||
1 if the option requires an argument,
|
required_argument (or 1) if the option requires an argument,
|
||||||
2 if the option takes an optional 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
|
to the value given in the field `val' when the option is found, but
|
||||||
left unchanged if the option is not found.
|
left unchanged if the option is not found.
|
||||||
|
|
||||||
@ -66,37 +78,54 @@ extern int opterr;
|
|||||||
|
|
||||||
struct option
|
struct option
|
||||||
{
|
{
|
||||||
|
#if __STDC__
|
||||||
|
const char *name;
|
||||||
|
#else
|
||||||
char *name;
|
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 has_arg;
|
||||||
int *flag;
|
int *flag;
|
||||||
int val;
|
int val;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if __STDC__
|
/* Names for the values of the `has_arg' field of `struct option'. */
|
||||||
extern const struct option *_getopt_long_options;
|
|
||||||
#else
|
|
||||||
extern struct option *_getopt_long_options;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* If nonzero, '-' can introduce long-named options.
|
#define no_argument 0
|
||||||
Set by getopt_long_only. */
|
#define required_argument 1
|
||||||
|
#define optional_argument 2
|
||||||
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;
|
|
||||||
|
|
||||||
#if __STDC__
|
#if __STDC__
|
||||||
int gnu_getopt (int argc, char **argv, const char *shortopts);
|
#if defined(__GNU_LIBRARY__)
|
||||||
int gnu_getopt_long (int argc, char **argv, const char *shortopts,
|
/* Many other libraries have conflicting prototypes for getopt, with
|
||||||
const struct option *longopts, int *longind);
|
differences in the consts, in stdlib.h. To avoid compilation
|
||||||
int gnu_getopt_long_only (int argc, char **argv, const char *shortopts,
|
errors, only prototype getopt for the GNU C library. */
|
||||||
const struct option *longopts, int *longind);
|
extern int getopt (int argc, char *const *argv, const char *shortopts);
|
||||||
#else
|
#else /* not __GNU_LIBRARY__ */
|
||||||
int gnu_getopt ();
|
extern int getopt ();
|
||||||
int gnu_getopt_long ();
|
#endif /* not __GNU_LIBRARY__ */
|
||||||
int gnu_getopt_long_only ();
|
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind);
|
||||||
|
extern int getopt_long_only (int argc, char *const *argv,
|
||||||
|
const char *shortopts,
|
||||||
|
const struct option *longopts, int *longind);
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
#endif /* _GETOPT_H */
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
/* Getopt for GNU.
|
/* getopt_long and getopt_long_only entry points for GNU getopt.
|
||||||
Copyright (C) 1987-1992 Free Software Foundation, Inc.
|
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
|
This program is free software; you can redistribute it and/or modify it
|
||||||
it under the terms of the GNU General Public License as published by
|
under the terms of the GNU General Public License as published by the
|
||||||
the Free Software Foundation; either version 2, or (at your option)
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
any later version.
|
later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
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
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
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"
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#if defined (emacs) || defined (CONFIG_BROKETS)
|
||||||
#if !__STDC__
|
/* We use <config.h> instead of "config.h" so that a compilation
|
||||||
#define const
|
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
|
#endif
|
||||||
|
|
||||||
#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
|
#include "getopt.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#else /* STDC_HEADERS or __GNU_LIBRARY__ */
|
|
||||||
char *getenv ();
|
|
||||||
#endif /* STDC_HEADERS or __GNU_LIBRARY__ */
|
|
||||||
|
|
||||||
#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
|
#define NULL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
gnu_getopt_long (argc, argv, options, long_options, opt_index)
|
getopt_long (argc, argv, options, long_options, opt_index)
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char *const *argv;
|
||||||
const char *options;
|
const char *options;
|
||||||
const struct option *long_options;
|
const struct option *long_options;
|
||||||
int *opt_index;
|
int *opt_index;
|
||||||
{
|
{
|
||||||
int val;
|
return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Like getopt_long, but '-' as well as '+' can indicate a long option.
|
/* Like getopt_long, but '-' as well as '--' can indicate a long option.
|
||||||
If an option that starts with '-' doesn't match 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
|
but does match a short option, it is parsed as a short option
|
||||||
instead. */
|
instead. */
|
||||||
|
|
||||||
int
|
int
|
||||||
gnu_getopt_long_only (argc, argv, options, long_options, opt_index)
|
getopt_long_only (argc, argv, options, long_options, opt_index)
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char *const *argv;
|
||||||
const char *options;
|
const char *options;
|
||||||
const struct option *long_options;
|
const struct option *long_options;
|
||||||
int *opt_index;
|
int *opt_index;
|
||||||
{
|
{
|
||||||
int val;
|
return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
|
||||||
|
|
||||||
_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _LIBC or not __GNU_LIBRARY__. */
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -89,7 +107,6 @@ main (argc, argv)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
int this_option_optind = optind ? optind : 1;
|
int this_option_optind = optind ? optind : 1;
|
||||||
char *name = '\0';
|
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
static struct option long_options[] =
|
static struct option long_options[] =
|
||||||
{
|
{
|
||||||
@ -110,7 +127,7 @@ main (argc, argv)
|
|||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
printf ("option %s", (long_options[option_index]).name);
|
printf ("option %s", long_options[option_index].name);
|
||||||
if (optarg)
|
if (optarg)
|
||||||
printf (" with arg %s", optarg);
|
printf (" with arg %s", optarg);
|
||||||
printf ("\n");
|
printf ("\n");
|
||||||
@ -144,6 +161,10 @@ main (argc, argv)
|
|||||||
printf ("option c with value `%s'\n", optarg);
|
printf ("option c with value `%s'\n", optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
printf ("option d with value `%s'\n", optarg);
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
of getwd() which is much faster than getcwd(). As a result, we use the
|
of getwd() which is much faster than getcwd(). As a result, we use the
|
||||||
system's getwd() if it is available */
|
system's getwd() if it is available */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
/* Get the current working directory into PATHNAME */
|
/* Get the current working directory into PATHNAME */
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
* Polk's hash list manager. So cool.
|
||||||
*/
|
*/
|
||||||
@ -10,31 +10,32 @@
|
|||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
/* global caches */
|
/* global caches */
|
||||||
static List *listcache = NULL;
|
static List *listcache = NULL;
|
||||||
static Node *nodecache = NULL;
|
static Node *nodecache = NULL;
|
||||||
|
|
||||||
#if __STDC__
|
static void freenode_mem PROTO((Node * p));
|
||||||
static void freenode_mem (Node * p);
|
|
||||||
#else
|
|
||||||
static void freenode_mem ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
/* hash function */
|
/* hash function */
|
||||||
static int
|
static int
|
||||||
hashp (key)
|
hashp (key)
|
||||||
char *key;
|
char *key;
|
||||||
{
|
{
|
||||||
register char *p;
|
unsigned int h = 0;
|
||||||
register int n = 0;
|
unsigned int g;
|
||||||
|
|
||||||
for (p = key; *p; p++)
|
while (*key != 0)
|
||||||
n += *p;
|
{
|
||||||
|
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 */
|
/* make a new list from scratch */
|
||||||
list = (List *) xmalloc (sizeof (List));
|
list = (List *) xmalloc (sizeof (List));
|
||||||
bzero ((char *) list, sizeof (List));
|
memset ((char *) list, 0, sizeof (List));
|
||||||
node = getnode ();
|
node = getnode ();
|
||||||
list->list = node;
|
list->list = node;
|
||||||
node->type = HEADER;
|
node->type = HEADER;
|
||||||
@ -130,7 +131,7 @@ getnode ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* always make it clean */
|
/* always make it clean */
|
||||||
bzero ((char *) p, sizeof (Node));
|
memset ((char *) p, 0, sizeof (Node));
|
||||||
p->type = UNKNOWN;
|
p->type = UNKNOWN;
|
||||||
|
|
||||||
return (p);
|
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 *
|
Node *
|
||||||
findnode (list, key)
|
findnode (list, key)
|
||||||
@ -273,9 +275,10 @@ findnode (list, key)
|
|||||||
* walk a list with a specific proc
|
* walk a list with a specific proc
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
walklist (list, proc)
|
walklist (list, proc, closure)
|
||||||
List *list;
|
List *list;
|
||||||
int (*proc) ();
|
int (*proc) ();
|
||||||
|
void *closure;
|
||||||
{
|
{
|
||||||
Node *head, *p;
|
Node *head, *p;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
@ -285,7 +288,7 @@ walklist (list, proc)
|
|||||||
|
|
||||||
head = list->list;
|
head = list->list;
|
||||||
for (p = head->next; p != head; p = p->next)
|
for (p = head->next; p != head; p = p->next)
|
||||||
err += proc (p);
|
err += proc (p, closure);
|
||||||
return (err);
|
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
|
* Copyright (c) 1992, Brian Berliner and Jeff Polk
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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 *options;
|
||||||
char *tag;
|
char *tag;
|
||||||
char *date;
|
char *date;
|
||||||
|
char *conflict;
|
||||||
};
|
};
|
||||||
typedef struct entnode Entnode;
|
typedef struct entnode Entnode;
|
||||||
|
|
||||||
#if __STDC__
|
List *getlist PROTO((void));
|
||||||
List *getlist (void);
|
Node *findnode PROTO((List * list, char *key));
|
||||||
Node *findnode (List * list, char *key);
|
Node *getnode PROTO((void));
|
||||||
Node *getnode (void);
|
int addnode PROTO((List * list, Node * p));
|
||||||
int addnode (List * list, Node * p);
|
int walklist PROTO((List * list, int PROTO((*proc)) PROTO((Node *n, void *closure)), void *closure));
|
||||||
int walklist (List * list, int (*proc) ());
|
void dellist PROTO((List ** listp));
|
||||||
void dellist (List ** listp);
|
void delnode PROTO((Node * p));
|
||||||
void delnode (Node * p);
|
void freenode PROTO((Node * p));
|
||||||
void freenode (Node * p);
|
void sortlist PROTO((List * list, int PROTO((*comp))()));
|
||||||
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__ */
|
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
* Copyright (c) 1992, Brian Berliner
|
* Copyright (c) 1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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:
|
* A simple ndbm-emulator for CVS. It parses a text file of the format:
|
||||||
*
|
*
|
||||||
@ -18,7 +18,8 @@
|
|||||||
#ifdef MY_NDBM
|
#ifdef MY_NDBM
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
static void mydbm_load_file ();
|
static void mydbm_load_file ();
|
||||||
@ -138,7 +139,7 @@ mydbm_load_file (fp, list)
|
|||||||
|
|
||||||
for (cont = 0; fgets (line, sizeof (line), fp) != NULL;)
|
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 */
|
*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
|
#ifdef MY_NDBM
|
||||||
|
|
||||||
@ -27,18 +27,10 @@ typedef struct
|
|||||||
#define dbm_firstkey mydbm_firstkey
|
#define dbm_firstkey mydbm_firstkey
|
||||||
#define dbm_nextkey mydbm_nextkey
|
#define dbm_nextkey mydbm_nextkey
|
||||||
|
|
||||||
#if __STDC__
|
DBM *mydbm_open PROTO((char *file, int flags, int mode));
|
||||||
DBM *mydbm_open (char *file, int flags, int mode);
|
void mydbm_close PROTO((DBM * db));
|
||||||
void mydbm_close (DBM * db);
|
datum mydbm_fetch PROTO((DBM * db, datum key));
|
||||||
datum mydbm_fetch (DBM * db, datum key);
|
datum mydbm_firstkey PROTO((DBM * db));
|
||||||
datum mydbm_firstkey (DBM * db);
|
datum mydbm_nextkey PROTO((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__ */
|
|
||||||
|
|
||||||
#endif /* MY_NDBM */
|
#endif /* MY_NDBM */
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,7 @@
|
|||||||
/* Definitions for data structures and routines for the regular
|
/* Definitions for data structures and routines for the regular
|
||||||
expression library, version REPLACE-WITH-VERSION.
|
expression library, version 0.12.
|
||||||
|
|
||||||
Copyright (C) 1985, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.
|
Copyright (C) 1985, 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -20,7 +20,15 @@
|
|||||||
#ifndef __REGEXP_LIBRARY_H__
|
#ifndef __REGEXP_LIBRARY_H__
|
||||||
#define __REGEXP_LIBRARY_H__
|
#define __REGEXP_LIBRARY_H__
|
||||||
|
|
||||||
/* POSIX says that <sys/types.h> must be included before <regex.h>. */
|
/* POSIX says that <sys/types.h> must be included (by the caller) before
|
||||||
|
<regex.h>. */
|
||||||
|
|
||||||
|
#ifdef VMS
|
||||||
|
/* VMS doesn't have `size_t' in <sys/types.h>, even though POSIX says it
|
||||||
|
should be there. */
|
||||||
|
#include <stddef.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* The following bits are used to determine the regexp syntax we
|
/* The following bits are used to determine the regexp syntax we
|
||||||
recognize. The set/not-set meanings are chosen so that Emacs syntax
|
recognize. The set/not-set meanings are chosen so that Emacs syntax
|
||||||
@ -45,17 +53,17 @@ typedef unsigned reg_syntax_t;
|
|||||||
#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
|
#define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
|
||||||
|
|
||||||
/* If this bit is set, then ^ and $ are always anchors (outside bracket
|
/* If this bit is set, then ^ and $ are always anchors (outside bracket
|
||||||
expressions).
|
expressions, of course).
|
||||||
If this bit is not set, then it depends:
|
If this bit is not set, then it depends:
|
||||||
^ is an anchor if it is at the beginning of a regular
|
^ is an anchor if it is at the beginning of a regular
|
||||||
expression or after an open-group or an alternation operator;
|
expression or after an open-group or an alternation operator;
|
||||||
$ is an anchor if it is at the end of a regular expression, or
|
$ is an anchor if it is at the end of a regular expression, or
|
||||||
before a close-group or an alternation operator.
|
before a close-group or an alternation operator.
|
||||||
|
|
||||||
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
|
This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
|
||||||
POSIX now says that the behavior of * etc. in leading positions is
|
POSIX draft 11.2 says that * etc. in leading positions is undefined.
|
||||||
undefined. We have already implemented a previous draft which
|
We already implemented a previous draft which made those constructs
|
||||||
made those constructs invalid, so we may as well not change the code
|
invalid, though, so we haven't changed the code back. */
|
||||||
back. */
|
|
||||||
#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
|
#define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
|
||||||
|
|
||||||
/* If this bit is set, then special characters are always special
|
/* If this bit is set, then special characters are always special
|
||||||
@ -67,16 +75,14 @@ typedef unsigned reg_syntax_t;
|
|||||||
#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
|
#define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
|
||||||
|
|
||||||
/* If this bit is set, then *, +, ?, and { cannot be first in an re or
|
/* If this bit is set, then *, +, ?, and { cannot be first in an re or
|
||||||
immediately after an alternation or begin-group operator.
|
immediately after an alternation or begin-group operator. */
|
||||||
Furthermore, alternation cannot be first or last in an re, or
|
|
||||||
immediately follow another alternation or begin-group. */
|
|
||||||
#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
|
#define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
|
||||||
|
|
||||||
/* If this bit is set, then . matches a newline.
|
/* If this bit is set, then . matches newline.
|
||||||
If not set, then it doesn't. */
|
If not set, then it doesn't. */
|
||||||
#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
|
#define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
|
||||||
|
|
||||||
/* If this bit is set, then period doesn't match a null.
|
/* If this bit is set, then . doesn't match NUL.
|
||||||
If not set, then it does. */
|
If not set, then it does. */
|
||||||
#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
|
#define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
|
||||||
|
|
||||||
@ -89,7 +95,7 @@ typedef unsigned reg_syntax_t;
|
|||||||
If not set, \{, \}, {, and } are literals. */
|
If not set, \{, \}, {, and } are literals. */
|
||||||
#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
|
#define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
|
||||||
|
|
||||||
/* If this bit is set, +, ? and | aren't recognized as operators.
|
/* If this bit is set, +, ? and | aren't recognized as operators.
|
||||||
If not set, they are. */
|
If not set, they are. */
|
||||||
#define RE_LIMITED_OPS (RE_INTERVALS << 1)
|
#define RE_LIMITED_OPS (RE_INTERVALS << 1)
|
||||||
|
|
||||||
@ -97,104 +103,112 @@ typedef unsigned reg_syntax_t;
|
|||||||
If not set, newline is literal. */
|
If not set, newline is literal. */
|
||||||
#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
|
#define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
|
||||||
|
|
||||||
/* If this bit is set, newline in the pattern is an ordinary character.
|
/* If this bit is set, then `{...}' defines an interval, and \{ and \}
|
||||||
If not set, newline before ^ or after $ allows the ^ or $ to be an
|
are literals.
|
||||||
anchor. */
|
If not set, then `\{...\}' defines an interval. */
|
||||||
#define RE_NEWLINE_ORDINARY (RE_NEWLINE_ALT << 1)
|
#define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
|
||||||
|
|
||||||
/* If this bit is not set, then \{ and \} defines an interval,
|
|
||||||
and { and } are literals.
|
|
||||||
If set, then { and } defines an interval, and \{ and \} are literals. */
|
|
||||||
#define RE_NO_BK_BRACES (RE_NEWLINE_ORDINARY << 1)
|
|
||||||
|
|
||||||
/* If this bit is set, (...) defines a group, and \( and \) are literals.
|
/* If this bit is set, (...) defines a group, and \( and \) are literals.
|
||||||
If not set, \(...\) defines a group, and ( and ) are literals. */
|
If not set, \(...\) defines a group, and ( and ) are literals. */
|
||||||
#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
|
#define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
|
||||||
|
|
||||||
/* If this bit is set, then back references (i.e., \<digit>) are not
|
/* If this bit is set, then \<digit> matches <digit>.
|
||||||
recognized.
|
If not set, then \<digit> is a back-reference. */
|
||||||
If not set, then they are. */
|
|
||||||
#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
|
#define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
|
||||||
|
|
||||||
/* If this bit is set, then | is an alternation operator, and \| is literal.
|
/* If this bit is set, then | is an alternation operator, and \| is literal.
|
||||||
If not set, then \| is an alternation operator, and | is literal. */
|
If not set, then \| is an alternation operator, and | is literal. */
|
||||||
#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
|
#define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
|
||||||
|
|
||||||
/* If this bit is set, then you can't have empty alternatives.
|
/* If this bit is set, then an ending range point collating higher
|
||||||
If not set, then you can. */
|
than the starting range point, as in [z-a], is invalid.
|
||||||
#define RE_NO_EMPTY_ALTS (RE_NO_BK_VBAR << 1)
|
If not set, then when ending range point collates higher than the
|
||||||
|
starting range point, the range is ignored. */
|
||||||
|
#define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
|
||||||
|
|
||||||
/* If this bit is set, then you can't have empty groups.
|
/* If this bit is set, then an unmatched ) is ordinary.
|
||||||
If not set, then you can. */
|
If not set, then an unmatched ) is invalid. */
|
||||||
#define RE_NO_EMPTY_GROUPS (RE_NO_EMPTY_ALTS << 1)
|
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
|
||||||
|
|
||||||
/* If this bit is set, then an ending range point has to collate higher
|
|
||||||
than or equal to the starting range point.
|
|
||||||
If not set, then when the ending range point collates higher than the
|
|
||||||
starting range point, we consider such a range to be empty. */
|
|
||||||
#define RE_NO_EMPTY_RANGES (RE_NO_EMPTY_GROUPS << 1)
|
|
||||||
|
|
||||||
/* If this bit is set, then all back references must refer to a preceding
|
|
||||||
subexpression.
|
|
||||||
If not set, then a back reference to a nonexistent subexpression is
|
|
||||||
treated as literal characters. */
|
|
||||||
#define RE_NO_MISSING_BK_REF (RE_NO_EMPTY_RANGES << 1)
|
|
||||||
|
|
||||||
/* If this bit is set, then Regex considers an unmatched close-group
|
|
||||||
operator to be the ordinary character parenthesis.
|
|
||||||
If not set, then an unmatched close-group operator is invalid. */
|
|
||||||
#define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_MISSING_BK_REF << 1)
|
|
||||||
|
|
||||||
/* This global variable defines the particular regexp syntax to use (for
|
/* This global variable defines the particular regexp syntax to use (for
|
||||||
some interfaces). When a regexp is compiled, the syntax used is
|
some interfaces). When a regexp is compiled, the syntax used is
|
||||||
stored in the pattern buffer, so changing this does not affect
|
stored in the pattern buffer, so changing this does not affect
|
||||||
already-compiled regexps. */
|
already-compiled regexps. */
|
||||||
extern reg_syntax_t obscure_syntax;
|
extern reg_syntax_t re_syntax_options;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Define combinations of the above bits for the standard possibilities.
|
/* Define combinations of the above bits for the standard possibilities.
|
||||||
(The [[[ comments delimit what gets put into the Texinfo file.) */
|
(The [[[ comments delimit what gets put into the Texinfo file, so
|
||||||
|
don't delete them!) */
|
||||||
/* [[[begin syntaxes]]] */
|
/* [[[begin syntaxes]]] */
|
||||||
#define RE_SYNTAX_EMACS 0
|
#define RE_SYNTAX_EMACS 0
|
||||||
|
|
||||||
#define RE_SYNTAX_POSIX_AWK \
|
|
||||||
(RE_CONTEXT_INDEP_ANCHORS | RE_CONTEXT_INDEP_OPS | RE_NO_BK_PARENS \
|
|
||||||
| RE_NO_BK_VBAR)
|
|
||||||
|
|
||||||
#define RE_SYNTAX_AWK \
|
#define RE_SYNTAX_AWK \
|
||||||
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_SYNTAX_POSIX_AWK)
|
(RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \
|
||||||
|
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
|
||||||
|
| RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \
|
||||||
|
| RE_UNMATCHED_RIGHT_PAREN_ORD)
|
||||||
|
|
||||||
|
#define RE_SYNTAX_POSIX_AWK \
|
||||||
|
(RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS)
|
||||||
|
|
||||||
#define RE_SYNTAX_GREP \
|
#define RE_SYNTAX_GREP \
|
||||||
(RE_BK_PLUS_QM | RE_NEWLINE_ALT)
|
(RE_BK_PLUS_QM | RE_CHAR_CLASSES \
|
||||||
|
| RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \
|
||||||
|
| RE_NEWLINE_ALT)
|
||||||
|
|
||||||
#define RE_SYNTAX_EGREP \
|
#define RE_SYNTAX_EGREP \
|
||||||
(RE_CONTEXT_INDEP_ANCHORS | RE_CONTEXT_INDEP_OPS \
|
(RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
|
||||||
| RE_NEWLINE_ALT | RE_NO_BK_PARENS | RE_NO_BK_VBAR)
|
| RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \
|
||||||
|
| RE_NEWLINE_ALT | RE_NO_BK_PARENS \
|
||||||
|
| RE_NO_BK_VBAR)
|
||||||
|
|
||||||
|
#define RE_SYNTAX_POSIX_EGREP \
|
||||||
|
(RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
|
||||||
|
|
||||||
|
/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */
|
||||||
|
#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
|
||||||
|
|
||||||
|
#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
|
||||||
|
|
||||||
|
/* Syntax bits common to both basic and extended POSIX regex syntax. */
|
||||||
|
#define _RE_SYNTAX_POSIX_COMMON \
|
||||||
|
(RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
|
||||||
|
| RE_INTERVALS | RE_NO_EMPTY_RANGES)
|
||||||
|
|
||||||
#define RE_SYNTAX_POSIX_BASIC \
|
#define RE_SYNTAX_POSIX_BASIC \
|
||||||
(RE_CHAR_CLASSES | RE_DOT_NEWLINE \
|
(_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM)
|
||||||
| RE_DOT_NOT_NULL | RE_INTERVALS | RE_LIMITED_OPS \
|
|
||||||
| RE_NEWLINE_ORDINARY | RE_NO_EMPTY_RANGES | RE_NO_MISSING_BK_REF)
|
/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
|
||||||
|
RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this
|
||||||
|
isn't minimal, since other operators, such as \`, aren't disabled. */
|
||||||
|
#define RE_SYNTAX_POSIX_MINIMAL_BASIC \
|
||||||
|
(_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
|
||||||
|
|
||||||
#define RE_SYNTAX_POSIX_EXTENDED \
|
#define RE_SYNTAX_POSIX_EXTENDED \
|
||||||
(RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \
|
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
|
||||||
| RE_CONTEXT_INVALID_OPS | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \
|
| RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \
|
||||||
| RE_INTERVALS | RE_NEWLINE_ORDINARY | RE_NO_BK_BRACES \
|
| RE_NO_BK_PARENS | RE_NO_BK_VBAR \
|
||||||
| RE_NO_BK_PARENS | RE_NO_BK_REFS | RE_NO_BK_VBAR \
|
|
||||||
| RE_NO_EMPTY_ALTS | RE_NO_EMPTY_GROUPS | RE_NO_EMPTY_RANGES \
|
|
||||||
| RE_UNMATCHED_RIGHT_PAREN_ORD)
|
| RE_UNMATCHED_RIGHT_PAREN_ORD)
|
||||||
|
|
||||||
|
/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS
|
||||||
|
replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */
|
||||||
|
#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \
|
||||||
|
(_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \
|
||||||
|
| RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \
|
||||||
|
| RE_NO_BK_PARENS | RE_NO_BK_REFS \
|
||||||
|
| RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD)
|
||||||
/* [[[end syntaxes]]] */
|
/* [[[end syntaxes]]] */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Maximum number of duplicates an interval can allow. */
|
/* Maximum number of duplicates an interval can allow. Some systems
|
||||||
|
(erroneously) define this in other header files, but we want our
|
||||||
|
value, so remove any previous define. */
|
||||||
|
#ifdef RE_DUP_MAX
|
||||||
#undef RE_DUP_MAX
|
#undef RE_DUP_MAX
|
||||||
#define RE_DUP_MAX ((1 << 15) - 1)
|
#endif
|
||||||
|
#define RE_DUP_MAX ((1 << 15) - 1)
|
||||||
|
|
||||||
|
|
||||||
/* POSIX `cflags' bits (i.e., information for regcomp). */
|
/* POSIX `cflags' bits (i.e., information for `regcomp'). */
|
||||||
|
|
||||||
/* If this bit is set, then use extended regular expression syntax.
|
/* If this bit is set, then use extended regular expression syntax.
|
||||||
If not set, then use basic regular expression syntax. */
|
If not set, then use basic regular expression syntax. */
|
||||||
@ -254,9 +268,6 @@ typedef enum
|
|||||||
REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
|
REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */
|
||||||
REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
|
REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */
|
||||||
} reg_errcode_t;
|
} reg_errcode_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* This data structure represents a compiled pattern. Before calling
|
/* This data structure represents a compiled pattern. Before calling
|
||||||
the pattern compiler, the fields `buffer', `allocated', `fastmap',
|
the pattern compiler, the fields `buffer', `allocated', `fastmap',
|
||||||
@ -295,19 +306,28 @@ struct re_pattern_buffer
|
|||||||
/* Number of subexpressions found by the compiler. */
|
/* Number of subexpressions found by the compiler. */
|
||||||
size_t re_nsub;
|
size_t re_nsub;
|
||||||
|
|
||||||
/* Set to 1 by re_compile_fastmap if this pattern can match the
|
/* Zero if this pattern cannot match the empty string, one else.
|
||||||
null string; 0 prevents the searcher from matching it with
|
Well, in truth it's used only in `re_search_2', to see
|
||||||
the null string. Set to 2 if it might match the null string
|
whether or not we should use the fastmap, so we don't set
|
||||||
either at the end of a search range or just before a
|
this absolutely perfectly; see `re_compile_fastmap' (the
|
||||||
character listed in the fastmap. */
|
`duplicate' case). */
|
||||||
unsigned can_be_null : 2;
|
unsigned can_be_null : 1;
|
||||||
|
|
||||||
/* Set to zero when regex_compile compiles a pattern; set to one
|
/* If REGS_UNALLOCATED, allocate space in the `regs' structure
|
||||||
by re_compile_fastmap when it updates the fastmap, if any. */
|
for `max (RE_NREGS, re_nsub + 1)' groups.
|
||||||
|
If REGS_REALLOCATE, reallocate space if necessary.
|
||||||
|
If REGS_FIXED, use what's there. */
|
||||||
|
#define REGS_UNALLOCATED 0
|
||||||
|
#define REGS_REALLOCATE 1
|
||||||
|
#define REGS_FIXED 2
|
||||||
|
unsigned regs_allocated : 2;
|
||||||
|
|
||||||
|
/* Set to zero when `regex_compile' compiles a pattern; set to one
|
||||||
|
by `re_compile_fastmap' if it updates the fastmap. */
|
||||||
unsigned fastmap_accurate : 1;
|
unsigned fastmap_accurate : 1;
|
||||||
|
|
||||||
/* If set, regexec reports only success or failure and does not
|
/* If set, `re_match_2' does not return information about
|
||||||
return anything in pmatch. */
|
subexpressions. */
|
||||||
unsigned no_sub : 1;
|
unsigned no_sub : 1;
|
||||||
|
|
||||||
/* If set, a beginning-of-line anchor doesn't match at the
|
/* If set, a beginning-of-line anchor doesn't match at the
|
||||||
@ -320,10 +340,6 @@ struct re_pattern_buffer
|
|||||||
/* If true, an anchor at a newline matches. */
|
/* If true, an anchor at a newline matches. */
|
||||||
unsigned newline_anchor : 1;
|
unsigned newline_anchor : 1;
|
||||||
|
|
||||||
/* If set, re_match_2 assumes a non-null REGS argument is
|
|
||||||
initialized. If not set, REGS is initialized to the max of
|
|
||||||
RE_NREGS and re_nsub + 1 registers. */
|
|
||||||
unsigned caller_allocated_regs : 1;
|
|
||||||
/* [[[end pattern_buffer]]] */
|
/* [[[end pattern_buffer]]] */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -333,12 +349,8 @@ typedef struct re_pattern_buffer regex_t;
|
|||||||
/* search.c (search_buffer) in Emacs needs this one opcode value. It is
|
/* search.c (search_buffer) in Emacs needs this one opcode value. It is
|
||||||
defined both in `regex.c' and here. */
|
defined both in `regex.c' and here. */
|
||||||
#define RE_EXACTN_VALUE 1
|
#define RE_EXACTN_VALUE 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Type for byte offsets within the string. POSIX mandates us defining
|
/* Type for byte offsets within the string. POSIX mandates this. */
|
||||||
this. */
|
|
||||||
typedef int regoff_t;
|
typedef int regoff_t;
|
||||||
|
|
||||||
|
|
||||||
@ -352,8 +364,9 @@ struct re_registers
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* If `caller_allocated_regs' is zero in the pattern buffer, re_match_2
|
/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
|
||||||
returns information about this many registers. */
|
`re_match_2' returns information about at least this many registers
|
||||||
|
the first time a `regs' structure is passed. */
|
||||||
#ifndef RE_NREGS
|
#ifndef RE_NREGS
|
||||||
#define RE_NREGS 30
|
#define RE_NREGS 30
|
||||||
#endif
|
#endif
|
||||||
@ -367,29 +380,41 @@ typedef struct
|
|||||||
regoff_t rm_so; /* Byte offset from string's start to substring's start. */
|
regoff_t rm_so; /* Byte offset from string's start to substring's start. */
|
||||||
regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
|
regoff_t rm_eo; /* Byte offset from string's start to substring's end. */
|
||||||
} regmatch_t;
|
} regmatch_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Declarations for routines. */
|
/* Declarations for routines. */
|
||||||
|
|
||||||
|
/* To avoid duplicating every routine declaration -- once with a
|
||||||
|
prototype (if we are ANSI), and once without (if we aren't) -- we
|
||||||
|
use the following macro to declare argument types. This
|
||||||
|
unfortunately clutters up the declarations a bit, but I think it's
|
||||||
|
worth it. */
|
||||||
|
|
||||||
#if __STDC__
|
#if __STDC__
|
||||||
|
|
||||||
/* Sets the current syntax to SYNTAX. You can also simply assign to the
|
#define _RE_ARGS(args) args
|
||||||
`obscure_syntax' variable. */
|
|
||||||
extern reg_syntax_t re_set_syntax (reg_syntax_t syntax);
|
#else /* not __STDC__ */
|
||||||
|
|
||||||
|
#define _RE_ARGS(args) ()
|
||||||
|
|
||||||
|
#endif /* not __STDC__ */
|
||||||
|
|
||||||
|
/* Sets the current default syntax to SYNTAX, and return the old syntax.
|
||||||
|
You can also simply assign to the `re_syntax_options' variable. */
|
||||||
|
extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax));
|
||||||
|
|
||||||
/* Compile the regular expression PATTERN, with length LENGTH
|
/* Compile the regular expression PATTERN, with length LENGTH
|
||||||
and syntax given by the global `obscure_syntax', into the buffer
|
and syntax given by the global `re_syntax_options', into the buffer
|
||||||
BUFFER. Return NULL if successful, and an error string if not. */
|
BUFFER. Return NULL if successful, and an error string if not. */
|
||||||
extern const char *re_compile_pattern (const char *pattern, int length,
|
extern const char *re_compile_pattern
|
||||||
struct re_pattern_buffer *buffer);
|
_RE_ARGS ((const char *pattern, int length,
|
||||||
|
struct re_pattern_buffer *buffer));
|
||||||
|
|
||||||
|
|
||||||
/* Compile a fastmap for the compiled pattern in BUFFER; used to
|
/* Compile a fastmap for the compiled pattern in BUFFER; used to
|
||||||
accelerate searches. Return 0 if successful and -2 if was an
|
accelerate searches. Return 0 if successful and -2 if was an
|
||||||
internal error. */
|
internal error. */
|
||||||
extern int re_compile_fastmap (struct re_pattern_buffer *buffer);
|
extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer));
|
||||||
|
|
||||||
|
|
||||||
/* Search in the string STRING (with length LENGTH) for the pattern
|
/* Search in the string STRING (with length LENGTH) for the pattern
|
||||||
@ -397,78 +422,64 @@ extern int re_compile_fastmap (struct re_pattern_buffer *buffer);
|
|||||||
characters. Return the starting position of the match, -1 for no
|
characters. Return the starting position of the match, -1 for no
|
||||||
match, or -2 for an internal error. Also return register
|
match, or -2 for an internal error. Also return register
|
||||||
information in REGS (if REGS and BUFFER->no_sub are nonzero). */
|
information in REGS (if REGS and BUFFER->no_sub are nonzero). */
|
||||||
extern int re_search (struct re_pattern_buffer *buffer,
|
extern int re_search
|
||||||
const char *string, int length,
|
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
|
||||||
int start, int range,
|
int length, int start, int range, struct re_registers *regs));
|
||||||
struct re_registers *regs);
|
|
||||||
|
|
||||||
|
|
||||||
/* Like `re_search', but search in the concatenation of STRING1 and
|
/* Like `re_search', but search in the concatenation of STRING1 and
|
||||||
STRING2. Also, stop searching at index START + STOP. */
|
STRING2. Also, stop searching at index START + STOP. */
|
||||||
extern int re_search_2 (struct re_pattern_buffer *buffer,
|
extern int re_search_2
|
||||||
const char *string1, int length1,
|
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
|
||||||
const char *string2, int length2,
|
int length1, const char *string2, int length2,
|
||||||
int start, int range,
|
int start, int range, struct re_registers *regs, int stop));
|
||||||
struct re_registers *regs,
|
|
||||||
int stop);
|
|
||||||
|
|
||||||
|
|
||||||
/* Like `re_search', but return how many characters in STRING the regexp
|
/* Like `re_search', but return how many characters in STRING the regexp
|
||||||
in BUFFER matched, starting at position START. */
|
in BUFFER matched, starting at position START. */
|
||||||
extern int re_match (const struct re_pattern_buffer *buffer,
|
extern int re_match
|
||||||
const char *string, int length,
|
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string,
|
||||||
int start, struct re_registers *regs);
|
int length, int start, struct re_registers *regs));
|
||||||
|
|
||||||
|
|
||||||
/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
|
/* Relates to `re_match' as `re_search_2' relates to `re_search'. */
|
||||||
extern int re_match_2 (const struct re_pattern_buffer *buffer,
|
extern int re_match_2
|
||||||
const char *string1, int length1,
|
_RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1,
|
||||||
const char *string2, int length2,
|
int length1, const char *string2, int length2,
|
||||||
int start,
|
int start, struct re_registers *regs, int stop));
|
||||||
struct re_registers *regs,
|
|
||||||
int stop);
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef __386BSD__
|
/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
|
||||||
|
ENDS. Subsequent matches using BUFFER and REGS will use this memory
|
||||||
|
for recording register information. STARTS and ENDS must be
|
||||||
|
allocated with malloc, and must each be at least `NUM_REGS * sizeof
|
||||||
|
(regoff_t)' bytes long.
|
||||||
|
|
||||||
|
If NUM_REGS == 0, then subsequent matches should allocate their own
|
||||||
|
register data.
|
||||||
|
|
||||||
|
Unless this function is called, the first search or match using
|
||||||
|
PATTERN_BUFFER will allocate its own register data, without
|
||||||
|
freeing the old data. */
|
||||||
|
extern void re_set_registers
|
||||||
|
_RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs,
|
||||||
|
unsigned num_regs, regoff_t *starts, regoff_t *ends));
|
||||||
|
|
||||||
/* 4.2 bsd compatibility. */
|
/* 4.2 bsd compatibility. */
|
||||||
#ifndef bsdi
|
extern char *re_comp _RE_ARGS ((const char *));
|
||||||
extern const char *re_comp (const char *);
|
extern int re_exec _RE_ARGS ((const char *));
|
||||||
#endif
|
|
||||||
extern int re_exec (const char *);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* POSIX compatibility. */
|
/* POSIX compatibility. */
|
||||||
extern int regcomp (regex_t *preg, const char *pattern, int cflags);
|
extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags));
|
||||||
extern int regexec (const regex_t *preg, const char *string, size_t nmatch,
|
extern int regexec
|
||||||
regmatch_t pmatch[], int eflags);
|
_RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch,
|
||||||
extern size_t regerror (int errcode, const regex_t *preg, char *errbuf,
|
regmatch_t pmatch[], int eflags));
|
||||||
size_t errbuf_size);
|
extern size_t regerror
|
||||||
extern void regfree (regex_t *preg);
|
_RE_ARGS ((int errcode, const regex_t *preg, char *errbuf,
|
||||||
|
size_t errbuf_size));
|
||||||
|
extern void regfree _RE_ARGS ((regex_t *preg));
|
||||||
|
|
||||||
#else /* not __STDC__ */
|
|
||||||
|
|
||||||
/* Support old C compilers. */
|
|
||||||
#define const
|
|
||||||
|
|
||||||
extern reg_syntax_t re_set_syntax ();
|
|
||||||
extern char *re_compile_pattern ();
|
|
||||||
extern int re_search (), re_search_2 ();
|
|
||||||
extern int re_match (), re_match_2 ();
|
|
||||||
|
|
||||||
/* 4.2 BSD compatibility. */
|
|
||||||
extern char *re_comp ();
|
|
||||||
extern int re_exec ();
|
|
||||||
|
|
||||||
/* POSIX compatibility. */
|
|
||||||
extern int regcomp ();
|
|
||||||
extern int regexec ();
|
|
||||||
extern size_t regerror ();
|
|
||||||
extern void regfree ();
|
|
||||||
|
|
||||||
#endif /* not __STDC__ */
|
|
||||||
#endif /* not __REGEXP_LIBRARY_H__ */
|
#endif /* not __REGEXP_LIBRARY_H__ */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Local variables:
|
Local variables:
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -30,10 +30,14 @@
|
|||||||
* must not themselves make calls to the signal handling
|
* must not themselves make calls to the signal handling
|
||||||
* facilities.
|
* 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 <sys/types.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -54,18 +58,14 @@ char *malloc();
|
|||||||
#undef POSIX /* Minix 1.6 doesn't support POSIX.1 sigaction yet */
|
#undef POSIX /* Minix 1.6 doesn't support POSIX.1 sigaction yet */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SIGTYPE
|
|
||||||
#define SIGTYPE void
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Define the highest signal number (usually) */
|
/* Define the highest signal number (usually) */
|
||||||
#ifndef SIGMAX
|
#ifndef SIGMAX
|
||||||
#define SIGMAX 32
|
#define SIGMAX 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define linked list of signal handlers structure */
|
/* Define linked list of signal handlers structure */
|
||||||
struct SIG_hlist {
|
struct SIG_hlist {
|
||||||
SIGTYPE (*handler)();
|
RETSIGTYPE (*handler)();
|
||||||
struct SIG_hlist *next;
|
struct SIG_hlist *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ static struct sigaction *SIG_defaults;
|
|||||||
#ifdef BSD_SIGNALS
|
#ifdef BSD_SIGNALS
|
||||||
static struct sigvec *SIG_defaults;
|
static struct sigvec *SIG_defaults;
|
||||||
#else
|
#else
|
||||||
static SIGTYPE (**SIG_defaults)();
|
static RETSIGTYPE (**SIG_defaults)();
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -112,11 +112,7 @@ static int SIG_init()
|
|||||||
|
|
||||||
#ifdef POSIX
|
#ifdef POSIX
|
||||||
(void) sigfillset(&sigset_test);
|
(void) sigfillset(&sigset_test);
|
||||||
for (i = 1; sigismember(&sigset_test, i) == 1; i++)
|
for (i = 1; i < SIGMAX && sigismember(&sigset_test, i) == 1; i++)
|
||||||
#ifdef BROKEN_SIGISMEMBER
|
|
||||||
if ( i >= NSIG )
|
|
||||||
break
|
|
||||||
#endif
|
|
||||||
;
|
;
|
||||||
if (i < SIGMAX)
|
if (i < SIGMAX)
|
||||||
i = SIGMAX;
|
i = SIGMAX;
|
||||||
@ -133,8 +129,8 @@ static int SIG_init()
|
|||||||
calloc(i, sizeof(struct sigvec));
|
calloc(i, sizeof(struct sigvec));
|
||||||
#else
|
#else
|
||||||
if (!SIG_defaults)
|
if (!SIG_defaults)
|
||||||
SIG_defaults = (SIGTYPE (**)())
|
SIG_defaults = (RETSIGTYPE (**)())
|
||||||
calloc(i, sizeof(SIGTYPE (**)()));
|
calloc(i, sizeof(RETSIGTYPE (**)()));
|
||||||
#endif
|
#endif
|
||||||
SIG_crSectMask = 0;
|
SIG_crSectMask = 0;
|
||||||
#endif
|
#endif
|
||||||
@ -149,7 +145,7 @@ static int SIG_init()
|
|||||||
* they were registered.
|
* they were registered.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static SIGTYPE SIG_handle(sig)
|
static RETSIGTYPE SIG_handle(sig)
|
||||||
int sig;
|
int sig;
|
||||||
{
|
{
|
||||||
struct SIG_hlist *this;
|
struct SIG_hlist *this;
|
||||||
@ -175,7 +171,7 @@ int sig;
|
|||||||
|
|
||||||
int SIG_register(sig,fn)
|
int SIG_register(sig,fn)
|
||||||
int sig;
|
int sig;
|
||||||
SIGTYPE (*fn)();
|
RETSIGTYPE (*fn)();
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
struct SIG_hlist *this;
|
struct SIG_hlist *this;
|
||||||
@ -236,7 +232,7 @@ SIGTYPE (*fn)();
|
|||||||
val = sigvec(sig, &vec, &SIG_defaults[sig]);
|
val = sigvec(sig, &vec, &SIG_defaults[sig]);
|
||||||
#else
|
#else
|
||||||
if ((SIG_defaults[sig] = signal(sig, SIG_handle)) ==
|
if ((SIG_defaults[sig] = signal(sig, SIG_handle)) ==
|
||||||
(SIGTYPE (*)()) -1)
|
(RETSIGTYPE (*)()) -1)
|
||||||
val = -1;
|
val = -1;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@ -279,7 +275,7 @@ SIGTYPE (*fn)();
|
|||||||
|
|
||||||
int SIG_deregister(sig,fn)
|
int SIG_deregister(sig,fn)
|
||||||
int sig;
|
int sig;
|
||||||
SIGTYPE (*fn)();
|
RETSIGTYPE (*fn)();
|
||||||
{
|
{
|
||||||
int val;
|
int val;
|
||||||
struct SIG_hlist *this;
|
struct SIG_hlist *this;
|
||||||
@ -341,7 +337,7 @@ SIGTYPE (*fn)();
|
|||||||
#ifdef BSD_SIGNALS
|
#ifdef BSD_SIGNALS
|
||||||
val = sigvec(sig, &SIG_defaults[sig], (struct sigvec *) NULL);
|
val = sigvec(sig, &SIG_defaults[sig], (struct sigvec *) NULL);
|
||||||
#else
|
#else
|
||||||
if (signal(sig, SIG_defaults[sig]) == (SIGTYPE (*)()) -1)
|
if (signal(sig, SIG_defaults[sig]) == (RETSIGTYPE (*)()) -1)
|
||||||
val = -1;
|
val = -1;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -15,14 +15,20 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
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>
|
#include <string.h>
|
||||||
#ifndef index
|
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
|
||||||
#define index strchr
|
#if !STDC_HEADERS && HAVE_MEMORY_H
|
||||||
#endif
|
#include <memory.h>
|
||||||
#else
|
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||||
|
#else /* not STDC_HJEADERS and not HAVE_STRING_H */
|
||||||
#include <strings.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>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -43,7 +49,7 @@ strip_path (path)
|
|||||||
int stripped = 0;
|
int stripped = 0;
|
||||||
char *cp, *slash;
|
char *cp, *slash;
|
||||||
|
|
||||||
for (cp = path; (slash = index(cp, '/')) != NULL; cp = slash)
|
for (cp = path; (slash = strchr(cp, '/')) != NULL; cp = slash)
|
||||||
{
|
{
|
||||||
*slash = '\0';
|
*slash = '\0';
|
||||||
if ((!*cp && (cp != path || stripped)) ||
|
if ((!*cp && (cp != path || stripped)) ||
|
||||||
|
@ -15,12 +15,21 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
#if defined(STDC_HEADERS) || defined(USG)
|
#ifdef HAVE_CONFIG_H
|
||||||
#include <string.h>
|
#include "config.h"
|
||||||
#else
|
|
||||||
#include <strings.h>
|
|
||||||
#endif
|
#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. */
|
/* Remove trailing slashes from PATH. */
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -3,19 +3,24 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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.
|
* Various useful functions for the CVS support code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
|
#ifndef lint
|
||||||
|
static char rcsid[] = "$CVSid: @(#)subr.c 1.64 94/10/07 $";
|
||||||
|
USE(rcsid)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MINIX
|
#ifdef _MINIX
|
||||||
#undef POSIX /* Minix 1.6 doesn't support POSIX.1 sigaction yet */
|
#undef POSIX /* Minix 1.6 doesn't support POSIX.1 sigaction yet */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
#if __STDC__
|
#if defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__)
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#define VA_START(args, lastarg) va_start(args, lastarg)
|
#define VA_START(args, lastarg) va_start(args, lastarg)
|
||||||
#else
|
#else
|
||||||
@ -27,17 +32,24 @@
|
|||||||
#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
|
#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
|
||||||
#endif
|
#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
|
#endif
|
||||||
|
|
||||||
#if __STDC__
|
static void run_add_arg PROTO((char *s));
|
||||||
static void run_add_arg (char *s);
|
static void run_init_prog PROTO((void));
|
||||||
static void run_init_prog (void);
|
|
||||||
#else
|
|
||||||
static void run_add_arg ();
|
|
||||||
static void run_init_prog ();
|
|
||||||
#endif /* __STDC__ */
|
|
||||||
|
|
||||||
extern char *getlogin ();
|
extern char *getlogin ();
|
||||||
extern char *strtok ();
|
extern char *strtok ();
|
||||||
@ -74,7 +86,7 @@ copy_file (from, to)
|
|||||||
if (read (fdin, buf, (int) sb.st_size) != (int) sb.st_size)
|
if (read (fdin, buf, (int) sb.st_size) != (int) sb.st_size)
|
||||||
error (1, errno, "cannot read file %s for copying", from);
|
error (1, errno, "cannot read file %s for copying", from);
|
||||||
if (write (fdout, buf, (int) sb.st_size) != (int) sb.st_size
|
if (write (fdout, buf, (int) sb.st_size) != (int) sb.st_size
|
||||||
#ifndef FSYNC_MISSING
|
#ifdef HAVE_FSYNC
|
||||||
|| fsync (fdout) == -1
|
|| fsync (fdout) == -1
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
@ -88,11 +100,15 @@ copy_file (from, to)
|
|||||||
error (1, errno, "cannot close %s", to);
|
error (1, errno, "cannot close %s", to);
|
||||||
|
|
||||||
/* now, set the times for the copied file to match those of the original */
|
/* 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.actime = sb.st_atime;
|
||||||
t.modtime = sb.st_mtime;
|
t.modtime = sb.st_mtime;
|
||||||
(void) utime (to, &t);
|
(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
|
* Returns non-zero if the argument file is a directory, or is a symbolic
|
||||||
* link which points to a directory.
|
* link which points to a directory.
|
||||||
@ -202,25 +218,8 @@ make_directory (name)
|
|||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
if (stat (name, &buf) == 0)
|
if (stat (name, &buf) == 0 && (!S_ISDIR (buf.st_mode)))
|
||||||
{
|
|
||||||
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
|
|
||||||
error (0, 0, "%s already exists but is not a directory", name);
|
error (0, 0, "%s already exists but is not a directory", name);
|
||||||
}
|
|
||||||
if (!noexec && mkdir (name, 0777) < 0)
|
if (!noexec && mkdir (name, 0777) < 0)
|
||||||
error (1, errno, "cannot make directory %s", name);
|
error (1, errno, "cannot make directory %s", name);
|
||||||
}
|
}
|
||||||
@ -245,7 +244,7 @@ make_directories (name)
|
|||||||
error (0, errno, "cannot make path to %s", name);
|
error (0, errno, "cannot make path to %s", name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((cp = rindex (name, '/')) == NULL)
|
if ((cp = strrchr (name, '/')) == NULL)
|
||||||
return;
|
return;
|
||||||
*cp = '\0';
|
*cp = '\0';
|
||||||
make_directories (name);
|
make_directories (name);
|
||||||
@ -260,14 +259,12 @@ make_directories (name)
|
|||||||
*/
|
*/
|
||||||
char *
|
char *
|
||||||
xmalloc (bytes)
|
xmalloc (bytes)
|
||||||
int bytes;
|
size_t bytes;
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
if (bytes <= 0)
|
if ((cp = malloc (bytes)) == NULL)
|
||||||
error (1, 0, "bad malloc size %d", bytes);
|
error (1, 0, "can not allocate %lu bytes", (unsigned long) bytes);
|
||||||
if ((cp = malloc ((unsigned) bytes)) == NULL)
|
|
||||||
error (1, 0, "malloc failed");
|
|
||||||
return (cp);
|
return (cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,17 +276,17 @@ xmalloc (bytes)
|
|||||||
char *
|
char *
|
||||||
xrealloc (ptr, bytes)
|
xrealloc (ptr, bytes)
|
||||||
char *ptr;
|
char *ptr;
|
||||||
int bytes;
|
size_t bytes;
|
||||||
{
|
{
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return (xmalloc (bytes));
|
cp = malloc (bytes);
|
||||||
|
else
|
||||||
|
cp = realloc (ptr, bytes);
|
||||||
|
|
||||||
if (bytes <= 0)
|
if (cp == NULL)
|
||||||
error (1, 0, "bad realloc size %d", bytes);
|
error (1, 0, "can not reallocate %lu bytes", (unsigned long) bytes);
|
||||||
if ((cp = realloc (ptr, (unsigned) bytes)) == NULL)
|
|
||||||
error (1, 0, "realloc failed");
|
|
||||||
return (cp);
|
return (cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -320,7 +317,7 @@ xchmod (fname, writable)
|
|||||||
int writable;
|
int writable;
|
||||||
{
|
{
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
int mode, oumask;
|
mode_t mode, oumask;
|
||||||
|
|
||||||
if (stat (fname, &sb) < 0)
|
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.
|
* 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
|
* 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.
|
* source files are typically not too large.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* richfix: this *could* exploit mmap. */
|
||||||
|
|
||||||
int
|
int
|
||||||
xcmp (file1, file2)
|
xcmp (file1, file2)
|
||||||
char *file1;
|
char *file1;
|
||||||
@ -430,10 +430,10 @@ xcmp (file1, file2)
|
|||||||
buf1 = xmalloc ((int) size);
|
buf1 = xmalloc ((int) size);
|
||||||
buf2 = xmalloc ((int) size);
|
buf2 = xmalloc ((int) size);
|
||||||
if (read (fd1, buf1, (int) size) != (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)
|
if (read (fd2, buf2, (int) size) != (int) size)
|
||||||
error (1, errno, "cannot read file %s for comparing", file2);
|
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 (buf1);
|
||||||
free (buf2);
|
free (buf2);
|
||||||
}
|
}
|
||||||
@ -512,10 +512,10 @@ getcaller ()
|
|||||||
static char uidname[20];
|
static char uidname[20];
|
||||||
struct passwd *pw;
|
struct passwd *pw;
|
||||||
char *name;
|
char *name;
|
||||||
int uid;
|
uid_t uid;
|
||||||
|
|
||||||
uid = getuid ();
|
uid = getuid ();
|
||||||
if (uid == 0)
|
if (uid == (uid_t) 0)
|
||||||
{
|
{
|
||||||
/* super-user; try getlogin() to distinguish */
|
/* super-user; try getlogin() to distinguish */
|
||||||
if (((name = getenv("LOGNAME")) || (name = getenv("USER")) ||
|
if (((name = getenv("LOGNAME")) || (name = getenv("USER")) ||
|
||||||
@ -524,7 +524,7 @@ getcaller ()
|
|||||||
}
|
}
|
||||||
if ((pw = (struct passwd *) getpwuid (uid)) == NULL)
|
if ((pw = (struct passwd *) getpwuid (uid)) == NULL)
|
||||||
{
|
{
|
||||||
(void) sprintf (uidname, "uid%d", uid);
|
(void) sprintf (uidname, "uid%d", (unsigned long) uid);
|
||||||
return (uidname);
|
return (uidname);
|
||||||
}
|
}
|
||||||
return (pw->pw_name);
|
return (pw->pw_name);
|
||||||
@ -549,7 +549,7 @@ static int run_argc;
|
|||||||
static int run_argc_allocated;
|
static int run_argc_allocated;
|
||||||
|
|
||||||
/* VARARGS */
|
/* VARARGS */
|
||||||
#if !defined (VPRINTF_MISSING) && __STDC__
|
#if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
|
||||||
void
|
void
|
||||||
run_setup (char *fmt,...)
|
run_setup (char *fmt,...)
|
||||||
#else
|
#else
|
||||||
@ -560,7 +560,7 @@ run_setup (fmt, va_alist)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -581,7 +581,7 @@ run_setup (fmt, va_alist)
|
|||||||
run_argc = 0;
|
run_argc = 0;
|
||||||
|
|
||||||
/* process the varargs into run_prog */
|
/* process the varargs into run_prog */
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
VA_START (args, fmt);
|
VA_START (args, fmt);
|
||||||
(void) vsprintf (run_prog, fmt, args);
|
(void) vsprintf (run_prog, fmt, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
@ -602,7 +602,7 @@ run_arg (s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* VARARGS */
|
/* VARARGS */
|
||||||
#if !defined (VPRINTF_MISSING) && __STDC__
|
#if defined (HAVE_VPRINTF) && (defined (USE_PROTOTYPES) ? USE_PROTOTYPES : defined (__STDC__))
|
||||||
void
|
void
|
||||||
run_args (char *fmt,...)
|
run_args (char *fmt,...)
|
||||||
#else
|
#else
|
||||||
@ -613,7 +613,7 @@ run_args (fmt, va_alist)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -621,7 +621,7 @@ run_args (fmt, va_alist)
|
|||||||
run_init_prog ();
|
run_init_prog ();
|
||||||
|
|
||||||
/* process the varargs into run_prog */
|
/* process the varargs into run_prog */
|
||||||
#ifndef VPRINTF_MISSING
|
#ifdef HAVE_VPRINTF
|
||||||
VA_START (args, fmt);
|
VA_START (args, fmt);
|
||||||
(void) vsprintf (run_prog, fmt, args);
|
(void) vsprintf (run_prog, fmt, args);
|
||||||
va_end (args);
|
va_end (args);
|
||||||
@ -668,7 +668,12 @@ run_exec (stin, stout, sterr, flags)
|
|||||||
{
|
{
|
||||||
int shin, shout, sherr;
|
int shin, shout, sherr;
|
||||||
int mode_out, mode_err;
|
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 rerrno = 0;
|
||||||
int pid, w;
|
int pid, w;
|
||||||
|
|
||||||
@ -682,7 +687,7 @@ run_exec (stin, stout, sterr, flags)
|
|||||||
struct sigvec vec, ivec, qvec;
|
struct sigvec vec, ivec, qvec;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
SIGTYPE (*istat) (), (*qstat) ();
|
RETSIGTYPE (*istat) (), (*qstat) ();
|
||||||
#endif
|
#endif
|
||||||
#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 */
|
/* The output files, if any, are now created. Do the fork and dups */
|
||||||
#ifdef VFORK_MISSING
|
#ifdef HAVE_VFORK
|
||||||
pid = fork ();
|
|
||||||
#else
|
|
||||||
pid = vfork ();
|
pid = vfork ();
|
||||||
|
#else
|
||||||
|
pid = fork ();
|
||||||
#endif
|
#endif
|
||||||
if (pid == 0)
|
if (pid == 0)
|
||||||
{
|
{
|
||||||
@ -761,6 +770,7 @@ run_exec (stin, stout, sterr, flags)
|
|||||||
|
|
||||||
/* dup'ing is done. try to run it now */
|
/* dup'ing is done. try to run it now */
|
||||||
(void) execvp (run_argv[0], run_argv);
|
(void) execvp (run_argv[0], run_argv);
|
||||||
|
error (0, errno, "cannot exec %s", run_argv[0]);
|
||||||
_exit (127);
|
_exit (127);
|
||||||
}
|
}
|
||||||
else if (pid == -1)
|
else if (pid == -1)
|
||||||
@ -790,7 +800,7 @@ run_exec (stin, stout, sterr, flags)
|
|||||||
#ifdef BSD_SIGNALS
|
#ifdef BSD_SIGNALS
|
||||||
if (flags & RUN_SIGIGNORE)
|
if (flags & RUN_SIGIGNORE)
|
||||||
{
|
{
|
||||||
bzero ((char *) &vec, sizeof (vec));
|
memset ((char *) &vec, 0, sizeof (vec));
|
||||||
vec.sv_handler = SIG_IGN;
|
vec.sv_handler = SIG_IGN;
|
||||||
(void) sigvec (SIGINT, &vec, &ivec);
|
(void) sigvec (SIGINT, &vec, &ivec);
|
||||||
(void) sigvec (SIGQUIT, &vec, &qvec);
|
(void) sigvec (SIGQUIT, &vec, &qvec);
|
||||||
@ -816,19 +826,19 @@ run_exec (stin, stout, sterr, flags)
|
|||||||
#endif
|
#endif
|
||||||
if (w == -1)
|
if (w == -1)
|
||||||
{
|
{
|
||||||
status = -1;
|
rc = -1;
|
||||||
rerrno = errno;
|
rerrno = errno;
|
||||||
}
|
}
|
||||||
else if (WIFEXITED (status))
|
else if (WIFEXITED (status))
|
||||||
status = WEXITSTATUS (status);
|
rc = WEXITSTATUS (status);
|
||||||
else if (WIFSIGNALED (status))
|
else if (WIFSIGNALED (status))
|
||||||
{
|
{
|
||||||
if (WTERMSIG (status) == SIGPIPE)
|
if (WTERMSIG (status) == SIGPIPE)
|
||||||
error (1, 0, "broken pipe");
|
error (1, 0, "broken pipe");
|
||||||
status = 2;
|
rc = 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
status = 1;
|
rc = 1;
|
||||||
|
|
||||||
/* restore the signals */
|
/* restore the signals */
|
||||||
#ifdef POSIX
|
#ifdef POSIX
|
||||||
@ -868,7 +878,7 @@ run_exec (stin, stout, sterr, flags)
|
|||||||
out0:
|
out0:
|
||||||
if (rerrno)
|
if (rerrno)
|
||||||
errno = rerrno;
|
errno = rerrno;
|
||||||
return (status);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -910,3 +920,130 @@ get_date (date, now)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
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/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -52,16 +52,13 @@
|
|||||||
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
|
#if !defined(S_ISNWK) && defined(S_IFNWK) /* HP/UX */
|
||||||
#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
|
#define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
|
||||||
#endif
|
#endif
|
||||||
#if defined(MKFIFO_MISSING)
|
#if !defined(HAVE_MKFIFO)
|
||||||
#define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0))
|
#define mkfifo(path, mode) (mknod ((path), (mode) | S_IFIFO, 0))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef POSIX
|
#if defined(POSIX) || defined(HAVE_UNISTD_H)
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#ifndef PATH_MAX
|
|
||||||
#define PATH_MAX pathconf ("/", _PC_PATH_MAX)
|
|
||||||
#endif
|
|
||||||
#else
|
#else
|
||||||
off_t lseek ();
|
off_t lseek ();
|
||||||
#endif
|
#endif
|
||||||
@ -72,7 +69,7 @@ off_t lseek ();
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TIMEB_H_MISSING
|
#ifndef HAVE_SYS_TIMEB_H
|
||||||
struct timeb {
|
struct timeb {
|
||||||
time_t time; /* Seconds since the epoch */
|
time_t time; /* Seconds since the epoch */
|
||||||
unsigned short millitm; /* Field not used */
|
unsigned short millitm; /* Field not used */
|
||||||
@ -87,29 +84,66 @@ struct timeb {
|
|||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(FTIME_MISSING) && !defined(HAVE_TIMEZONE)
|
#if !defined(HAVE_FTIME) && !defined(HAVE_TIMEZONE)
|
||||||
#if !defined(timezone)
|
#if !defined(timezone)
|
||||||
extern char *timezone();
|
extern long timezone;
|
||||||
#endif
|
#endif
|
||||||
#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>
|
#include <sys/param.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _POSIX_PATH_MAX
|
#ifndef PATH_MAX
|
||||||
#define _POSIX_PATH_MAX 255
|
# ifdef MAXPATHLEN
|
||||||
#endif
|
# define PATH_MAX MAXPATHLEN
|
||||||
|
# else
|
||||||
|
# include <limits.h>
|
||||||
|
# ifndef PATH_MAX
|
||||||
|
# ifdef _POSIX_PATH_MAX
|
||||||
|
# define PATH_MAX _POSIX_PATH_MAX
|
||||||
|
# else
|
||||||
|
# define PATH_MAX 1024
|
||||||
|
# endif /* _POSIX_PATH_MAX */
|
||||||
|
# endif /* PATH_MAX */
|
||||||
|
# endif /* MAXPATHLEN */
|
||||||
|
#endif /* PATH_MAX */
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
|
||||||
#ifdef MAXPATHLEN
|
|
||||||
#define PATH_MAX MAXPATHLEN
|
|
||||||
#else
|
|
||||||
#define PATH_MAX _POSIX_PATH_MAX
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef POSIX
|
|
||||||
|
|
||||||
|
#ifdef HAVE_UTIME_H
|
||||||
#include <utime.h>
|
#include <utime.h>
|
||||||
#else
|
#else
|
||||||
#ifndef ALTOS
|
#ifndef ALTOS
|
||||||
@ -122,29 +156,33 @@ struct utimbuf
|
|||||||
int utime ();
|
int utime ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(USG) || defined(STDC_HEADERS)
|
#if STDC_HEADERS || HAVE_STRING_H
|
||||||
#include <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>
|
#include <memory.h>
|
||||||
#endif
|
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
|
||||||
|
|
||||||
#ifndef index
|
#ifndef index
|
||||||
#define index strchr
|
#define index strchr
|
||||||
#endif
|
#endif /* index */
|
||||||
|
|
||||||
#ifndef rindex
|
#ifndef rindex
|
||||||
#define rindex strrchr
|
#define rindex strrchr
|
||||||
#endif
|
#endif /* rindex */
|
||||||
#ifndef bcopy
|
|
||||||
#define bcopy(from, to, len) memcpy ((to), (from), (len))
|
|
||||||
#endif
|
|
||||||
#ifndef bzero
|
|
||||||
#define bzero(s, n) (void) memset ((s), 0, (n))
|
|
||||||
#endif
|
|
||||||
#ifndef bcmp
|
#ifndef bcmp
|
||||||
#define bcmp(s1, s2, n) memcmp((s1), (s2), (n))
|
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
|
||||||
#endif
|
#endif /* bcmp */
|
||||||
#else
|
|
||||||
|
#ifndef bzero
|
||||||
|
#define bzero(s, n) memset ((s), 0, (n))
|
||||||
|
#endif /* bzero */
|
||||||
|
|
||||||
|
#else /* not STDC_HJEADERS and not HAVE_STRING_H */
|
||||||
#include <strings.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>
|
#include <errno.h>
|
||||||
#ifdef STDC_HEADERS
|
#ifdef STDC_HEADERS
|
||||||
@ -157,34 +195,24 @@ char *calloc ();
|
|||||||
extern int errno;
|
extern int errno;
|
||||||
#endif
|
#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)
|
#if defined(USG) || defined(POSIX)
|
||||||
#include <fcntl.h>
|
|
||||||
char *getcwd ();
|
char *getcwd ();
|
||||||
#else
|
#else
|
||||||
#include <sys/file.h>
|
|
||||||
char *getwd ();
|
char *getwd ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_FCNTL_H
|
||||||
|
#include <fcntl.h>
|
||||||
|
#else
|
||||||
|
#include <sys/file.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SEEK_SET
|
#ifndef SEEK_SET
|
||||||
#define SEEK_SET 0
|
#define SEEK_SET 0
|
||||||
#define SEEK_CUR 1
|
#define SEEK_CUR 1
|
||||||
#define SEEK_END 2
|
#define SEEK_END 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef F_OK
|
#ifndef F_OK
|
||||||
#define F_OK 0
|
#define F_OK 0
|
||||||
#define X_OK 1
|
#define X_OK 1
|
||||||
@ -192,23 +220,23 @@ char *getwd ();
|
|||||||
#define R_OK 4
|
#define R_OK 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DIRENT
|
/* unistd.h defines _POSIX_VERSION on POSIX.1 systems. */
|
||||||
|
#if defined(DIRENT) || defined(_POSIX_VERSION)
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#ifdef direct
|
#define NLENGTH(dirent) (strlen((dirent)->d_name))
|
||||||
#undef direct
|
#else /* not (DIRENT or _POSIX_VERSION) */
|
||||||
#endif
|
#define dirent direct
|
||||||
#define direct dirent
|
#define NLENGTH(dirent) ((dirent)->d_namlen)
|
||||||
#else
|
#ifdef HAVE_SYS_NDIR_H
|
||||||
#ifdef SYSNDIR
|
|
||||||
#include <sys/ndir.h>
|
#include <sys/ndir.h>
|
||||||
#else
|
#endif
|
||||||
#ifdef NDIR
|
#ifdef HAVE_SYS_DIR_H
|
||||||
#include <ndir.h>
|
|
||||||
#else /* must be BSD */
|
|
||||||
#include <sys/dir.h>
|
#include <sys/dir.h>
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#ifdef HAVE_NDIR_H
|
||||||
#endif
|
#include <ndir.h>
|
||||||
|
#endif
|
||||||
|
#endif /* not (DIRENT or _POSIX_VERSION) */
|
||||||
|
|
||||||
/* Convert B 512-byte blocks to kilobytes if K is nonzero,
|
/* Convert B 512-byte blocks to kilobytes if K is nonzero,
|
||||||
otherwise return it unchanged. */
|
otherwise return it unchanged. */
|
||||||
@ -218,6 +246,17 @@ char *getwd ();
|
|||||||
#define lstat stat
|
#define lstat stat
|
||||||
#endif
|
#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
|
#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
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
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/types.h> /* For pid_t. */
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#else
|
#else
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
/* Read one line from standard input
|
/* 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"
|
.TH MKMODULES 1 "12 October 1991"
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright (c) 1989-1992, Brian Berliner
|
* Copyright (c) 1989-1992, Brian Berliner
|
||||||
*
|
*
|
||||||
* You may distribute under the terms of the GNU General Public License as
|
* 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
|
* mkmodules
|
||||||
*
|
*
|
||||||
@ -13,11 +13,9 @@
|
|||||||
|
|
||||||
#include "cvs.h"
|
#include "cvs.h"
|
||||||
|
|
||||||
#undef PATH_MAX
|
|
||||||
#define PATH_MAX 1024 /* max number of bytes in pathname */
|
|
||||||
|
|
||||||
#ifndef lint
|
#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
|
#endif
|
||||||
|
|
||||||
#ifndef DBLKSIZ
|
#ifndef DBLKSIZ
|
||||||
@ -30,30 +28,16 @@ char *Rcsbin = RCSBIN_DFLT;
|
|||||||
int noexec = 0; /* Here only to satisfy use in subr.c */
|
int noexec = 0; /* Here only to satisfy use in subr.c */
|
||||||
int trace = 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 PROTO((char *file, char *temp));
|
||||||
static int checkout_file (char *file, char *temp);
|
static void make_tempfile PROTO((char *temp));
|
||||||
static void make_tempfile (char *temp);
|
static void mkmodules_usage PROTO((void));
|
||||||
static void mkmodules_usage (void);
|
static void rename_rcsfile PROTO((char *temp, char *real));
|
||||||
static void rename_rcsfile (char *temp, char *real);
|
|
||||||
|
|
||||||
#ifndef MY_NDBM
|
#ifndef MY_NDBM
|
||||||
static void rename_dbmfile (char *temp);
|
static void rename_dbmfile PROTO((char *temp));
|
||||||
static void write_dbmfile (char *temp);
|
static void write_dbmfile PROTO((char *temp));
|
||||||
#endif /* !MY_NDBM */
|
#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
|
int
|
||||||
main (argc, argv)
|
main (argc, argv)
|
||||||
@ -62,15 +46,34 @@ main (argc, argv)
|
|||||||
{
|
{
|
||||||
extern char *getenv ();
|
extern char *getenv ();
|
||||||
char temp[PATH_MAX];
|
char temp[PATH_MAX];
|
||||||
char *cp;
|
char *cp, *last, *fname;
|
||||||
#ifdef MY_NDBM
|
#ifdef MY_NDBM
|
||||||
DBM *db;
|
DBM *db;
|
||||||
#endif
|
#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
|
* 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];
|
program_name = argv[0];
|
||||||
else
|
else
|
||||||
program_name++;
|
program_name++;
|
||||||
@ -127,7 +130,7 @@ main (argc, argv)
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error (0, 0,
|
error (0, 0,
|
||||||
"'cvs checkout' is less functional without a %s file",
|
"'cvs checkout' is less functional without a %s file",
|
||||||
CVSROOTADM_MODULES);
|
CVSROOTADM_MODULES);
|
||||||
break;
|
break;
|
||||||
@ -135,57 +138,63 @@ main (argc, argv)
|
|||||||
|
|
||||||
(void) unlink_file (temp);
|
(void) unlink_file (temp);
|
||||||
|
|
||||||
/*
|
/* Checkout the files that need it in CVSROOT dir */
|
||||||
* Now, check out the "loginfo" file, so that it is always up-to-date in
|
for (fileptr = filelist; fileptr && fileptr->filename; fileptr++) {
|
||||||
* the CVSROOT directory.
|
make_tempfile (temp);
|
||||||
*/
|
if (checkout_file (fileptr->filename, temp) == 0)
|
||||||
make_tempfile (temp);
|
rename_rcsfile (temp, fileptr->filename);
|
||||||
if (checkout_file (CVSROOTADM_LOGINFO, temp) == 0)
|
#if 0
|
||||||
rename_rcsfile (temp, CVSROOTADM_LOGINFO);
|
/*
|
||||||
else
|
* If there was some problem other than the file not existing,
|
||||||
error (0, 0,
|
* checkout_file already printed a real error message. If the
|
||||||
"no logging of 'cvs commit' messages is done without a %s file",
|
* file does not exist, it is harmless--it probably just means
|
||||||
CVSROOTADM_LOGINFO);
|
* that the repository was created with an old version of CVS
|
||||||
(void) unlink_file (temp);
|
* 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 */
|
||||||
* Now, check out the "rcsinfo" file, so that it is always up-to-date in
|
fp = fopen (CVSROOTADM_CHECKOUTLIST, "r");
|
||||||
* the CVSROOT directory.
|
if (fp)
|
||||||
*/
|
{
|
||||||
make_tempfile (temp);
|
/*
|
||||||
if (checkout_file (CVSROOTADM_RCSINFO, temp) == 0)
|
* File format:
|
||||||
rename_rcsfile (temp, CVSROOTADM_RCSINFO);
|
* [<whitespace>]<filename><whitespace><error message><end-of-line>
|
||||||
else
|
*/
|
||||||
error (0, 0,
|
for (; fgets (line, sizeof (line), fp) != NULL;)
|
||||||
"a %s file can be used to configure 'cvs commit' templates",
|
{
|
||||||
CVSROOTADM_RCSINFO);
|
if ((last = strrchr (line, '\n')) != NULL)
|
||||||
(void) unlink_file (temp);
|
*last = '\0'; /* strip the newline */
|
||||||
|
|
||||||
/*
|
/* Skip leading white space. */
|
||||||
* Now, check out the "editinfo" file, so that it is always up-to-date in
|
for (fname = line; *fname && isspace(*fname); fname++)
|
||||||
* the CVSROOT directory.
|
;
|
||||||
*/
|
|
||||||
make_tempfile (temp);
|
/* Find end of filename. */
|
||||||
if (checkout_file (CVSROOTADM_EDITINFO, temp) == 0)
|
for (cp = fname; *cp && !isspace(*cp); cp++)
|
||||||
rename_rcsfile (temp, CVSROOTADM_EDITINFO);
|
;
|
||||||
else
|
*cp = '\0';
|
||||||
error (0, 0,
|
|
||||||
"a %s file can be used to validate log messages",
|
make_tempfile (temp);
|
||||||
CVSROOTADM_EDITINFO);
|
if (checkout_file (fname, temp) == 0)
|
||||||
(void) unlink_file (temp);
|
{
|
||||||
|
rename_rcsfile (temp, fname);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (cp++; cp < last && *last && isspace(*last); cp++)
|
||||||
|
;
|
||||||
|
if (cp < last && *cp)
|
||||||
|
error (0, 0, cp, fname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(void) fclose (fp);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
else
|
|
||||||
error (0, 0,
|
|
||||||
"a %s file can be used to configure 'cvs commit' checking",
|
|
||||||
CVSROOTADM_COMMITINFO);
|
|
||||||
(void) unlink_file (temp);
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +260,7 @@ write_dbmfile (temp)
|
|||||||
error (1, errno, "cannot open dbm file %s for creation", temp);
|
error (1, errno, "cannot open dbm file %s for creation", temp);
|
||||||
for (cont = 0; fgets (line, sizeof (line), fp) != NULL;)
|
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 */
|
*cp = '\0'; /* strip the newline */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -370,8 +379,15 @@ rename_rcsfile (temp, real)
|
|||||||
char *real;
|
char *real;
|
||||||
{
|
{
|
||||||
char bak[50];
|
char bak[50];
|
||||||
|
struct stat statbuf;
|
||||||
|
char rcs[PATH_MAX];
|
||||||
|
|
||||||
|
/* 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) < 0) /* chmod 444 "temp" */
|
if (chmod (temp, 0444 | (statbuf.st_mode & 0111)) < 0)
|
||||||
error (0, errno, "warning: cannot chmod %s", temp);
|
error (0, errno, "warning: cannot chmod %s", temp);
|
||||||
(void) sprintf (bak, "%s%s", BAKPREFIX, real);
|
(void) sprintf (bak, "%s%s", BAKPREFIX, real);
|
||||||
(void) unlink_file (bak); /* rm .#loginfo */
|
(void) unlink_file (bak); /* rm .#loginfo */
|
||||||
|
Loading…
Reference in New Issue
Block a user