Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Import GNU rcs 5.7

  • Loading branch information...
commit a8b100e1ea88026b35254cbac292a517d7db61ca 1 parent f5a20c6
veego authored
Showing with 7,955 additions and 4,771 deletions.
  1. +4 −1 gnu/usr.bin/rcs/Makefile
  2. +4 −6 gnu/usr.bin/rcs/Makefile.inc
  3. +4 −3 gnu/usr.bin/rcs/ci/Makefile
  4. +171 −42 gnu/usr.bin/rcs/ci/ci.1
  5. +373 −217 gnu/usr.bin/rcs/ci/ci.c
  6. +4 −3 gnu/usr.bin/rcs/co/Makefile
  7. +228 −59 gnu/usr.bin/rcs/co/co.1
  8. +213 −153 gnu/usr.bin/rcs/co/co.c
  9. +38 −42 gnu/usr.bin/rcs/doc/rcs.ms
  10. +2 −0  gnu/usr.bin/rcs/doc/rcs_func.ms
  11. +4 −3 gnu/usr.bin/rcs/ident/Makefile
  12. +118 −10 gnu/usr.bin/rcs/ident/ident.1
  13. +111 −53 gnu/usr.bin/rcs/ident/ident.c
  14. +12 −5 gnu/usr.bin/rcs/lib/Makefile
  15. +150 −242 gnu/usr.bin/rcs/lib/conf.h
  16. +304 −305 gnu/usr.bin/rcs/lib/maketime.c
  17. +41 −0 gnu/usr.bin/rcs/lib/maketime.h
  18. +45 −34 gnu/usr.bin/rcs/lib/merger.c
  19. +658 −597 gnu/usr.bin/rcs/lib/partime.c
  20. +73 −0 gnu/usr.bin/rcs/lib/partime.h
  21. +210 −128 gnu/usr.bin/rcs/lib/rcsbase.h
  22. +645 −350 gnu/usr.bin/rcs/lib/rcsedit.c
  23. +78 −42 gnu/usr.bin/rcs/lib/rcsfcmp.c
  24. +309 −308 gnu/usr.bin/rcs/lib/rcsfnms.c
  25. +289 −37 gnu/usr.bin/rcs/lib/rcsgen.c
  26. +112 −80 gnu/usr.bin/rcs/lib/rcskeep.c
  27. +21 −15 gnu/usr.bin/rcs/lib/rcskeys.c
  28. +577 −257 gnu/usr.bin/rcs/lib/rcslex.c
  29. +7 −4 gnu/usr.bin/rcs/lib/rcsmap.c
  30. +308 −184 gnu/usr.bin/rcs/lib/rcsrev.c
  31. +120 −293 gnu/usr.bin/rcs/lib/rcssyn.c
  32. +193 −0 gnu/usr.bin/rcs/lib/rcstime.c
  33. +619 −219 gnu/usr.bin/rcs/lib/rcsutil.c
  34. +4 −0 gnu/usr.bin/rcs/lib/version.c
  35. +4 −3 gnu/usr.bin/rcs/merge/Makefile
  36. +81 −46 gnu/usr.bin/rcs/merge/merge.1
  37. +38 −20 gnu/usr.bin/rcs/merge/merge.c
  38. +5 −5 gnu/usr.bin/rcs/rcs/Makefile
  39. +83 −24 gnu/usr.bin/rcs/rcs/rcs.1
  40. +479 −401 gnu/usr.bin/rcs/rcs/rcs.c
  41. +229 −26 gnu/usr.bin/rcs/rcs/rcsfile.5
  42. +16 −4 gnu/usr.bin/rcs/rcs/rcsintro.1
  43. +4 −3 gnu/usr.bin/rcs/rcsclean/Makefile
  44. +39 −11 gnu/usr.bin/rcs/rcsclean/rcsclean.1
  45. +77 −39 gnu/usr.bin/rcs/rcsclean/rcsclean.c
  46. +4 −3 gnu/usr.bin/rcs/rcsdiff/Makefile
  47. +15 −7 gnu/usr.bin/rcs/rcsdiff/rcsdiff.1
  48. +153 −92 gnu/usr.bin/rcs/rcsdiff/rcsdiff.c
  49. +3 −1 gnu/usr.bin/rcs/rcsfreeze/Makefile
  50. +3 −1 gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.1
  51. +20 −19 gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.sh
  52. +4 −3 gnu/usr.bin/rcs/rcsmerge/Makefile
  53. +55 −4 gnu/usr.bin/rcs/rcsmerge/rcsmerge.1
  54. +122 −85 gnu/usr.bin/rcs/rcsmerge/rcsmerge.c
  55. +128 −69 gnu/usr.bin/rcs/rcstest
  56. +4 −3 gnu/usr.bin/rcs/rlog/Makefile
  57. +71 −15 gnu/usr.bin/rcs/rlog/rlog.1
  58. +269 −195 gnu/usr.bin/rcs/rlog/rlog.c
View
5 gnu/usr.bin/rcs/Makefile
@@ -1,3 +1,6 @@
-SUBDIR= lib ci co ident merge rcs rcsclean rcsdiff rcsmerge rlog rcsfreeze
+# $NetBSD: Makefile,v 1.1.1.2 1996/10/13 21:56:40 veego Exp $
+
+SUBDIR+=lib
+SUBDIR+=ci co ident merge rcs rcsclean rcsdiff rcsfreeze rcsmerge rlog
.include <bsd.subdir.mk>
View
10 gnu/usr.bin/rcs/Makefile.inc
@@ -1,7 +1,5 @@
-# Location of librcs
+# $NetBSD: Makefile.inc,v 1.1.1.2 1996/10/13 21:56:39 veego Exp $
-.if exists(${.CURDIR}/../lib/obj)
-LIBRCS= ${.CURDIR}/../lib/obj/librcs.a
-.else
-LIBRCS= ${.CURDIR}/../lib/librcs.a
-.endif
+LIBRCS!=cd $(.CURDIR)/../lib; \
+ printf "xxx:\n\techo \$${.OBJDIR}/librcs.a\n" | \
+ ${MAKE} -r -s -f - xxx | grep librcs
View
7 gnu/usr.bin/rcs/ci/Makefile
@@ -1,8 +1,9 @@
+# $NetBSD: Makefile,v 1.1.1.2 1996/10/13 21:56:45 veego Exp $
+
PROG= ci
-SRCS= ci.c
CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
+LDADD= ${LIBRCS} -lgnumalloc
+DPADD= ${LIBRCS} /usr/lib/libgnumalloc.a
.include "../../Makefile.inc"
.include <bsd.prog.mk>
View
213 gnu/usr.bin/rcs/ci/ci.1
@@ -1,9 +1,13 @@
+.\" $NetBSD: ci.1,v 1.1.1.2 1996/10/13 21:56:41 veego Exp $
+.\"
.de Id
.ds Rv \\$3
.ds Dt \\$4
..
-.Id ci.1,v 1.1.1.1 1993/06/18 04:22:11 jkh Exp
+.\" Id: ci.1,v 5.17 1995/06/16 06:19:24 eggert Exp
+.ds i \&\s-1ISO\s0
.ds r \&\s-1RCS\s0
+.ds u \&\s-1UTC\s0
.if n .ds - \%--
.if t .ds - \(em
.TH CI 1 \*(Dt GNU
@@ -41,7 +45,7 @@ new branch can be created. This restriction is not enforced
for the owner of the file if non-strict locking is used
(see
.BR rcs (1)).
-A lock held by someone else may be broken with the
+A lock held by someone else can be broken with the
.B rcs
command.
.PP
@@ -105,7 +109,9 @@ The number
.I rev
of the deposited revision can be given by any of the options
.BR \-f ,
+.BR \-i ,
.BR \-I ,
+.BR \-j ,
.BR \-k ,
.BR \-l ,
.BR \-M ,
@@ -114,7 +120,15 @@ of the deposited revision can be given by any of the options
or
.BR \-u .
.I rev
-may be symbolic, numeric, or mixed.
+can be symbolic, numeric, or mixed.
+Symbolic names in
+.I rev
+must already be defined;
+see the
+.B \-n
+and
+.B \-N
+options for assigning names during checkin.
If
.I rev
is
@@ -124,6 +138,15 @@ determines the revision number from keyword values in the working file.
.PP
If
.I rev
+begins with a period,
+then the default branch (normally the trunk) is prepended to it.
+If
+.I rev
+is a branch number followed by a period,
+then the latest revision on that branch is used.
+.PP
+If
+.I rev
is a revision number, it must be higher than the latest
one on the branch to which
.I rev
@@ -172,25 +195,28 @@ Exception: On the trunk, revisions can be appended to the end, but
not inserted.
.SH OPTIONS
.TP
-.BR \-r [\f2rev\fP]
-checks in a revision, releases the corresponding lock, and
-removes the working file. This is the default.
-.RS
-.PP
-The
+.BI \-r rev
+Check in revision
+.IR rev .
+.TP
+.BR \-r
+The bare
.B \-r
-option has an unusual meaning in
+option (without any revision) has an unusual meaning in
.BR ci .
-In other \*r commands,
+With other \*r commands, a bare
.B \-r
-merely specifies a revision number,
-but in
-.B ci
-it also releases a lock and removes the working file.
-See
+option specifies the most recent revision on the default branch,
+but with
+.BR ci ,
+a bare
+.B \-r
+option reestablishes the default behavior of releasing a lock and
+removing the working file, and is used to override any default
+.B \-l
+or
.B \-u
-for a tricky example.
-.RE
+options established by shell aliases or scripts.
.TP
.BR \-l [\f2rev\fP]
works like
@@ -213,6 +239,7 @@ immediately after checkin.
.PP
The
.BR \-l ,
+bare
.BR \-r ,
and
.B \-u
@@ -221,7 +248,7 @@ For example,
.B "ci\ \-u\ \-r"
is equivalent to
.B "ci\ \-r"
-because
+because bare
.B \-r
overrides
.BR \-u .
@@ -244,7 +271,7 @@ several sites should be checked in with the
.B \-k
option at these sites to
preserve the original number, date, author, and state.
-The extracted keyword values and the default log message may be overridden
+The extracted keyword values and the default log message can be overridden
with the options
.BR \-d ,
.BR \-m ,
@@ -259,6 +286,14 @@ unless
.B \-f
is given.
.TP
+.BR \-i [\f2rev\fP]
+initial checkin; report an error if the \*r file already exists.
+This avoids race conditions in certain applications.
+.TP
+.BR \-j [\f2rev\fP]
+just checkin and do not initialize;
+report an error if the \*r file does not already exist.
+.TP
.BR \-I [\f2rev\fP]
interactive mode;
the user is prompted and questioned
@@ -296,6 +331,18 @@ Use this option with care; it can confuse
uses the string
.I msg
as the log message for all revisions checked in.
+By convention, log messages that start with
+.B #
+are comments and are ignored by programs like GNU Emacs's
+.B vc
+package.
+Also, log messages that start with
+.BI { clumpname }
+(followed by white space) are meant to be clumped together if possible,
+even if they are associated with different files; the
+.BI { clumpname }
+label is used only for clumping,
+and is not considered to be part of the log message itself.
.TP
.BI \-n "name"
assigns the symbolic name
@@ -326,7 +373,7 @@ into the \*r file,
deleting the existing text.
The
.I file
-may not begin with
+cannot begin with
.BR \- .
.TP
.BI \-t\- string
@@ -356,6 +403,41 @@ For backward compatibility with older versions of \*r, a bare
option is ignored.
.RE
.TP
+.B \-T
+Set the \*r file's modification time to the new revision's time
+if the former precedes the latter and there is a new revision;
+preserve the \*r file's modification time otherwise.
+If you have locked a revision,
+.B ci
+usually updates the \*r file's modification time to the current time,
+because the lock is stored in the \*r file
+and removing the lock requires changing the \*r file.
+This can create an \*r file newer than the working file in one of two ways:
+first,
+.B "ci\ \-M"
+can create a working file with a date before the current time;
+second, when reverting to the previous revision
+the \*r file can change while the working file remains unchanged.
+These two cases can cause excessive recompilation caused by a
+.BR make (1)
+dependency of the working file on the \*r file.
+The
+.B \-T
+option inhibits this recompilation by lying about the \*r file's date.
+Use this option with care; it can suppress recompilation even when
+a checkin of one working file should affect
+another working file associated with the same \*r file.
+For example, suppose the \*r file's time is 01:00,
+the (changed) working file's time is 02:00,
+some other copy of the working file has a time of 03:00,
+and the current time is 04:00.
+Then
+.B "ci\ \-d\ \-T"
+sets the \*r file's time to 02:00 instead of the usual 04:00;
+this causes
+.BR make (1)
+to think (incorrectly) that the other copy is newer than the \*r file.
+.TP
.BI \-w "login"
uses
.I login
@@ -364,6 +446,9 @@ Useful for lying about the author, and for
.B \-k
if no author is available.
.TP
+.BI \-V
+Print \*r's version number.
+.TP
.BI \-V n
Emulate \*r version
.IR n .
@@ -375,9 +460,9 @@ for details.
specifies the suffixes for \*r files.
A nonempty suffix matches any pathname ending in the suffix.
An empty suffix matches any pathname of the form
-.BI RCS/ file
+.BI RCS/ path
or
-.IB path /RCS/ file.
+.IB path1 /RCS/ path2.
The
.B \-x
option can specify a list of suffixes
@@ -398,10 +483,49 @@ The default for
.IR suffixes
is installation-dependent; normally it is
.B ,v/
-for hosts like Unix that permit commas in file names,
+for hosts like Unix that permit commas in filenames,
and is empty (i.e. just the empty suffix) for other hosts.
+.TP
+.BI \-z zone
+specifies the date output format in keyword substitution,
+and specifies the default time zone for
+.I date
+in the
+.BI \-d date
+option.
+The
+.I zone
+should be empty, a numeric \*u offset, or the special string
+.B LT
+for local time.
+The default is an empty
+.IR zone ,
+which uses the traditional \*r format of \*u without any time zone indication
+and with slashes separating the parts of the date;
+otherwise, times are output in \*i 8601 format with time zone indication.
+For example, if local time is January 11, 1990, 8pm Pacific Standard Time,
+eight hours west of \*u,
+then the time is output as follows:
+.RS
+.LP
+.RS
+.nf
+.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u
+.ne 4
+\f2option\fP \f2time output\fP
+\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP
+\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP
+\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP
+.ta 4n +4n +4n +4n
+.fi
+.RE
+.LP
+The
+.B \-z
+option does not affect dates stored in \*r files,
+which are always \*u.
.SH "FILE NAMING"
-Pairs of \*r files and working files may be specified in three ways
+Pairs of \*r files and working files can be specified in three ways
(see also the
example section).
.PP
@@ -423,9 +547,9 @@ If
.I X
is empty,
.IB path1 /
-must be
+must start with
.B RCS/
-or must end in
+or must contain
.BR /RCS/ .
.PP
2) Only the \*r file is given. Then the working file is created in the current
@@ -516,7 +640,7 @@ preserves its read and execute permissions.
.B ci
always turns off all write permissions of \*r files.
.SH FILES
-Several temporary files may be created in the directory containing
+Temporary files are created in the directory containing
the working file, and also in the temporary directory (see
.B \s-1TMPDIR\s0
under
@@ -576,21 +700,23 @@ who can check in new revisions but cannot otherwise change the \*r files.
.SH "SETUID USE"
To prevent anybody but their \*r administrator from deleting revisions,
a set of users can employ setuid privileges as follows.
-.nr n \w'\(bu '+1n-1/1n
-.IP \(bu \nn
+.nr n \w'\(bu'+2n-1/1n
+.ds n \nn
+.if \n(.g .if r an-tag-sep .ds n \w'\(bu'u+\n[an-tag-sep]u
+.IP \(bu \*n
Check that the host supports \*r setuid use.
Consult a trustworthy expert if there are any doubts.
It is best if the
-.B seteuid()
+.B seteuid
system call works as described in Posix 1003.1a Draft 5,
because \*r can switch back and forth easily
between real and effective users, even if the real user is
.BR root .
If not, the second best is if the
-.B setuid()
+.B setuid
system call supports saved setuid
(the {\s-1_POSIX_SAVED_IDS\s0} behavior of Posix 1003.1-1990);
-this fails only if the real user is
+this fails only if the real or effective user is
.BR root .
If \*r detects any failure in setuid, it quits immediately.
.IP \(bu \nn
@@ -599,7 +725,7 @@ Choose a user
to serve as \*r administrator for the set of users.
Only
.I A
-will be able to invoke the
+can invoke the
.B rcs
command on the users' \*r files.
.I A
@@ -608,9 +734,9 @@ should not be
or any other user with special powers.
Mutually suspicious sets of users should use different administrators.
.IP \(bu \nn
-Choose a path name
+Choose a pathname
.I B
-that will be a directory of files to be executed by the users.
+to be a directory of files to be executed by the users.
.IP \(bu \nn
Have
.I A
@@ -733,8 +859,9 @@ Useful
options include
.BR \-q ,
.BR \-V ,
+.BR \-x ,
and
-.BR \-x .
+.BR \-z .
.TP
.B \s-1TMPDIR\s0
Name of the temporary directory.
@@ -755,14 +882,16 @@ The exit status is zero if and only if all operations were successful.
.SH IDENTIFICATION
Author: Walter F. Tichy.
.br
-Revision Number: \*(Rv; Release Date: \*(Dt.
+Manual Page Revision: \*(Rv; Release Date: \*(Dt.
.br
-Copyright \(co 1982, 1988, 1989 by Walter F. Tichy.
+Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
.br
-Copyright \(co 1990, 1991 by Paul Eggert.
+Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
.SH "SEE ALSO"
-co(1), ident(1), make(1), rcs(1), rcsclean(1), rcsdiff(1),
-rcsintro(1), rcsmerge(1), rlog(1), rcsfile(5)
+co(1),
+emacs(1),
+ident(1), make(1), rcs(1), rcsclean(1), rcsdiff(1),
+rcsintro(1), rcsmerge(1), rlog(1), setuid(2), rcsfile(5)
.br
Walter F. Tichy,
\*r\*-A System for Version Control,
View
590 gnu/usr.bin/rcs/ci/ci.c
@@ -1,5 +1,9 @@
-/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991 by Paul Eggert
+/* $NetBSD: ci.c,v 1.1.1.2 1996/10/13 21:56:43 veego Exp $ */
+
+/* Check in revisions of RCS files from working files. */
+
+/* Copyright 1982, 1988, 1989 Walter Tichy
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
Distributed under license by the Free Software Foundation, Inc.
This file is part of RCS.
@@ -15,8 +19,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with RCS; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+along with RCS; see the file COPYING.
+If not, write to the Free Software Foundation,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Report problems and direct all questions to:
@@ -25,18 +30,52 @@ Report problems and direct all questions to:
*/
/*
- * RCS checkin operation
- */
-/*******************************************************************
- * check revisions into RCS files
- *******************************************************************
- */
-
-
-
-/* ci.c,v
- * Revision 1.1.1.1 1993/06/18 04:22:10 jkh
- * Updated GNU utilities
+ * $Log: ci.c,v $
+ * Revision 1.1.1.2 1996/10/13 21:56:43 veego
+ * Import GNU rcs 5.7
+ *
+ * Revision 5.30 1995/06/16 06:19:24 eggert
+ * Update FSF address.
+ *
+ * Revision 5.29 1995/06/01 16:23:43 eggert
+ * (main): Add -kb.
+ * Use `cmpdate', not `cmpnum', to compare dates.
+ * This is for MKS RCS's incompatible 20th-century date format.
+ * Don't worry about errno after ftruncate fails.
+ * Fix input file rewinding bug when large_memory && !maps_memory
+ * and checking in a branch tip.
+ *
+ * (fixwork): Fall back on chmod if fchmod fails, since it might be ENOSYS.
+ *
+ * Revision 5.28 1994/03/20 04:52:58 eggert
+ * Do not generate a corrupted RCS file if the user modifies the working file
+ * while `ci' is running.
+ * Do not remove the lock when `ci -l' reverts.
+ * Move buffer-flushes out of critical sections, since they aren't critical.
+ * Use ORCSerror to clean up after a fatal error.
+ * Specify subprocess input via file descriptor, not file name.
+ *
+ * Revision 5.27 1993/11/09 17:40:15 eggert
+ * -V now prints version on stdout and exits. Don't print usage twice.
+ *
+ * Revision 5.26 1993/11/03 17:42:27 eggert
+ * Add -z. Don't subtract from RCS file timestamp even if -T.
+ * Scan for and use Name keyword if -k.
+ * Don't discard ignored phrases. Improve quality of diagnostics.
+ *
+ * Revision 5.25 1992/07/28 16:12:44 eggert
+ * Add -i, -j, -V. Check that working and RCS files are distinct.
+ *
+ * Revision 5.24 1992/02/17 23:02:06 eggert
+ * `-rREV' now just specifies a revision REV; only bare `-r' reverts to default.
+ * Add -T.
+ *
+ * Revision 5.23 1992/01/27 16:42:51 eggert
+ * Always unlock branchpoint if caller has a lock.
+ * Add support for bad_chmod_close, bad_creat0. lint -> RCS_lint
+ *
+ * Revision 5.22 1992/01/06 02:42:34 eggert
+ * Invoke utime() before chmod() to keep some buggy systems happy.
*
* Revision 5.21 1991/11/20 17:58:07 eggert
* Don't read the delta tree from a nonexistent RCS file.
@@ -217,16 +256,16 @@ struct Symrev {
};
static char const *getcurdate P((void));
-static int addbranch P((struct hshentry*,struct buf*));
+static int addbranch P((struct hshentry*,struct buf*,int));
static int addelta P((void));
static int addsyms P((char const*));
-static int fixwork P((mode_t,char const*));
+static int fixwork P((mode_t,time_t));
static int removelock P((struct hshentry*));
-static int xpandfile P((RILE*,char const*,struct hshentry const*,char const**));
+static int xpandfile P((RILE*,struct hshentry const*,char const**,int));
static struct cbuf getlogmsg P((void));
static void cleanup P((void));
static void incnum P((char const*,struct buf*));
-static void addassoclst P((int, char *));
+static void addassoclst P((int,char const*));
static FILE *exfile;
static RILE *workptr; /* working file pointer */
@@ -239,37 +278,41 @@ static struct hshentries *gendeltas; /* deltas to be generated */
static struct hshentry *targetdelta; /* old delta to be generated */
static struct hshentry newdelta; /* new delta to be inserted */
static struct stat workstat;
-static struct Symrev *assoclst, *lastassoc;
+static struct Symrev *assoclst, **nextassoc;
-mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
+mainProg(ciId, "ci", "Id: ci.c,v 5.30 1995/06/16 06:19:24 eggert Exp")
{
static char const cmdusage[] =
- "\nci usage: ci -{fklqru}[rev] -mmsg -{nN}name -sstate -t[textfile] -Vn file ...";
+ "\nci usage: ci -{fIklMqru}[rev] -d[date] -mmsg -{nN}name -sstate -ttext -T -Vn -wwho -xsuff -zzone file ...";
static char const default_state[] = DEFAULTSTATE;
char altdate[datesize];
char olddate[datesize];
- char newdatebuf[datesize], targetdatebuf[datesize];
+ char newdatebuf[datesize + zonelenmax];
+ char targetdatebuf[datesize + zonelenmax];
char *a, **newargv, *textfile;
char const *author, *krev, *rev, *state;
- char const *diffilename, *expfilename;
- char const *workdiffname, *newworkfilename;
- char const *mtime;
- int lockflag, lockthis, mtimeflag, removedlock;
+ char const *diffname, *expname;
+ char const *newworkname;
+ int initflag, mustread;
+ int lockflag, lockthis, mtimeflag, removedlock, Ttimeflag;
int r;
- int changedRCS, changework, newhead;
+ int changedRCS, changework, dolog, newhead;
int usestatdate; /* Use mod time of file for -d. */
mode_t newworkmode; /* mode for working file */
+ time_t mtime, wtime;
struct hshentry *workdelta;
-
+
setrid();
- author = rev = state = textfile = nil;
- lockflag = false;
+ author = rev = state = textfile = 0;
+ initflag = lockflag = mustread = false;
mtimeflag = false;
+ Ttimeflag = false;
altdate[0]= '\0'; /* empty alternate date for -d */
usestatdate=false;
suffixes = X_DEFAULT;
+ nextassoc = &assoclst;
argc = getRCSINIT(argc, argv, &newargv);
argv = newargv;
@@ -277,7 +320,13 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
switch (*a++) {
case 'r':
+ if (*a)
+ goto revno;
keepworkingfile = lockflag = false;
+ break;
+
+ case 'l':
+ keepworkingfile = lockflag = true;
revno:
if (*a) {
if (rev) warn("redefinition of revision number");
@@ -285,14 +334,18 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
}
break;
- case 'l':
- keepworkingfile=lockflag=true;
- goto revno;
-
case 'u':
keepworkingfile=true; lockflag=false;
goto revno;
+ case 'i':
+ initflag = true;
+ goto revno;
+
+ case 'j':
+ mustread = true;
+ goto revno;
+
case 'I':
interactiveflag = true;
goto revno;
@@ -313,7 +366,7 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
if (msg.size) redefined('m');
msg = cleanlogmsg(a, strlen(a));
if (!msg.size)
- warn("missing message for -m option");
+ error("missing message for -m option");
break;
case 'n':
@@ -321,7 +374,7 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
error("missing symbolic name after -n");
break;
}
- checksid(a);
+ checkssym(a);
addassoclst(false, a);
break;
@@ -330,7 +383,7 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
error("missing symbolic name after -N");
break;
}
- checksid(a);
+ checkssym(a);
addassoclst(true, a);
break;
@@ -340,7 +393,7 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
checksid(a);
state = a;
} else
- warn("missing state for -s option");
+ error("missing state for -s option");
break;
case 't':
@@ -353,7 +406,7 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
case 'd':
if (altdate[0] || usestatdate)
redefined('d');
- altdate[0] = 0;
+ altdate[0] = '\0';
if (!(usestatdate = !*a))
str2date(a, altdate);
break;
@@ -368,7 +421,7 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
checksid(a);
author = a;
} else
- warn("missing author for -w option");
+ error("missing author for -w option");
break;
case 'x':
@@ -379,26 +432,34 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
setRCSversion(*argv);
break;
+ case 'z':
+ zone_set(a);
+ break;
-
+ case 'T':
+ if (!*a) {
+ Ttimeflag = true;
+ break;
+ }
+ /* fall into */
default:
- faterror("unknown option: %s%s", *argv, cmdusage);
+ error("unknown option: %s%s", *argv, cmdusage);
};
} /* end processing of options */
- if (argc<1) faterror("no input file%s", cmdusage);
-
- /* now handle all filenames */
- do {
- targetdelta=nil;
+ /* Handle all pathnames. */
+ if (nerror) cleanup();
+ else if (argc < 1) faterror("no input file%s", cmdusage);
+ else for (; 0 < argc; cleanup(), ++argv, --argc) {
+ targetdelta = 0;
ffree();
- switch (pairfilenames(argc, argv, rcswriteopen, false, false)) {
+ switch (pairnames(argc, argv, rcswriteopen, mustread, false)) {
case -1: /* New RCS file */
# if has_setuid && has_getuid
if (euid() != ruid()) {
- error("setuid initial checkin prohibited; use `rcs -i -a' first");
+ workerror("setuid initial checkin prohibited; use `rcs -i -a' first");
continue;
}
# endif
@@ -409,38 +470,52 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
continue;
case 1: /* Normal checkin with prev . RCS file */
+ if (initflag) {
+ rcserror("already exists");
+ continue;
+ }
rcsinitflag = !Head;
}
- /* now RCSfilename contains the name of the RCS file, and
- * workfilename contains the name of the working file.
+ /*
+ * RCSname contains the name of the RCS file, and
+ * workname contains the name of the working file.
* If the RCS file exists, finptr contains the file descriptor for the
- * RCS file. The admin node is initialized.
- * RCSstat is set.
+ * RCS file, and RCSstat is set. The admin node is initialized.
*/
- diagnose("%s <-- %s\n", RCSfilename,workfilename);
+ diagnose("%s <-- %s\n", RCSname, workname);
- if (!(workptr = Iopen(workfilename, FOPEN_R_WORK, &workstat))) {
- eerror(workfilename);
+ if (!(workptr = Iopen(workname, FOPEN_R_WORK, &workstat))) {
+ eerror(workname);
continue;
}
- if (finptr && !checkaccesslist()) continue; /* give up */
+
+ if (finptr) {
+ if (same_file(RCSstat, workstat, 0)) {
+ rcserror("RCS file is the same as working file %s.",
+ workname
+ );
+ continue;
+ }
+ if (!checkaccesslist())
+ continue;
+ }
krev = rev;
if (keepflag) {
/* get keyword values from working file */
if (!getoldkeys(workptr)) continue;
if (!rev && !*(krev = prevrev.string)) {
- error("can't find a revision number in %s",workfilename);
+ workerror("can't find a revision number");
continue;
}
if (!*prevdate.string && *altdate=='\0' && usestatdate==false)
- warn("can't find a date in %s", workfilename);
+ workwarn("can't find a date");
if (!*prevauthor.string && !author)
- warn("can't find an author in %s", workfilename);
+ workwarn("can't find an author");
if (!*prevstate.string && !state)
- warn("can't find a state in %s", workfilename);
+ workwarn("can't find a state");
} /* end processing keepflag */
/* Read the delta tree. */
@@ -456,17 +531,20 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
continue;
newdelta.num = newdelnum.string;
- newdelta.branches=nil;
- newdelta.lockedby=nil; /*might be changed by addlock() */
+ newdelta.branches = 0;
+ newdelta.lockedby = 0; /* This might be changed by addlock(). */
newdelta.selector = true;
+ newdelta.name = 0;
+ clear_buf(&newdelta.ig);
+ clear_buf(&newdelta.igtext);
/* set author */
- if (author!=nil)
+ if (author)
newdelta.author=author; /* set author given by -w */
else if (keepflag && *prevauthor.string)
newdelta.author=prevauthor.string; /* preserve old author if possible*/
else newdelta.author=getcaller();/* otherwise use caller's id */
newdelta.state = default_state;
- if (state!=nil)
+ if (state)
newdelta.state=state; /* set state given by -s */
else if (keepflag && *prevstate.string)
newdelta.state=prevstate.string; /* preserve old state if possible */
@@ -482,9 +560,9 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
} else
newdelta.date = getcurdate(); /* use current date */
/* now check validity of date -- needed because of -d and -k */
- if (targetdelta!=nil &&
- cmpnum(newdelta.date,targetdelta->date) < 0) {
- error("Date %s precedes %s in existing revision %s.",
+ if (targetdelta &&
+ cmpdate(newdelta.date,targetdelta->date) < 0) {
+ rcserror("Date %s precedes %s in revision %s.",
date2str(newdelta.date, newdatebuf),
date2str(targetdelta->date, targetdatebuf),
targetdelta->num
@@ -493,48 +571,46 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
}
- if (lockflag && addlock(&newdelta) < 0) continue;
+ if (lockflag && addlock(&newdelta, true) < 0) continue;
+
+ if (keepflag && *prevname.string)
+ if (addsymbol(newdelta.num, prevname.string, false) < 0)
+ continue;
if (!addsyms(newdelta.num))
continue;
- putadmin(frewrite);
+ putadmin();
puttree(Head,frewrite);
putdesc(false,textfile);
- changework = Expand != OLD_EXPAND;
+ changework = Expand < MIN_UNCHANGED_EXPAND;
+ dolog = true;
lockthis = lockflag;
workdelta = &newdelta;
/* build rest of file */
if (rcsinitflag) {
- diagnose("initial revision: %s\n", newdelnum.string);
+ diagnose("initial revision: %s\n", newdelta.num);
/* get logmessage */
newdelta.log=getlogmsg();
- if (!putdftext(newdelnum.string,newdelta.log,workptr,frewrite,false)) continue;
+ putdftext(&newdelta, workptr, frewrite, false);
RCSstat.st_mode = workstat.st_mode;
+ RCSstat.st_nlink = 0;
changedRCS = true;
} else {
- diffilename = maketemp(0);
- workdiffname = workfilename;
- if (workdiffname[0] == '+') {
- /* Some diffs have options with leading '+'. */
- char *dp = ftnalloc(char, strlen(workfilename)+3);
- workdiffname = dp;
- *dp++ = '.';
- *dp++ = SLASH;
- VOID strcpy(dp, workfilename);
- }
+ diffname = maketemp(0);
newhead = Head == &newdelta;
if (!newhead)
foutptr = frewrite;
- expfilename = buildrevision(
+ expname = buildrevision(
gendeltas, targetdelta, (FILE*)0, false
);
if (
!forceciflag &&
+ strcmp(newdelta.state, targetdelta->state) == 0 &&
(changework = rcsfcmp(
- workptr, &workstat, expfilename, targetdelta
+ workptr, &workstat, expname, targetdelta
)) <= 0
) {
diagnose("file is unchanged; reverting to previous revision %s\n",
@@ -544,12 +620,8 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
diagnose("previous revision was not locked; ignoring -l option\n");
lockthis = 0;
}
- if (!(changedRCS =
- lockflag < removedlock
- || assoclst
- || newdelta.state != default_state
- && strcmp(newdelta.state, targetdelta->state) != 0
- ))
+ dolog = false;
+ if (! (changedRCS = lockflag<removedlock || assoclst))
workdelta = targetdelta;
else {
/*
@@ -558,20 +630,22 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
*/
long hwm = ftell(frewrite);
int bad_truncate;
- if (fseek(frewrite, 0L, SEEK_SET) != 0)
- Oerror();
+ Orewind(frewrite);
+
+ /*
+ * Work around a common ftruncate() bug:
+ * NFS won't let you truncate a file that you
+ * currently lack permissions for, even if you
+ * had permissions when you opened it.
+ * Also, Posix 1003.1b-1993 sec 5.6.7.2 p 128 l 1022
+ * says ftruncate might fail because it's not supported.
+ */
# if !has_ftruncate
- bad_truncate = 1;
-# else
- /*
- * Work around a common ftruncate() bug.
- * We can't rely on has_truncate, because we might
- * be using a filesystem exported to us via NFS.
- */
- bad_truncate = ftruncate(fileno(frewrite),(off_t)0);
- if (bad_truncate && errno != EACCES)
- Oerror();
+# undef ftruncate
+# define ftruncate(fd,length) (-1)
# endif
+ bad_truncate = ftruncate(fileno(frewrite), (off_t)0);
+
Irewind(finptr);
Lexinit();
getadmin();
@@ -584,11 +658,11 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
workdelta->log = targetdelta->log;
if (newdelta.state != default_state)
workdelta->state = newdelta.state;
- if (removedlock && removelock(workdelta)<0)
+ if (lockthis<removedlock && removelock(workdelta)<0)
continue;
if (!addsyms(workdelta->num))
continue;
- if (!dorewrite(true, true))
+ if (dorewrite(true, true) != 0)
continue;
fastcopy(finptr, frewrite);
if (bad_truncate)
@@ -598,48 +672,127 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
afputc('\n', frewrite);
}
} else {
+ int wfd = Ifileno(workptr);
+ struct stat checkworkstat;
+ char const *diffv[6 + !!OPEN_O_BINARY], **diffp;
+# if large_memory && !maps_memory
+ FILE *wfile = workptr->stream;
+ long wfile_off;
+# endif
+# if !has_fflush_input && !(large_memory && maps_memory)
+ off_t wfd_off;
+# endif
+
diagnose("new revision: %s; previous revision: %s\n",
- newdelnum.string, targetdelta->num
+ newdelta.num, targetdelta->num
);
newdelta.log = getlogmsg();
- switch (run((char*)0, diffilename,
- DIFF DIFF_FLAGS,
- newhead ? workdiffname : expfilename,
- newhead ? expfilename : workdiffname,
- (char*)0
- )) {
+# if !large_memory
+ Irewind(workptr);
+# if has_fflush_input
+ if (fflush(workptr) != 0)
+ Ierror();
+# endif
+# else
+# if !maps_memory
+ if (
+ (wfile_off = ftell(wfile)) == -1
+ || fseek(wfile, 0L, SEEK_SET) != 0
+# if has_fflush_input
+ || fflush(wfile) != 0
+# endif
+ )
+ Ierror();
+# endif
+# endif
+# if !has_fflush_input && !(large_memory && maps_memory)
+ wfd_off = lseek(wfd, (off_t)0, SEEK_CUR);
+ if (wfd_off == -1
+ || (wfd_off != 0
+ && lseek(wfd, (off_t)0, SEEK_SET) != 0))
+ Ierror();
+# endif
+ diffp = diffv;
+ *++diffp = DIFF;
+ *++diffp = DIFFFLAGS;
+# if OPEN_O_BINARY
+ if (Expand == BINARY_EXPAND)
+ *++diffp = "--binary";
+# endif
+ *++diffp = newhead ? "-" : expname;
+ *++diffp = newhead ? expname : "-";
+ *++diffp = 0;
+ switch (runv(wfd, diffname, diffv)) {
case DIFF_FAILURE: case DIFF_SUCCESS: break;
- default: faterror("diff failed");
+ default: rcsfaterror("diff failed");
}
+# if !has_fflush_input && !(large_memory && maps_memory)
+ if (lseek(wfd, wfd_off, SEEK_CUR) == -1)
+ Ierror();
+# endif
+# if large_memory && !maps_memory
+ if (fseek(wfile, wfile_off, SEEK_SET) != 0)
+ Ierror();
+# endif
if (newhead) {
Irewind(workptr);
- if (!putdftext(newdelnum.string,newdelta.log,workptr,frewrite,false)) continue;
- if (!putdtext(targetdelta->num,targetdelta->log,diffilename,frewrite,true)) continue;
+ putdftext(&newdelta, workptr, frewrite, false);
+ if (!putdtext(targetdelta,diffname,frewrite,true)) continue;
} else
- if (!putdtext(newdelnum.string,newdelta.log,diffilename,frewrite,true)) continue;
+ if (!putdtext(&newdelta,diffname,frewrite,true)) continue;
+
+ /*
+ * Check whether the working file changed during checkin,
+ * to avoid producing an inconsistent RCS file.
+ */
+ if (
+ fstat(wfd, &checkworkstat) != 0
+ || workstat.st_mtime != checkworkstat.st_mtime
+ || workstat.st_size != checkworkstat.st_size
+ ) {
+ workerror("file changed during checkin");
+ continue;
+ }
+
changedRCS = true;
}
}
- if (!donerewrite(changedRCS))
+
+ /* Deduce time_t of new revision if it is needed later. */
+ wtime = (time_t)-1;
+ if (mtimeflag | Ttimeflag)
+ wtime = date2time(workdelta->date);
+
+ if (donerewrite(changedRCS,
+ !Ttimeflag ? (time_t)-1
+ : finptr && wtime < RCSstat.st_mtime ? RCSstat.st_mtime
+ : wtime
+ ) != 0)
continue;
if (!keepworkingfile) {
Izclose(&workptr);
- r = un_link(workfilename); /* Get rid of old file */
+ r = un_link(workname); /* Get rid of old file */
} else {
newworkmode = WORKMODE(RCSstat.st_mode,
! (Expand==VAL_EXPAND || lockthis < StrictLocks)
);
- mtime = mtimeflag ? workdelta->date : (char const*)0;
+ mtime = mtimeflag ? wtime : (time_t)-1;
/* Expand if it might change or if we can't fix mode, time. */
if (changework || (r=fixwork(newworkmode,mtime)) != 0) {
Irewind(workptr);
/* Expand keywords in file. */
locker_expansion = lockthis;
+ workdelta->name =
+ namedrev(
+ assoclst ? assoclst->ssymbol
+ : keepflag && *prevname.string ? prevname.string
+ : rev,
+ workdelta
+ );
switch (xpandfile(
- workptr, workfilename,
- workdelta, &newworkfilename
+ workptr, workdelta, &newworkname, dolog
)) {
default:
continue;
@@ -654,24 +807,24 @@ mainProg(ciId, "ci", "ci.c,v 1.1.1.1 1993/06/18 04:22:10 jkh Exp")
break;
/* fall into */
case 1:
- if (!(r = setfiledate(newworkfilename,mtime))) {
- Izclose(&workptr);
- ignoreints();
- r = chnamemod(&exfile, newworkfilename, workfilename, newworkmode);
- keepdirtemp(newworkfilename);
- restoreints();
- }
+ Izclose(&workptr);
+ aflush(exfile);
+ ignoreints();
+ r = chnamemod(&exfile, newworkname,
+ workname, 1, newworkmode, mtime
+ );
+ keepdirtemp(newworkname);
+ restoreints();
}
}
}
if (r != 0) {
- eerror(workfilename);
+ eerror(workname);
continue;
}
diagnose("done\n");
- } while (cleanup(),
- ++argv, --argc >=1);
+ }
tempunlink();
exitmain(exitstatus);
@@ -685,16 +838,17 @@ cleanup()
Izclose(&workptr);
Ozclose(&exfile);
Ozclose(&fcopy);
- Ozclose(&frewrite);
+ ORCSclose();
dirtempunlink();
}
-#if lint
+#if RCS_lint
# define exiterr ciExit
#endif
- exiting void
+ void
exiterr()
{
+ ORCSerror();
dirtempunlink();
tempunlink();
_exit(EXIT_FAILURE);
@@ -713,26 +867,28 @@ addelta()
*/
{
register char *tp;
- register unsigned i;
+ register int i;
int removedlock;
- unsigned newdnumlength; /* actual length of new rev. num. */
+ int newdnumlength; /* actual length of new rev. num. */
newdnumlength = countnumflds(newdelnum.string);
if (rcsinitflag) {
/* this covers non-existing RCS file and a file initialized with rcs -i */
- if ((newdnumlength==0)&&(Dbranch!=nil)) {
+ if (newdnumlength==0 && Dbranch) {
bufscpy(&newdelnum, Dbranch);
newdnumlength = countnumflds(Dbranch);
}
if (newdnumlength==0) bufscpy(&newdelnum, "1.1");
else if (newdnumlength==1) bufscat(&newdelnum, ".1");
else if (newdnumlength>2) {
- error("Branch point doesn't exist for %s.",newdelnum.string);
+ rcserror("Branch point doesn't exist for revision %s.",
+ newdelnum.string
+ );
return -1;
} /* newdnumlength == 2 is OK; */
Head = &newdelta;
- newdelta.next=nil;
+ newdelta.next = 0;
return 0;
}
if (newdnumlength==0) {
@@ -755,11 +911,11 @@ addelta()
} else if (!targetdelta->next && countnumflds(targetdelta->num)>2) {
/* new tip revision on side branch */
targetdelta->next= &newdelta;
- newdelta.next = nil;
+ newdelta.next = 0;
} else {
/* middle revision; start a new branch */
bufscpy(&newdelnum, "");
- return addbranch(targetdelta,&newdelnum);
+ return addbranch(targetdelta, &newdelnum, 1);
}
incnum(targetdelta->num, &newdelnum);
return 1; /* successful use of existing lock */
@@ -768,7 +924,7 @@ addelta()
/* no existing lock; try Dbranch */
/* update newdelnum */
if (StrictLocks || !myself(RCSstat.st_uid)) {
- error("no lock set by %s",getcaller());
+ rcserror("no lock set by %s", getcaller());
return -1;
}
if (Dbranch) {
@@ -790,8 +946,9 @@ addelta()
bufscat(&newdelnum, ".1");
}
if (cmpnum(newdelnum.string,Head->num) <= 0) {
- error("deltanumber %s too low; must be higher than %s",
- newdelnum.string, Head->num);
+ rcserror("revision %s too low; must be higher than %s",
+ newdelnum.string, Head->num
+ );
return -1;
}
targetdelta = Head;
@@ -806,44 +963,46 @@ addelta()
/* put new revision on side branch */
/*first, get branch point */
tp = newdelnum.string;
- for (i = newdnumlength - (newdnumlength&1 ^ 1); (--i); )
+ for (i = newdnumlength - ((newdnumlength&1) ^ 1); --i; )
while (*tp++ != '.')
- ;
+ continue;
*--tp = 0; /* Kill final dot to get old delta temporarily. */
- if (!(targetdelta=genrevs(newdelnum.string,(char*)nil,(char*)nil,(char*)nil,&gendeltas)))
+ if (!(targetdelta=genrevs(newdelnum.string,(char*)0,(char*)0,(char*)0,&gendeltas)))
return -1;
if (cmpnum(targetdelta->num, newdelnum.string) != 0) {
- error("can't find branchpoint %s", newdelnum.string);
+ rcserror("can't find branch point %s", newdelnum.string);
return -1;
}
*tp = '.'; /* Restore final dot. */
- return addbranch(targetdelta,&newdelnum);
+ return addbranch(targetdelta, &newdelnum, 0);
}
}
static int
-addbranch(branchpoint,num)
+addbranch(branchpoint, num, removedlock)
struct hshentry *branchpoint;
struct buf *num;
+ int removedlock;
/* adds a new branch and branch delta at branchpoint.
* If num is the null string, appends the new branch, incrementing
* the highest branch number (initially 1), and setting the level number to 1.
* the new delta and branchhead are in globals newdelta and newbranch, resp.
* the new number is placed into num.
* Return -1 on error, 1 if a lock is removed, 0 otherwise.
+ * If REMOVEDLOCK is 1, a lock was already removed.
*/
{
struct branchhead *bhead, **btrail;
struct buf branchnum;
- int removedlock, result;
- unsigned field, numlength;
+ int result;
+ int field, numlength;
static struct branchhead newbranch; /* new branch to be inserted */
numlength = countnumflds(num->string);
- if (branchpoint->branches==nil) {
+ if (!branchpoint->branches) {
/* start first branch */
branchpoint->branches = &newbranch;
if (numlength==0) {
@@ -851,7 +1010,7 @@ addbranch(branchpoint,num)
bufscat(num, ".1.1");
} else if (numlength&1)
bufscat(num, ".1");
- newbranch.nextbranch=nil;
+ newbranch.nextbranch = 0;
} else if (numlength==0) {
/* append new branch to the end */
@@ -863,10 +1022,10 @@ addbranch(branchpoint,num)
incnum(branchnum.string, num);
bufautoend(&branchnum);
bufscat(num, ".1");
- newbranch.nextbranch=nil;
+ newbranch.nextbranch = 0;
} else {
/* place the branch properly */
- field = numlength - (numlength&1 ^ 1);
+ field = numlength - ((numlength&1) ^ 1);
/* field of branch number */
btrail = &branchpoint->branches;
while (0 < (result=cmpnumfld(num->string,(*btrail)->hsh->num,field))) {
@@ -885,17 +1044,22 @@ addbranch(branchpoint,num)
/* branch exists; append to end */
bufautobegin(&branchnum);
getbranchno(num->string, &branchnum);
- targetdelta=genrevs(branchnum.string,(char*)nil,
- (char*)nil,(char*)nil,&gendeltas);
+ targetdelta = genrevs(
+ branchnum.string, (char*)0, (char*)0, (char*)0,
+ &gendeltas
+ );
bufautoend(&branchnum);
if (!targetdelta)
return -1;
if (cmpnum(num->string,targetdelta->num) <= 0) {
- error("deltanumber %s too low; must be higher than %s",
- num->string,targetdelta->num);
+ rcserror("revision %s too low; must be higher than %s",
+ num->string, targetdelta->num
+ );
return -1;
}
- if (0 <= (removedlock = removelock(targetdelta))) {
+ if (!removedlock
+ && 0 <= (removedlock = removelock(targetdelta))
+ ) {
if (numlength&1)
incnum(targetdelta->num,num);
targetdelta->next = &newdelta;
@@ -906,8 +1070,11 @@ addbranch(branchpoint,num)
}
}
newbranch.hsh = &newdelta;
- newdelta.next=nil;
- return 0;
+ newdelta.next = 0;
+ if (branchpoint->lockedby)
+ if (strcmp(branchpoint->lockedby, getcaller()) == 0)
+ return removelock(branchpoint); /* This returns 1. */
+ return removedlock;
}
static int
@@ -917,7 +1084,7 @@ addsyms(num)
register struct Symrev *p;
for (p = assoclst; p; p = p->nextsym)
- if (!addsymbol(num, p->ssymbol, p->override))
+ if (addsymbol(num, p->ssymbol, p->override) < 0)
return false;
return true;
}
@@ -969,7 +1136,7 @@ struct hshentry * delta;
* return 0; return 1 if a lock is actually removed.
*/
{
- register struct lock *next, **trail;
+ register struct rcslock *next, **trail;
char const *num;
num=delta->num;
@@ -981,12 +1148,12 @@ struct hshentry * delta;
delta->lockedby = 0;
return 1;
} else {
- error("revision %s locked by %s",num,next->login);
+ rcserror("revision %s locked by %s", num, next->login);
return -1;
}
if (!StrictLocks && myself(RCSstat.st_uid))
return 0;
- error("no lock set by %s for revision %s", getcaller(), num);
+ rcserror("no lock set by %s for revision %s", getcaller(), num);
return -1;
}
@@ -997,76 +1164,70 @@ getcurdate()
/* Return a pointer to the current date. */
{
static char buffer[datesize]; /* date buffer */
- time_t t;
- if (!buffer[0]) {
- t = time((time_t *)0);
- if (t == -1)
- faterror("time not available");
- time2date(t, buffer);
- }
+ if (!buffer[0])
+ time2date(now(), buffer);
return buffer;
}
static int
#if has_prototypes
-fixwork(mode_t newworkmode, char const *mtime)
+fixwork(mode_t newworkmode, time_t mtime)
/* The `#if has_prototypes' is needed because mode_t might promote to int. */
#else
fixwork(newworkmode, mtime)
mode_t newworkmode;
- char const *mtime;
+ time_t mtime;
#endif
{
- int r;
return
1 < workstat.st_nlink
- || newworkmode&S_IWUSR && !myself(workstat.st_uid)
+ || (newworkmode&S_IWUSR && !myself(workstat.st_uid))
+ || setmtime(workname, mtime) != 0
? -1
- :
- workstat.st_mode != newworkmode
- &&
- (r =
-# if has_fchmod
- fchmod(Ifileno(workptr), newworkmode)
-# else
- chmod(workfilename, newworkmode)
-# endif
- ) != 0
- ? r
- :
- setfiledate(workfilename, mtime);
+ : workstat.st_mode == newworkmode ? 0
+#if has_fchmod
+ : fchmod(Ifileno(workptr), newworkmode) == 0 ? 0
+#endif
+#if bad_chmod_close
+ : -1
+#else
+ : chmod(workname, newworkmode)
+#endif
+ ;
}
static int
-xpandfile(unexfile, dir, delta, exfilename)
+xpandfile(unexfile, delta, exname, dolog)
RILE *unexfile;
- char const *dir;
struct hshentry const *delta;
- char const **exfilename;
+ char const **exname;
+ int dolog;
/*
* Read unexfile and copy it to a
- * file in dir, performing keyword substitution with data from delta.
+ * file, performing keyword substitution with data from delta.
* Return -1 if unsuccessful, 1 if expansion occurred, 0 otherwise.
* If successful, stores the stream descriptor into *EXFILEP
- * and its name into *EXFILENAME.
+ * and its name into *EXNAME.
*/
{
- char const *targetfname;
+ char const *targetname;
int e, r;
- targetfname = makedirtemp(dir, 1);
- if (!(exfile = fopen(targetfname, FOPEN_W_WORK))) {
- eerror(targetfname);
- error("can't expand working file");
+ targetname = makedirtemp(1);
+ if (!(exfile = fopenSafer(targetname, FOPEN_W_WORK))) {
+ eerror(targetname);
+ workerror("can't build working file");
return -1;
}
r = 0;
- if (Expand == OLD_EXPAND)
+ if (MIN_UNEXPAND <= Expand)
fastcopy(unexfile,exfile);
else {
for (;;) {
- e = expandline(unexfile,exfile,delta,false,(FILE*)nil);
+ e = expandline(
+ unexfile, exfile, delta, false, (FILE*)0, dolog
+ );
if (e < 0)
break;
r |= e;
@@ -1074,8 +1235,7 @@ xpandfile(unexfile, dir, delta, exfilename)
break;
}
}
- *exfilename = targetfname;
- aflush(exfile);
+ *exname = targetname;
return r & 1;
}
@@ -1116,7 +1276,7 @@ getlogmsg()
/* generate std. log message */
caller = getcaller();
i = sizeof(ciklog)+strlen(caller)+3;
- bufalloc(&logbuf, i+datesize);
+ bufalloc(&logbuf, i + datesize + zonelenmax);
tp = logbuf.string;
VOID sprintf(tp, "%s%s at ", ciklog, caller);
VOID date2str(getcurdate(), tp+i);
@@ -1150,19 +1310,15 @@ getlogmsg()
static void
addassoclst(flag, sp)
-int flag;
-char * sp;
+ int flag;
+ char const *sp;
{
struct Symrev *pt;
pt = talloc(struct Symrev);
pt->ssymbol = sp;
pt->override = flag;
- pt->nextsym = nil;
- if (lastassoc)
- lastassoc->nextsym = pt;
- else
- assoclst = pt;
- lastassoc = pt;
- return;
+ pt->nextsym = 0;
+ *nextassoc = pt;
+ nextassoc = &pt->nextsym;
}
View
7 gnu/usr.bin/rcs/co/Makefile
@@ -1,8 +1,9 @@
+# $NetBSD: Makefile,v 1.1.1.2 1996/10/13 21:56:50 veego Exp $
+
PROG= co
-SRCS= co.c
CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
+LDADD= ${LIBRCS} -lgnumalloc
+DPADD= ${LIBRCS} /usr/lib/libgnumalloc.a
.include "../../Makefile.inc"
.include <bsd.prog.mk>
View
287 gnu/usr.bin/rcs/co/co.1
@@ -1,10 +1,13 @@
+.\" $NetBSD: co.1,v 1.1.1.2 1996/10/13 21:56:48 veego Exp $
+.\"
.de Id
.ds Rv \\$3
.ds Dt \\$4
..
-.Id co.1,v 1.1.1.1 1993/06/18 04:22:11 jkh Exp
-.ds g \&\s-1UTC\s0
+.\" Id: co.1,v 5.13 1995/06/01 16:23:43 eggert Exp
+.ds i \&\s-1ISO\s0
.ds r \&\s-1RCS\s0
+.ds u \&\s-1UTC\s0
.if n .ds - \%--
.if t .ds - \(em
.TH CO 1 \*(Dt GNU
@@ -23,12 +26,12 @@ all others denote working files.
Names are paired as explained in
.BR ci (1).
.PP
-Revisions of an \*r file may be checked out locked or unlocked. Locking a
+Revisions of an \*r file can be checked out locked or unlocked. Locking a
revision prevents overlapping updates. A revision checked out for reading or
processing (e.g., compiling) need not be locked. A revision checked out
for editing and later checkin must normally be locked. Checkout with locking
fails if the revision to be checked out is currently locked by another user.
-(A lock may be broken with
+(A lock can be broken with
.BR rcs "(1).)\ \&"
Checkout with locking also requires the caller to be on the access list of
the \*r file, unless he is the owner of the
@@ -51,7 +54,7 @@ on the default branch (normally the trunk, see the
.B \-b
option of
.BR rcs (1)).
-A revision or branch number may be attached
+A revision or branch number can be attached
to any of the options
.BR \-f ,
.BR \-I ,
@@ -73,7 +76,7 @@ retrieve from a single branch, the
.I selected
branch,
which is either specified by one of
-.BR \-f,
+.BR \-f ,
\&.\|.\|.,
.BR \-u ,
or the default branch.
@@ -88,7 +91,7 @@ always performs keyword substitution (see below).
.TP
.BR \-r [\f2rev\fP]
retrieves the latest revision whose number is less than or equal to
-.I rev.
+.IR rev .
If
.I rev
indicates a branch rather than a revision,
@@ -108,7 +111,16 @@ is
.B co
determines the revision number from keyword values in the working file.
Otherwise, a revision is composed of one or more numeric or symbolic fields
-separated by periods. The numeric equivalent of a symbolic field
+separated by periods.
+If
+.I rev
+begins with a period,
+then the default branch (normally the trunk) is prepended to it.
+If
+.I rev
+is a branch number followed by a period,
+then the latest revision on that branch is used.
+The numeric equivalent of a symbolic field
is specified with the
.B \-n
option of the commands
@@ -166,7 +178,7 @@ Like
except that a locker's name is always inserted
if the given revision is currently locked.
.TP
-.BR \-kk
+.B \-kk
Generate only keyword names in keyword strings; omit their values.
See
.SM "KEYWORD SUBSTITUTION"
@@ -176,11 +188,17 @@ For example, for the
keyword, generate the string
.B $\&Revision$
instead of
-.BR "$\&Revision: \*(Rv $".
+.BR "$\&Revision: \*(Rv $" .
This option is useful to ignore differences due to keyword substitution
when comparing different revisions of a file.
+Log messages are inserted after
+.B $\&Log$
+keywords even if
+.B \-kk
+is specified,
+since this tends to be more useful when merging changes.
.TP
-.BR \-ko
+.B \-ko
Generate the old keyword string,
present in the working file just before it was checked in.
For example, for the
@@ -190,18 +208,33 @@ keyword, generate the string
instead of
.B "$\&Revision: \*(Rv $"
if that is how the string appeared when the file was checked in.
-This can be useful for binary file formats
+This can be useful for file formats
that cannot tolerate any changes to substrings
that happen to take the form of keyword strings.
.TP
-.BR \-kv
+.B \-kb
+Generate a binary image of the old keyword string.
+This acts like
+.BR \-ko ,
+except it performs all working file input and output in binary mode.
+This makes little difference on Posix and Unix hosts,
+but on DOS-like hosts one should use
+.B "rcs\ \-i\ \-kb"
+to initialize an \*r file intended to be used for binary files.
+Also, on all hosts,
+.BR rcsmerge (1)
+normally refuses to merge files when
+.B \-kb
+is in effect.
+.TP
+.B \-kv
Generate only keyword values for keyword strings.
For example, for the
.B Revision
keyword, generate the string
.B \*(Rv
instead of
-.BR "$\&Revision: \*(Rv $".
+.BR "$\&Revision: \*(Rv $" .
This can help generate files in programming languages where it is hard to
strip keyword delimiters like
.B "$\&Revision:\ $"
@@ -233,8 +266,8 @@ even if the standard input is not a terminal.
.BI \-d date
retrieves the latest revision on the selected branch whose checkin date/time is
less than or equal to
-.I date.
-The date and time may be given in free format.
+.IR date .
+The date and time can be given in free format.
The time zone
.B LT
stands for local time;
@@ -243,38 +276,43 @@ For example, the following
.IR date s
are equivalent
if local time is January 11, 1990, 8pm Pacific Standard Time,
-eight hours west of Coordinated Universal Time (\*g):
+eight hours west of Coordinated Universal Time (\*u):
.RS
.LP
.RS
.nf
.ta \w'\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP 'u
-.ne 9
+.ne 10
\f38:00 pm lt\fP
-\f34:00 AM, Jan. 12, 1990\fP note: default is \*g
-\f31990/01/12 04:00:00\fP \*r date format
+\f34:00 AM, Jan. 12, 1990\fP default is \*u
+\f31990-01-12 04:00:00+00\fP \*i 8601 (\*u)
+\f31990-01-11 20:00:00\-08\fP \*i 8601 (local time)
+\f31990/01/12 04:00:00\fP traditional \*r format
\f3Thu Jan 11 20:00:00 1990 LT\fP output of \f3ctime\fP(3) + \f3LT\fP
\f3Thu Jan 11 20:00:00 PST 1990\fP output of \f3date\fP(1)
\f3Fri Jan 12 04:00:00 GMT 1990\fP
-\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP
-\f3Fri-JST, 1990, 1pm Jan 12\fP
-\f312-January-1990, 04:00-WET\fP
+\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP Internet RFC 822
+\f312-January-1990, 04:00 WET\fP
.ta 4n +4n +4n +4n
.fi
.RE
.LP
-Most fields in the date and time may be defaulted.
-The default time zone is \*g.
+Most fields in the date and time can be defaulted.
+The default time zone is normally \*u, but this can be overridden by the
+.B \-z
+option.
The other defaults are determined in the order year, month, day,
hour, minute, and second (most to least significant). At least one of these
fields must be provided. For omitted fields that are of higher significance
than the highest provided field, the time zone's current values are assumed.
For all other omitted fields,
the lowest possible values are assumed.
-For example, the date
+For example, without
+.BR \-z ,
+the date
.B "20, 10:30"
defaults to
-10:30:00 \*g of the 20th of the \*g time zone's current month and year.
+10:30:00 \*u of the 20th of the \*u time zone's current month and year.
The date/time must be quoted if it contains spaces.
.RE
.TP
@@ -286,12 +324,22 @@ Use this option with care; it can confuse
.TP
.BI \-s state
retrieves the latest revision on the selected branch whose state is set to
-.I state.
+.IR state .
+.TP
+.B \-T
+Preserve the modification time on the \*r file
+even if the \*r file changes because a lock is added or removed.
+This option can suppress extensive recompilation caused by a
+.BR make (1)
+dependency of some other copy of the working file on the \*r file.
+Use this option with care; it can suppress recompilation even when it is needed,
+i.e. when the change of lock
+would mean a change to keyword strings in the other working file.
.TP
.BR \-w [\f2login\fP]
retrieves the latest revision on the selected branch which was checked in
by the user with login name
-.I login.
+.IR login .
If the argument
.I login
is
@@ -299,7 +347,7 @@ omitted, the caller's login is assumed.
.TP
.BI \-j joinlist
generates a new revision which is the join of the revisions on
-.I joinlist.
+.IR joinlist .
This option is largely obsoleted by
.BR rcsmerge (1)
but is retained for backwards compatibility.
@@ -319,7 +367,7 @@ For the initial such pair,
.I rev1
denotes the revision selected
by the above options
-.BR \-f,
+.BR \-f ,
\&.\|.\|.,
.BR \-w .
For all other pairs,
@@ -335,13 +383,13 @@ joins revisions
and
.I rev3
with respect to
-.I rev2.
+.IR rev2 .
This means that all changes that transform
.I rev2
into
.I rev1
are applied to a copy of
-.I rev3.
+.IR rev3 .
This is particularly useful if
.I rev1
and
@@ -372,7 +420,7 @@ reports overlaps as described in
.PP
For the initial pair,
.I rev2
-may be omitted. The default is the common
+can be omitted. The default is the common
ancestor.
If any of the arguments indicate branches, the latest revisions
on those branches are assumed.
@@ -381,22 +429,28 @@ The options
and
.B \-u
lock or unlock
-.I rev1.
+.IR rev1 .
.RE
.TP
+.BI \-V
+Print \*r's version number.
+.TP
.BI \-V n
Emulate \*r version
.I n,
where
.I n
-may be
+can be
.BR 3 ,
.BR 4 ,
or
.BR 5 .
-This may be useful when interchanging \*r files with others who are
+This can be useful when interchanging \*r files with others who are
running older versions of \*r.
To see which version of \*r your correspondents are running, have them invoke
+.BR "rcs \-V" ;
+this works with newer versions of \*r.
+If it doesn't work, have them invoke
.B rlog
on an \*r file;
if none of the first few lines of output contain the string
@@ -404,15 +458,14 @@ if none of the first few lines of output contain the string
it is version 3;
if the dates' years have just two digits, it is version 4;
otherwise, it is version 5.
-An \*r file generated while emulating version 3 will lose its default branch.
-An \*r revision generated while emulating version 4 or earlier will have
-a timestamp that is off by up to 13 hours.
-A revision extracted while emulating version 4 or earlier will contain
-dates of the form
+An \*r file generated while emulating version 3 loses its default branch.
+An \*r revision generated while emulating version 4 or earlier has
+a time stamp that is off by up to 13 hours.
+A revision extracted while emulating version 4 or earlier contains
+abbreviated dates of the form
.IB yy / mm / dd
-instead of
-.IB yyyy / mm / dd
-and may also contain different white space in the substitution for
+and can also contain different white space and line prefixes
+in the substitution for
.BR $\&Log$ .
.TP
.BI \-x "suffixes"
@@ -422,6 +475,46 @@ to characterize \*r files.
See
.BR ci (1)
for details.
+.TP
+.BI \-z zone
+specifies the date output format in keyword substitution,
+and specifies the default time zone for
+.I date
+in the
+.BI \-d date
+option.
+The
+.I zone
+should be empty, a numeric \*u offset, or the special string
+.B LT
+for local time.
+The default is an empty
+.IR zone ,
+which uses the traditional \*r format of \*u without any time zone indication
+and with slashes separating the parts of the date;
+otherwise, times are output in \*i 8601 format with time zone indication.
+For example, if local time is January 11, 1990, 8pm Pacific Standard Time,
+eight hours west of \*u,
+then the time is output as follows:
+.RS
+.LP
+.RS
+.nf
+.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u
+.ne 4
+\f2option\fP \f2time output\fP
+\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP
+\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP
+\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP
+.ta 4n +4n +4n +4n
+.fi
+.RE
+.LP
+The
+.B \-z
+option does not affect dates stored in \*r files,
+which are always \*u.
+.RE
.SH "KEYWORD SUBSTITUTION"
Strings of the form
.BI $ keyword $
@@ -436,7 +529,7 @@ where
and
.I value
are pairs listed below.
-Keywords may be embedded in literal strings
+Keywords can be embedded in literal strings
or comments to identify a revision.
.PP
Initially, the user enters strings of the form
@@ -459,12 +552,18 @@ Keywords and their corresponding values:
The login name of the user who checked in the revision.
.TP
.B $\&Date$
-The date and time (\*g) the revision was checked in.
+The date and time the revision was checked in.
+With
+.BI \-z zone
+a numeric time zone offset is appended; otherwise, the date is \*u.
.TP
.B $\&Header$
A standard header containing the full pathname of the \*r file, the
-revision number, the date (\*g), the author, the state,
+revision number, the date and time, the author, the state,
and the locker (if locked).
+With
+.BI \-z zone
+a numeric time zone offset is appended to the date; otherwise, the date is \*u.
.TP
.B $\&Id$
Same as
@@ -477,7 +576,10 @@ The login name of the user who locked the revision (empty if not locked).
.B $\&Log$
The log message supplied during checkin, preceded by a header
containing the \*r filename, the revision number, the author, and the date
-(\*g).
+and time.
+With
+.BI \-z zone
+a numeric time zone offset is appended; otherwise, the date is \*u.
Existing log messages are
.I not
replaced.
@@ -485,6 +587,58 @@ Instead, the new log message is inserted after
.BR $\&Log: .\|.\|. $ .
This is useful for
accumulating a complete change log in a source file.
+.RS
+.LP
+Each inserted line is prefixed by the string that prefixes the
+.B $\&Log$
+line. For example, if the
+.B $\&Log$
+line is
+.RB \*(lq "//\ $\&Log: tan.cc\ $" \*(rq,
+\*r prefixes each line of the log with
+.RB \*(lq "//\ " \*(rq.
+This is useful for languages with comments that go to the end of the line.
+The convention for other languages is to use a
+.RB \*(lq " \(** " \(rq
+prefix inside a multiline comment.
+For example, the initial log comment of a C program
+conventionally is of the following form:
+.RS
+.LP
+.nf
+.ft 3
+.ne 3
+/\(**
+.in +\w'/'u
+\(** $\&Log$
+\(**/
+.in
+.ft
+.fi
+.RE
+.LP
+For backwards compatibility with older versions of \*r, if the log prefix is
+.B /\(**
+or
+.B (\(**
+surrounded by optional white space, inserted log lines contain a space
+instead of
+.B /
+or
+.BR ( ;
+however, this usage is obsolescent and should not be relied on.
+.RE
+.TP
+.B $\&Name$
+The symbolic name used to check out the revision, if any.
+For example,
+.B "co\ \-rJoe"
+generates
+.BR "$\&Name:\ Joe\ $" .
+Plain
+.B co
+generates just
+.BR "$\&Name:\ \ $" .
.TP
.B $\&RCSfile$
The name of the \*r file without a path.
@@ -502,6 +656,22 @@ option of
.BR rcs (1)
or
.BR ci (1).
+.PP
+The following characters in keyword values are represented by escape sequences
+to keep keyword strings well-formed.
+.LP
+.RS
+.nf
+.ne 6
+.ta \w'newline 'u
+\f2char escape sequence\fP
+tab \f3\et\fP
+newline \f3\en\fP
+space \f3\e040
+$ \e044
+\e \e\e\fP
+.fi
+.RE
.SH "FILE MODES"
The working file inherits the read and execute permissions from the \*r
file. In addition, the owner write permission is turned on, unless
@@ -523,7 +693,10 @@ is given, the working file is deleted without asking.
.B co
accesses files much as
.BR ci (1)
-does, except that it does not need to read the working file.
+does, except that it does not need to read the working file
+unless a revision number of
+.B $
+is specified.
.SH ENVIRONMENT
.TP
.B \s-1RCSINIT\s0
@@ -539,14 +712,14 @@ The exit status is zero if and only if all operations were successful.
.SH IDENTIFICATION
Author: Walter F. Tichy.
.br
-Revision Number: \*(Rv; Release Date: \*(Dt.
+Manual Page Revision: \*(Rv; Release Date: \*(Dt.
.br
-Copyright \(co 1982, 1988, 1989 by Walter F. Tichy.
+Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
.br
-Copyright \(co 1990, 1991 by Paul Eggert.
+Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
.SH "SEE ALSO"
-ci(1), ctime(3), date(1), ident(1), make(1),
-rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1),
+rcsintro(1), ci(1), ctime(3), date(1), ident(1), make(1),
+rcs(1), rcsclean(1), rcsdiff(1), rcsmerge(1), rlog(1),
rcsfile(5)
.br
Walter F. Tichy,
@@ -562,8 +735,4 @@ by writing them differently. In nroff and troff, this is done by embedding the
null-character
.B \e&
into the keyword.
-.SH BUGS
-The
-.B \-d
-option sometimes gets confused, and accepts no date before 1970.
.br
View
366 gnu/usr.bin/rcs/co/co.c
@@ -1,5 +1,9 @@
-/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991 by Paul Eggert
+/* $NetBSD: co.c,v 1.1.1.2 1996/10/13 21:56:49 veego Exp $ */
+
+/* Check out working files from revisions of RCS files. */
+
+/* Copyright 1982, 1988, 1989 Walter Tichy
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
Distributed under license by the Free Software Foundation, Inc.
This file is part of RCS.
@@ -15,8 +19,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
-along with RCS; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+along with RCS; see the file COPYING.
+If not, write to the Free Software Foundation,
+59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Report problems and direct all questions to:
@@ -25,20 +30,43 @@ Report problems and direct all questions to:
*/
/*
- * RCS checkout operation
- */
-/*****************************************************************************
- * check out revisions from RCS files
- *****************************************************************************
- */
-
-
-/* co.c,v
- * Revision 1.1.1.1 1993/06/18 04:22:11 jkh
- * Updated GNU utilities
+ * $Log: co.c,v $
+ * Revision 1.1.1.2 1996/10/13 21:56:49 veego
+ * Import GNU rcs 5.7
+ *
+ * Revision 5.18 1995/06/16 06:19:24 eggert
+ * Update FSF address.
+ *
+ * Revision 5.17 1995/06/01 16:23:43 eggert
+ * (main, preparejoin): Pass argument instead of using `join' static variable.
+ * (main): Add -kb.
+ *
+ * Revision 5.16 1994/03/17 14:05:48 eggert
+ * Move buffer-flushes out of critical sections, since they aren't critical.
+ * Use ORCSerror to clean up after a fatal error. Remove lint.
+ * Specify subprocess input via file descriptor, not file name.
+ *
+ * Revision 5.15 1993/11/09 17:40:15 eggert
+ * -V now prints version on stdout and exits. Don't print usage twice.
+ *
+ * Revision 5.14 1993/11/03 17:42:27 eggert
+ * Add -z. Generate a value for the Name keyword.
+ * Don't arbitrarily limit the number of joins.
+ * Improve quality of diagnostics.
+ *
+ * Revision 5.13 1992/07/28 16:12:44 eggert
+ * Add -V. Check that working and RCS files are distinct.
+ *
+ * Revision 5.12 1992/02/17 23:02:08 eggert
+ * Add -T.
+ *
+ * Revision 5.11 1992/01/24 18:44:19 eggert
+ * Add support for bad_creat0. lint -> RCS_lint
+ *
+ * Revision 5.10 1992/01/06 02:42:34 eggert
+ * Update usage string.
*
* Revision 5.9 1991/10/07 17:32:46 eggert
- * ci -u src/RCS/co.c,v src/co.c <<\.
* -k affects just working file, not RCS file.
*
* Revision 5.8 1991/08/19 03:13:55 eggert
@@ -146,17 +174,19 @@ Report problems and direct all questions to:
#include "rcsbase.h"
+static char *addjoin P((char*));
static char const *getancestor P((char const*,char const*));
static int buildjoin P((char const*));
-static int preparejoin P((void));
+static int preparejoin P((char*));
static int rmlock P((struct hshentry const*));
static int rmworkfile P((void));
static void cleanup P((void));
static char const quietarg[] = "-q";
-static char const *expandarg, *join, *suffixarg, *versionarg;
-static char const *joinlist[joinlength]; /* revisions to be joined */
+static char const *expandarg, *suffixarg, *versionarg, *zonearg;
+static char const **joinlist; /* revisions to be joined */
+static int joinlength;
static FILE *neworkptr;
static int exitstatus;
static int forceflag;
@@ -167,25 +197,31 @@ static struct hshentries *gendeltas; /* deltas to be generated */
static struct hshentry *targetdelta; /* final delta to be generated */
static struct stat workstat;
-mainProg(coId, "co", "co.c,v 1.1.1.1 1993/06/18 04:22:11 jkh Exp")
+mainProg(coId, "co", "Id: co.c,v 5.18 1995/06/16 06:19:24 eggert Exp")
{
static char const cmdusage[] =
- "\nco usage: co -{flpqru}[rev] -ddate -jjoinlist -sstate -w[login] -Vn file ...";
+ "\nco usage: co -{fIlMpqru}[rev] -ddate -jjoins -ksubst -sstate -T -w[who] -Vn -xsuff -zzone file ...";
- char *a, **newargv;
+ char *a, *joinflag, **newargv;
char const *author, *date, *rev, *state;
- char const *joinfilename, *newdate, *neworkfilename;
+ char const *joinname, *newdate, *neworkname;
int changelock; /* 1 if a lock has been changed, -1 if error */
int expmode, r, tostdout, workstatstat;
+ int Ttimeflag;
struct buf numericrev; /* expanded revision number */
char finaldate[datesize];
+# if OPEN_O_BINARY
+ int stdout_mode = 0;
+# endif
setrid();
- author = date = rev = state = nil;
+ author = date = rev = state = 0;
+ joinflag = 0;
bufautobegin(&numericrev);
expmode = -1;
suffixes = X_DEFAULT;
tostdout = false;
+ Ttimeflag = false;
argc = getRCSINIT(argc, argv, &newargv);
argv = newargv;
@@ -206,14 +242,14 @@ mainProg(coId, "co", "co.c,v 1.1.1.1 1993/06/18 04:22:11 jkh Exp")
case 'l':
if (lockflag < 0) {
- warn("-l overrides -u.");
+ warn("-u overridden by -l.");
}
lockflag = 1;
goto revno;
case 'u':
if (0 < lockflag) {
- warn("-l overrides -u.");
+ warn("-l overridden by -u.");
}
lockflag = -1;
goto revno;
@@ -239,8 +275,8 @@ mainProg(coId, "co", "co.c,v 1.1.1.1 1993/06/18 04:22:11 jkh Exp")
case 'j':
if (*a) {
- if (join) redefined('j');
- join = a;
+ if (joinflag) redefined('j');
+ joinflag = a;
}
break;
@@ -255,6 +291,12 @@ mainProg(coId, "co", "co.c,v 1.1.1.1 1993/06/18 04:22:11 jkh Exp")
}
break;
+ case 'T':
+ if (*a)
+ goto unknown;
+ Ttimeflag = true;
+ break;
+
case 'w':
if (author) redefined('w');
if (*a)
@@ -273,6 +315,11 @@ mainProg(coId, "co", "co.c,v 1.1.1.1 1993/06/18 04:22:11 jkh Exp")
setRCSversion(versionarg);
break;
+ case 'z':
+ zonearg = *argv;
+ zone_set(a);
+ break;
+
case 'k': /* set keyword expand mode */
expandarg = *argv;
if (0 <= expmode) redefined('k');
@@ -280,69 +327,81 @@ mainProg(coId, "co", "co.c,v 1.1.1.1 1993/06/18 04:22:11 jkh Exp")
break;
/* fall into */
default:
- faterror("unknown option: %s%s", *argv, cmdusage);
+ unknown:
+ error("unknown option: %s%s", *argv, cmdusage);