home *** CD-ROM | disk | FTP | other *** search
Text File | 1991-12-19 | 88.1 KB | 3,203 lines |
- Newsgroups: comp.sources.unix
- From: hammer@cs.purdue.edu (Adam Hammer)
- Subject: v25i078: rcs-5.6 - Revision Control System, V5.6, Part02/11
- Sender: sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: hammer@cs.purdue.edu (Adam Hammer)
- Posting-Number: Volume 25, Issue 78
- Archive-Name: rcs-5.6/part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 2 (of 11)."
- # Contents: man/rcs.1 man/rcsintro.1 src/README src/maketime.c
- # src/rcsdiff.c src/rcsfcmp.c src/rcskeep.c src/rcsmerge.c
- # src/rcstest
- # Wrapped by vixie@cognition.pa.dec.com on Fri Dec 20 16:23:39 1991
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'man/rcs.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'man/rcs.1'\"
- else
- echo shar: Extracting \"'man/rcs.1'\" \(8642 characters\)
- sed "s/^X//" >'man/rcs.1' <<'END_OF_FILE'
- X.de Id
- X.ds Rv \\$3
- X.ds Dt \\$4
- X..
- X.Id $Id: rcs.1,v 5.6 1991/09/26 23:16:17 eggert Exp $
- X.ds r \&\s-1RCS\s0
- X.if n .ds - \%--
- X.if t .ds - \(em
- X.TH RCS 1 \*(Dt GNU
- X.SH NAME
- rcs \- change RCS file attributes
- X.SH SYNOPSIS
- X.B rcs
- X.RI [ " options " ] " file " .\|.\|.
- X.SH DESCRIPTION
- X.B rcs
- creates new \*r files or changes attributes of existing ones.
- An \*r file contains multiple revisions of text,
- an access list, a change log,
- descriptive text,
- and some control attributes.
- XFor
- X.B rcs
- to work, the caller's login name must be on the access list,
- except if the access list is empty, the caller is the owner of the file
- or the superuser, or
- the
- X.B \-i
- option is present.
- X.PP
- Pathnames matching an \*r suffix denote \*r files;
- all others denote working files.
- Names are paired as explained in
- X.BR ci (1).
- Revision numbers use the syntax described in
- X.BR ci (1).
- X.SH OPTIONS
- X.TP
- X.B \-i
- Create and initialize a new \*r file, but do not deposit any revision.
- If the \*r file has no path prefix, try to place it
- first into the subdirectory
- X.BR ./RCS ,
- and then into the current directory.
- If the \*r file
- already exists, print an error message.
- X.TP
- X.BI \-a "logins"
- Append the login names appearing in the comma-separated list
- X.I logins
- to the access list of the \*r file.
- X.TP
- X.BI \-A "oldfile"
- Append the access list of
- X.I oldfile
- to the access list of the \*r file.
- X.TP
- X.BR \-e [\f2logins\fP]
- XErase the login names appearing in the comma-separated list
- X.I logins
- from the access list of the \*r file.
- If
- X.I logins
- is omitted, erase the entire access list.
- X.TP
- X.BR \-b [\f2rev\fP]
- Set the default branch to
- X.IR rev .
- If
- X.I rev
- is omitted, the default
- branch is reset to the (dynamically) highest branch on the trunk.
- X.TP
- X.BI \-c string
- sets the comment leader to
- X.IR string .
- The comment leader
- is printed before every log message line generated by the keyword
- X.B $\&Log$
- during checkout (see
- X.BR co (1)).
- This is useful for programming
- languages without multi-line comments.
- An initial
- X.B ci ,
- or an
- X.B "rcs\ \-i"
- without
- X.BR \-c ,
- guesses the comment leader from the suffix of the working file.
- X.TP
- X.BI \-k subst
- Set the default keyword substitution to
- X.IR subst .
- The effect of keyword substitution is described in
- X.BR co (1).
- Giving an explicit
- X.B \-k
- option to
- X.BR co ,
- X.BR rcsdiff ,
- and
- X.B rcsmerge
- overrides this default.
- Beware
- X.BR "rcs\ \-kv",
- because
- X.B \-kv
- is incompatible with
- X.BR "co\ \-l".
- Use
- X.B "rcs\ \-kkv"
- to restore the normal default keyword substitution.
- X.TP
- X.BR \-l [\f2rev\fP]
- Lock the revision with number
- X.IR rev .
- If a branch is given, lock the latest revision on that branch.
- If
- X.I rev
- is omitted, lock the latest revision on the default branch.
- Locking prevents overlapping changes.
- A lock is removed with
- X.B ci
- or
- X.B "rcs\ \-u"
- X(see below).
- X.TP
- X.BR \-u [\f2rev\fP]
- Unlock the revision with number
- X.IR rev .
- If a branch is given, unlock the latest revision on that branch.
- If
- X.I rev
- is omitted, remove the latest lock held by the caller.
- Normally, only the locker of a revision may unlock it.
- Somebody else unlocking a revision breaks the lock.
- This causes a mail message to be sent to the original locker.
- The message contains a commentary solicited from the breaker.
- The commentary is terminated by end-of-file or by a line containing
- X.BR \&. "\ by"
- itself.
- X.TP
- X.B \-L
- Set locking to
- X.IR strict .
- Strict locking means that the owner
- of an \*r file is not exempt from locking for checkin.
- This option should be used for files that are shared.
- X.TP
- X.B \-U
- Set locking to non-strict. Non-strict locking means that the owner of
- a file need not lock a revision for checkin.
- This option should
- X.I not
- be used for files that are shared.
- Whether default locking is strict is determined by your system administrator,
- but it is normally strict.
- X.TP
- X\f3\-m\fP\f2rev\fP\f3:\fP\f2msg\fP
- Replace revision
- X.IR rev 's
- log message with
- X.IR msg .
- X.TP
- X\f3\-n\fP\f2name\fP[\f3:\fP[\f2rev\fP]]
- Associate the symbolic name
- X.I name
- with the branch or
- revision
- X.IR rev .
- Delete the symbolic name if both
- X.B :
- and
- X.I rev
- are omitted; otherwise, print an error message if
- X.I name
- is already associated with
- another number.
- If
- X.I rev
- is symbolic, it is expanded before association.
- A
- X.I rev
- consisting of a branch number followed by a
- X.B .\&
- stands for the current latest revision in the branch.
- A
- X.B :
- with an empty
- X.I rev
- stands for the current latest revision on the default branch,
- normally the trunk.
- XFor example,
- X.BI "rcs\ \-n" name ":\ RCS/*"
- associates
- X.I name
- with the current latest revision of all the named \*r files;
- this contrasts with
- X.BI "rcs\ \-n" name ":$\ RCS/*"
- which associates
- X.I name
- with the revision numbers extracted from keyword strings
- in the corresponding working files.
- X.TP
- X\f3\-N\fP\f2name\fP[\f3:\fP[\f2rev\fP]]
- Act like
- X.BR \-n ,
- except override any previous assignment of
- X.IR name .
- X.TP
- X.BI \-o range
- deletes (\*(lqoutdates\*(rq) the revisions given by
- X.IR range .
- A range consisting of a single revision number means that revision.
- A range consisting of a branch number means the latest revision on that
- branch.
- A range of the form
- X.IB rev1 : rev2
- means
- revisions
- X.I rev1
- to
- X.I rev2
- on the same branch,
- X.BI : rev
- means from the beginning of the branch containing
- X.I rev
- up to and including
- X.IR rev ,
- and
- X.IB rev :
- means
- from revision
- X.I rev
- to the end of the branch containing
- X.IR rev .
- None of the outdated revisions may have branches or locks.
- X.TP
- X.B \-q
- Run quietly; do not print diagnostics.
- X.TP
- X.B \-I
- Run interactively, even if the standard input is not a terminal.
- X.TP
- X.B \-s\f2state\fP\f1[\fP:\f2rev\fP\f1]\fP
- Set the state attribute of the revision
- X.I rev
- to
- X.I state .
- If
- X.I rev
- is a branch number, assume the latest revision on that branch.
- If
- X.I rev
- is omitted, assume the latest revision on the default branch.
- Any identifier is acceptable for
- X.IR state .
- A useful set of states
- is
- X.B Exp
- X(for experimental),
- X.B Stab
- X(for stable), and
- X.B Rel
- X(for
- released).
- By default,
- X.BR ci (1)
- sets the state of a revision to
- X.BR Exp .
- X.TP
- X.BR \-t [\f2file\fP]
- Write descriptive text from the contents of the named
- X.I file
- into the \*r file, deleting the existing text.
- The
- X.IR file
- pathname may not begin with
- X.BR \- .
- If
- X.I file
- is omitted, obtain the text from standard input,
- terminated by end-of-file or by a line containing
- X.BR \&. "\ by"
- itself.
- Prompt for the text if interaction is possible; see
- X.BR \-I .
- With
- X.BR \-i ,
- descriptive text is obtained
- even if
- X.B \-t
- is not given.
- X.TP
- X.BI \-t\- string
- Write descriptive text from the
- X.I string
- into the \*r file, deleting the existing text.
- X.TP
- X.BI \-V n
- XEmulate \*r version
- X.IR n .
- See
- X.BR co (1)
- for details.
- X.TP
- X.BI \-x "suffixes"
- Use
- X.I suffixes
- to characterize \*r files.
- See
- X.BR ci (1)
- for details.
- X.SH COMPATIBILITY
- The
- X.BI \-b rev
- option generates an \*r file that cannot be parsed by \*r version 3 or earlier.
- X.PP
- The
- X.BI \-k subst
- options (except
- X.BR \-kkv )
- generate an \*r file that cannot be parsed by \*r version 4 or earlier.
- X.PP
- Use
- X.BI "rcs \-V" n
- to make an \*r file acceptable to \*r version
- X.I n
- by discarding information that would confuse version
- X.IR n .
- X.PP
- X\*r version 5.5 and earlier does not support the
- X.B \-x
- option, and requires a
- X.B ,v
- suffix on an \*r pathname.
- X.SH FILES
- X.B rcs
- accesses files much as
- X.BR ci (1)
- does,
- except that it uses the effective user for all accesses,
- it does not write the working file or its directory,
- and it does not even read the working file unless a revision number of
- X.B $
- is specified.
- X.SH ENVIRONMENT
- X.TP
- X.B \s-1RCSINIT\s0
- options prepended to the argument list, separated by spaces.
- See
- X.BR ci (1)
- for details.
- X.SH DIAGNOSTICS
- The \*r pathname and the revisions outdated are written to
- the diagnostic output.
- The exit status is zero if and only if all operations were successful.
- X.SH IDENTIFICATION
- Author: Walter F. Tichy.
- X.br
- Revision Number: \*(Rv; Release Date: \*(Dt.
- X.br
- Copyright \(co 1982, 1988, 1989 by Walter F. Tichy.
- X.br
- Copyright \(co 1990, 1991 by Paul Eggert.
- X.SH "SEE ALSO"
- co(1), ci(1), ident(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1),
- rcsfile(5)
- X.br
- Walter F. Tichy,
- X\*r\*-A System for Version Control,
- X.I "Software\*-Practice & Experience"
- X.BR 15 ,
- X7 (July 1985), 637-654.
- X.SH BUGS
- The separator for revision ranges in the
- X.B \-o
- option used to be
- X.B \-
- instead of
- X.BR : ,
- but this leads to confusion when symbolic names contain
- X.BR \- .
- XFor backwards compatibility
- X.B "rcs \-o"
- still supports the old
- X.B \-
- separator, but it warns about this obsolete use.
- X.PP
- Symbolic names need not refer to existing revisions or branches.
- XFor example, the
- X.B \-o
- option does not remove symbolic names for the outdated revisions; you must use
- X.B \-n
- to remove the names.
- X.br
- END_OF_FILE
- if test 8642 -ne `wc -c <'man/rcs.1'`; then
- echo shar: \"'man/rcs.1'\" unpacked with wrong size!
- fi
- # end of 'man/rcs.1'
- fi
- if test -f 'man/rcsintro.1' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'man/rcsintro.1'\"
- else
- echo shar: Extracting \"'man/rcsintro.1'\" \(9299 characters\)
- sed "s/^X//" >'man/rcsintro.1' <<'END_OF_FILE'
- X.de Id
- X.ds Rv \\$3
- X.ds Dt \\$4
- X..
- X.Id $Id: rcsintro.1,v 5.1 1991/04/21 12:00:46 eggert Exp $
- X.ds r \&\s-1RCS\s0
- X.if n .ds - \%--
- X.if t .ds - \(em
- X.am SS
- X.LP
- X..
- X.TH RCSINTRO 1 \*(Dt GNU
- X.SH NAME
- rcsintro \- introduction to RCS commands
- X.SH DESCRIPTION
- The Revision Control System (\*r) manages multiple revisions of files.
- X\*r automates the storing, retrieval, logging, identification, and merging
- of revisions. \*r is useful for text that is revised frequently, for example
- programs, documentation, graphics, papers, and form letters.
- X.PP
- The basic user interface is extremely simple. The novice only needs
- to learn two commands:
- X.BR ci (1)
- and
- X.BR co (1).
- X.BR ci ,
- short for \*(lqcheck in\*(rq, deposits the contents of a
- file into an archival file called an \*r file. An \*r file
- contains all revisions of a particular file.
- X.BR co ,
- short for \*(lqcheck out\*(rq, retrieves revisions from an \*r file.
- X.SS "Functions of \*r"
- X.IP \(bu
- Store and retrieve multiple revisions of text. \*r saves all old
- revisions in a space efficient way.
- Changes no longer destroy the original, because the
- previous revisions remain accessible. Revisions can be retrieved according to
- ranges of revision numbers, symbolic names, dates, authors, and
- states.
- X.IP \(bu
- Maintain a complete history of changes.
- X\*r logs all changes automatically.
- Besides the text of each revision, \*r stores the author, the date and time of
- check-in, and a log message summarizing the change.
- The logging makes it easy to find out
- what happened to a module, without having to compare
- source listings or having to track down colleagues.
- X.IP \(bu
- Resolve access conflicts. When two or more programmers wish to
- modify the same revision, \*r alerts the programmers and prevents one
- modification from corrupting the other.
- X.IP \(bu
- Maintain a tree of revisions. \*r can maintain separate lines of development
- for each module. It stores a tree structure that represents the
- ancestral relationships among revisions.
- X.IP \(bu
- Merge revisions and resolve conflicts.
- Two separate lines of development of a module can be coalesced by merging.
- If the revisions to be merged affect the same sections of code, \*r alerts the
- user about the overlapping changes.
- X.IP \(bu
- Control releases and configurations.
- Revisions can be assigned symbolic names
- and marked as released, stable, experimental, etc.
- With these facilities, configurations of modules can be
- described simply and directly.
- X.IP \(bu
- Automatically identify each revision with name, revision number,
- creation time, author, etc.
- The identification is like a stamp that can be embedded at an appropriate place
- in the text of a revision.
- The identification makes it simple to determine which
- revisions of which modules make up a given configuration.
- X.IP \(bu
- Minimize secondary storage. \*r needs little extra space for
- the revisions (only the differences). If intermediate revisions are
- deleted, the corresponding deltas are compressed accordingly.
- X.SS "Getting Started with \*r"
- Suppose you have a file
- X.B f.c
- that you wish to put under control of \*r.
- If you have not already done so, make an \*r directory with the command
- X.IP
- X.B "mkdir RCS"
- X.LP
- Then invoke the check-in command
- X.IP
- X.B "ci f.c"
- X.LP
- This command creates an \*r file in the
- X.B RCS
- directory,
- stores
- X.B f.c
- into it as revision 1.1, and
- deletes
- X.BR f.c .
- It also asks you for a description. The description
- should be a synopsis of the contents of the file. All later check-in
- commands will ask you for a log entry, which should summarize the
- changes that you made.
- X.PP
- XFiles in the \*r directory are called \*r files;
- the others are called working files.
- To get back the working file
- X.B f.c
- in the previous example, use the check-out
- command
- X.IP
- X.B "co f.c"
- X.LP
- This command extracts the latest revision from the \*r file
- and writes
- it into
- X.BR f.c .
- If you want to edit
- X.BR f.c ,
- you must lock it as you check it out with the command
- X.IP
- X.B "co \-l f.c"
- X.LP
- You can now edit
- X.BR f.c .
- X.PP
- Suppose after some editing you want to know what changes that you have made.
- The command
- X.IP
- X.B "rcsdiff f.c"
- X.LP
- tells you the difference between the most recently checked-in version
- and the working file.
- You can check the file back in by invoking
- X.IP
- X.B "ci f.c"
- X.LP
- This increments the revision number properly.
- X.PP
- If
- X.B ci
- complains with the message
- X.IP
- X.BI "ci error: no lock set by " "your name"
- X.LP
- then you have tried to check in a file even though you did not
- lock it when you checked it out.
- Of course, it is too late now to do the check-out with locking, because
- another check-out would
- overwrite your modifications. Instead, invoke
- X.IP
- X.B "rcs \-l f.c"
- X.LP
- This command will lock the latest revision for you, unless somebody
- else got ahead of you already. In this case, you'll have to negotiate with
- that person.
- X.PP
- Locking assures that you, and only you, can check in the next update, and
- avoids nasty problems if several people work on the same file.
- XEven if a revision is locked, it can still be checked out for
- reading, compiling, etc. All that locking
- prevents is a
- X.I "check-in"
- by anybody but the locker.
- X.PP
- If your \*r file is private, i.e., if you are the only person who is going
- to deposit revisions into it, strict locking is not needed and you
- can turn it off.
- If strict locking is turned off,
- the owner of the \*r file need not have a lock for check-in; all others
- still do. Turning strict locking off and on is done with the commands
- X.IP
- X.BR "rcs \-U f.c" " and " "rcs \-L f.c"
- X.LP
- If you don't want to clutter your working directory with \*r files, create
- a subdirectory called
- X.B RCS
- in your working directory, and move all your \*r
- files there. \*r commands will look first into that directory to find
- needed files. All the commands discussed above will still work, without any
- modification.
- X(Actually, pairs of \*r and working files can be specified in three ways:
- X(a) both are given, (b) only the working file is given, (c) only the
- X\*r file is given. Both \*r and working files may have arbitrary path prefixes;
- X\*r commands pair them up intelligently.)
- X.PP
- To avoid the deletion of the working file during check-in (in case you want to
- continue editing or compiling), invoke
- X.IP
- X.BR "ci \-l f.c" " or " "ci \-u f.c"
- X.LP
- These commands check in
- X.B f.c
- as usual, but perform an implicit
- check-out. The first form also locks the checked in revision, the second one
- doesn't. Thus, these options save you one check-out operation.
- The first form is useful if you want to continue editing,
- the second one if you just want to read the file.
- Both update the identification markers in your working file (see below).
- X.PP
- You can give
- X.B ci
- the number you want assigned to a checked in
- revision. Assume all your revisions were numbered 1.1, 1.2, 1.3, etc.,
- and you would like to start release 2.
- The command
- X.IP
- X.BR "ci \-r2 f.c" " or " "ci \-r2.1 f.c"
- X.LP
- assigns the number 2.1 to the new revision.
- XFrom then on,
- X.B ci
- will number the subsequent revisions
- with 2.2, 2.3, etc. The corresponding
- X.B co
- commands
- X.IP
- X.BR "co \-r2 f.c" " and " "co \-r2.1 f.c"
- X.PP
- retrieve the latest revision numbered
- X.RI 2. x
- and the revision 2.1,
- respectively.
- X.B co
- without a revision number selects
- the latest revision on the
- X.IR trunk ,
- i.e. the highest
- revision with a number consisting of two fields. Numbers with more than two
- fields are needed for branches.
- XFor example, to start a branch at revision 1.3, invoke
- X.IP
- X.B "ci \-r1.3.1 f.c"
- X.LP
- This command starts a branch numbered 1 at revision 1.3, and assigns
- the number 1.3.1.1 to the new revision. For more information about
- branches, see
- X.BR rcsfile (5).
- X.SS "Automatic Identification"
- X\*r can put special strings for identification into your source and object
- code. To obtain such identification, place the marker
- X.IP
- X.B "$\&Id$"
- X.LP
- into your text, for instance inside a comment.
- X\*r will replace this marker with a string of the form
- X.IP
- X.BI $\&Id: " filename revision date time author state " $
- X.LP
- With such a marker on the first page of each module, you can
- always see with which revision you are working.
- X\*r keeps the markers up to date automatically.
- To propagate the markers into your object code, simply put
- them into literal character strings. In C, this is done as follows:
- X.IP
- X.ft 3
- static char rcsid[] = \&"$\&Id$\&";
- X.ft
- X.LP
- The command
- X.B ident
- extracts such markers from any file, even object code
- and dumps.
- Thus,
- X.B ident
- lets you find out
- which revisions of which modules were used in a given program.
- X.PP
- You may also find it useful to put the marker
- X.B $\&Log$
- into your text, inside a comment. This marker accumulates
- the log messages that are requested during check-in.
- Thus, you can maintain the complete history of your file directly inside it.
- There are several additional identification markers; see
- X.BR co (1)
- for
- details.
- X.SH IDENTIFICATION
- Author: Walter F. Tichy.
- X.br
- Revision Number: \*(Rv; Release Date: \*(Dt.
- X.br
- Copyright \(co 1982, 1988, 1989 by Walter F. Tichy.
- X.br
- Copyright \(co 1990, 1991 by Paul Eggert.
- X.SH "SEE ALSO"
- ci(1), co(1), ident(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1)
- X.br
- Walter F. Tichy,
- X\*r\*-A System for Version Control,
- X.I "Software\*-Practice & Experience"
- X.BR 15 ,
- X7 (July 1985), 637-654.
- X.br
- END_OF_FILE
- if test 9299 -ne `wc -c <'man/rcsintro.1'`; then
- echo shar: \"'man/rcsintro.1'\" unpacked with wrong size!
- fi
- # end of 'man/rcsintro.1'
- fi
- if test -f 'src/README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/README'\"
- else
- echo shar: Extracting \"'src/README'\" \(9190 characters\)
- sed "s/^X//" >'src/README' <<'END_OF_FILE'
- RCS configuration instructions
- X
- X $Id: README,v 1.5 1991/10/07 17:32:46 eggert Exp $
- X
- X Copyright 1991 by Paul Eggert
- X Distributed under license by the Free Software Foundation, Inc.
- X
- X This file is part of RCS.
- X
- X RCS is free software; you can redistribute it and/or modify it
- X under the terms of the GNU General Public License as published
- X by the Free Software Foundation; either version 2, or (at your
- X option) any later version.
- X
- X RCS is distributed in the hope that it will be useful, but
- X WITHOUT ANY WARRANTY; without even the implied warranty of
- X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X GNU General Public License for more details.
- X
- X You should have received a copy of the GNU General Public
- X License along with RCS; see the file COPYING. If not, write to
- X the Free Software Foundation, 675 Mass Ave, Cambridge, MA
- X 02139, USA.
- X
- X Report problems and direct all questions to:
- X
- X rcs-bugs@cs.purdue.edu
- X
- X
- XFor Posix and near-Posix hosts, configure by editing Makefile,
- commenting out wrong lines and uncommenting right ones.
- See ``Makefile notes'' below for advice.
- X
- After configuring, make conf.h; if this fails,
- look in src/conf.error to see what went wrong in the conf.sh shell file.
- Check the resulting conf.h for plausibility; see ``conf.h notes'' below.
- If conf.h is wrong, and the mistake isn't listed in ``conf.h notes'',
- there is a bug in conf.sh; please report it.
- You can patch conf.h if you're in a hurry, but it's better to fix it;
- look at a.h and conf.error for ideas.
- If all else fails, copy conf.heg to conf.h and edit it by hand.
- After configuring, make `all'.
- X
- If all went well, make `install'.
- If installation succeeds, make `installtest';
- if this fails, make `installdebug' for detailed info.
- X
- If you want to test RCS before installing it,
- you must set RCSPREFIX to be empty, make RCS from scratch,
- prefix the src directory to your PATH, and run `sh src/rcstest'.
- Be sure to restore RCSPREFIX and rebuild RCS before installing it.
- X
- If you want to maintain RCS with itself,
- preserve the original revision numbers, dates, etc.
- by checking the files in with the -k option.
- X
- X
- X__________
- X
- Makefile notes
- X
- CC is the name of your C compiler.
- X
- CC_D is a list of extra options for the C preprocessor.
- It should include any extra -D and -I options needed on your system.
- X
- CC_O is the C compiler options that affect just compilation and assembly;
- not preprocessing, linking or linting.
- If your compiler has the BSD -R option, -R can improve performance by
- making all initialized data read-only (not just string literals);
- this is not worth worrying about if your compiler also supports `const'.
- X
- CC_W is the list of C compiler options to enable
- warnings about questionable constructs in the RCS source code.
- X
- COMPAT2 is 1 if you still have version 2 RCS files around.
- X(Version 2 became obsolete in 1982, so this isn't likely.)
- COMPAT2 assures that version 2 RCS files can still be read.
- When you have the new RCS installed, rename old version 2 RCS files as follows.
- Suppose the working file was `f.c';
- rename the RCS file `f.c.v' to `f.c,v', and the RCS file `f.v' to `f.c,v'.
- Thus suffixes are no longer dropped and RCS files end in `,v' rather than `.v'.
- After all version 2 RCS files have been updated with new versions of ci or rcs,
- you can remake RCS with COMPAT2 set to 0.
- X
- DIFF is the name of your diff program.
- If you override DIFF, make sure you rebuild conf.h afterwards;
- otherwise you may introduce a security hole.
- On some versions of Unix, the standard diff does not support RCS
- and you must use something like /usr/lib/rdiff instead;
- perhaps you should try GNU diff instead.
- X
- DIFFPREFIX act likes RCSPREFIX, except it applies to subsidiary diffs,
- not to subsidiary RCS commands. It must be nonempty if setuid is to be used.
- X
- DIFF_FLAGS are diff's options for RCS format output, probably -n.
- If available, also include the -a option for comparing arbitrary files.
- X
- DIFF_L is 1 if diff understands the -L option for labeling context diff output.
- X
- DIFF_SUCCESS, DIFF_FAILURE, DIFF_TROUBLE are integer constants
- representing diff's exit status when it finds
- no differences, some differences, or trouble respectively.
- The first two should be EXIT_SUCCESS and EXIT_FAILURE,
- but on some hosts they are broken.
- X
- DIFF3 is the name of the diff3 program.
- With GNU diff, this is simply its user-visible diff3 program.
- With traditional diff3, this is not the user-visible diff3 program;
- instead, it this is the name of the undocumented diff3 auxiliary program,
- whose name is /usr/lib/diff3 or /usr/5lib/rdiff3prog or something similar.
- X
- DIFF3_BIN is 1 if DIFF3 is the user-visible GNU diff3 program (see DIFF3).
- Before setting this to 1, make sure your diff3 understands -a, -L, and and -m;
- e.g. the command `echo x | diff3 -m /dev/null /dev/null -' should output `x'.
- X
- XED is the name of the standard Unix line editor.
- It is needed only if DIFF3_BIN is 0.
- X
- XEXECUTABLE_PERMISSIONS are the options given to INSTALL for executable files
- on BSD Unix sites. Watch out for `-g staff' if you don't have a staff group,
- or if your installation program doesn't have a -g option.
- X
- INSTALL is the command that installs commands.
- X
- LDFLAGS are the loader flags you need, e.g. -i, -n, -s, -x.
- X
- LDLIBS are the loader libraries you need, e.g. -lbsd, -lBSD, -ljobs, -lPW, -lx.
- X
- LINK is the command used to link together an executable.
- X
- LINT is the name and usual arguments of your lint program.
- X
- OTHER_OBJECT are any other object files you need to link.
- X
- RCSCOMMANDS is the list of commands to be installed by default.
- It doesn't include rcsclean$x, which is still a little experimental.
- X
- RCSDIR is where the RCS commands will be installed.
- X
- RCSPREFIX is the prefix for subsidiary RCS commands like ci.
- If empty, RCS will search the PATH for these commands;
- this lets you move RCS commands after building them, and permits
- multiple instances of setuid RCS commands on the same host for different users.
- If nonempty, it should be a path followed by /;
- this makes RCS look in just one place, and makes execution faster.
- X
- REMOVE is how to remove a file.
- X
- SENDMAIL is a comma-separated list of strings that are a command to send mail.
- The name of the addressee will be appended as a separate argument,
- and the standard input will be the message
- X(first line `Subject: xxxx', second line empty).
- If your host cannot send mail, leave SENDMAIL empty.
- X
- TESTPREFIX is the prefix for test commands.
- X
- o is the file name extension your host uses for object files.
- It includes the `.'. It is typically `.o' on Unix hosts.
- X
- x is the file name extension your host uses for executables.
- It includes the `.'. It is empty on Unix hosts,
- which traditionally lack extensions on executables.
- X
- X
- X__________
- X
- conf.h notes
- X
- See conf.sh for details about the definitions in conf.h.
- Comments below cover unusual situations that can require hand patches to conf.h.
- X
- has_NFS - Set this if the target host might use NFS.
- NFS's stateless server model has well-known problems with
- the non-idempotent operations link(), rename(), and unlink().
- XFor example, unlink() can run twice on the file server,
- causing the client to think that the unlink failed with errno==ENOENT.
- has_NFS enables code that works around these problems.
- X
- const - Some hosts support `const' but complain about it, perhaps because
- system headers are wrong. `#define const /*empty*/' pacifies them.
- X
- has_rename - This should be 0 in SCO Unix V.3.2. Its NFS rename() is broken,
- but if you run conf.sh in a non-NFS filesystem, conf.sh thinks rename() works.
- X
- has_seteuid - This should be 1 only if your seteuid lets you switch back and
- forth between any pair of users as specified in Posix 1003.1a Draft 5.
- One must be root to test this reliably, so conf.sh just guesses.
- X
- large_memory - This should be 1 if main memory is large enough to hold entire
- copies of RCS files, perhaps because virtual memory is available.
- X
- NAME_MAX - this should be #undef'ed in AT&T SVR4.0 V2.0, which defines NAME_MAX
- to be 14 even though longer names are permitted on some filesystems.
- If you run conf.sh in a short-name filesystem, conf.sh won't detect this bug.
- X
- X_POSIX_SOURCE must be #defined in a strict Standard C environment,
- because otherwise stdio.h cannot define useful names like fileno.
- Avoid defining _POSIX_SOURCE if possible,
- because it can disable useful non-Posix features in your host.
- Perhaps you can remove the need for _POSIX_SOURCE
- by supplying an option to your compiler to makes it less strict.
- X
- text_work_stdio - This option makes sense only on non-Posix hosts that
- distinguish between text and binary I/O, e.g. DOS. Set this option if
- you want to use text I/O for working files, but binary I/O for RCS
- files. If set, RCS does not support non-text working files, but RCS
- files are portable to other hosts across binary network file systems
- like NFS. If not set, RCS supports non-text working files, but RCS
- files are not portable to Posix hosts.
- X
- TZ_must_be_set - set this to 1 on hosts where gmtime() yields bogus
- values unless the TZ environment variable is set.
- X
- volatile - See `const'. E.g. `volatile sig_atomic_t' is conforming, but some
- buggy hosts complain. Also, Ultrix 4.0 Mips CC 2.0 has buggy volatile support.
- END_OF_FILE
- if test 9190 -ne `wc -c <'src/README'`; then
- echo shar: \"'src/README'\" unpacked with wrong size!
- fi
- # end of 'src/README'
- fi
- if test -f 'src/maketime.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/maketime.c'\"
- else
- echo shar: Extracting \"'src/maketime.c'\" \(9481 characters\)
- sed "s/^X//" >'src/maketime.c' <<'END_OF_FILE'
- X#
- X/*
- X * MAKETIME derive 32-bit time value from TM structure.
- X *
- X * Usage:
- X * int zone; Minutes west of GMT, or
- X * 48*60 for localtime
- X * time_t t;
- X * struct tm *tp; Pointer to TM structure from <time.h>
- X * t = maketime(tp,zone);
- X *
- X * Returns:
- X * -1 if failure; parameter out of range or nonsensical.
- X * else time-value.
- X * Notes:
- X * This code is quasi-public; it may be used freely in like software.
- X * It is not to be sold, nor used in licensed software without
- X * permission of the author.
- X * For everyone's benefit, please report bugs and improvements!
- X * Copyright 1981 by Ken Harrenstien, SRI International.
- X * (ARPANET: KLH @ SRI)
- X */
- X/* $Log: maketime.c,v $
- X * Revision 5.3 1991/08/19 03:13:55 eggert
- X * Add setfiledate, str2time, TZ_must_be_set.
- X *
- X * Revision 5.2 1990/11/01 05:03:30 eggert
- X * Remove lint.
- X *
- X * Revision 5.1 1990/10/04 06:30:13 eggert
- X * Calculate the GMT offset of 'xxx LT' as of xxx, not as of now.
- X * Don't assume time_t is 32 bits. Fix bugs near epoch and near end of time.
- X *
- X * Revision 5.0 1990/08/22 08:12:38 eggert
- X * Switch to GMT and fix the bugs exposed thereby.
- X * Permit dates past 1999/12/31. Ansify and Posixate.
- X *
- X * Revision 1.8 88/11/08 13:54:53 narten
- X * allow negative timezones (-24h <= x <= 24h)
- X *
- X * Revision 1.7 88/08/28 14:47:52 eggert
- X * Allow cc -R. Remove unportable "#endif XXX"s.
- X *
- X * Revision 1.6 87/12/18 17:05:58 narten
- X * include rcsparam.h
- X *
- X * Revision 1.5 87/12/18 11:35:51 narten
- X * maketime.c: fixed USG code - you have tgo call "tzset" in order to have
- X * "timezone" set. ("localtime" calls it, but it's probably better not to
- X * count on "localtime" having been called.)
- X *
- X * Revision 1.4 87/10/18 10:26:57 narten
- X * Updating version numbers. Changes relative to 1.0 are actually
- X * relative to 1.2
- X *
- X * Revision 1.3 87/09/24 13:58:45 narten
- X * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- X * warnings)
- X *
- X * Revision 1.2 87/03/27 14:21:48 jenkins
- X * Port to suns
- X *
- X * Revision 1.2 83/12/05 10:12:56 wft
- X * added cond. compilation for USG Unix; long timezone;
- X *
- X * Revision 1.1 82/05/06 11:38:00 wft
- X * Initial revision
- X *
- X */
- X
- X
- X#include "rcsbase.h"
- X
- libId(maketId, "$Id: maketime.c,v 5.3 1991/08/19 03:13:55 eggert Exp $")
- X
- static struct tm const *time2tm P((time_t));
- X
- X#define given(v) (0 <= (v)) /* Negative values are unspecified. */
- X
- static int const daytb[] = {
- X /* # days in year thus far, indexed by month (0-12!!) */
- X 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
- X};
- X
- X static time_t
- maketime(atm,zone)
- X struct tm const *atm;
- X int zone;
- X{
- X register struct tm const *tp;
- X register int i;
- X int year, yday, mon, day, hour, min, sec, leap, localzone;
- X int attempts;
- X time_t t, tres;
- X
- X attempts = 2;
- X localzone = zone==48*60;
- X tres = -1;
- X year = mon = day = 0; /* Keep lint happy. */
- X
- X do {
- X
- X if (localzone || !given(atm->tm_year)) {
- X if (tres == -1)
- X if ((tres = time((time_t*)0)) == -1)
- X return -1;
- X tp = time2tm(tres);
- X /* Get breakdowns of default time, adjusting to zone. */
- X year = tp->tm_year; /* Use to set up defaults */
- X yday = tp->tm_yday;
- X mon = tp->tm_mon;
- X day = tp->tm_mday;
- X hour = tp->tm_hour;
- X min = tp->tm_min;
- X if (localzone) {
- X tp = localtime(&tres);
- X zone =
- X min - tp->tm_min + 60*(
- X hour - tp->tm_hour + 24*(
- X /* If years differ, it's by one day. */
- X year - tp->tm_year
- X ? year - tp->tm_year
- X : yday - tp->tm_yday));
- X }
- X /* Adjust the default day, month and year according to zone. */
- X if ((min -= zone) < 0) {
- X if (hour-(59-min)/60 < 0 && --day <= 0) {
- X if (--mon < 0) {
- X --year;
- X mon = 11;
- X }
- X day = daytb[mon+1] - daytb[mon] + (mon==1&&!(year&3));
- X }
- X } else
- X if (
- X 24 <= hour+min/60 &&
- X daytb[mon+1] - daytb[mon] + (mon==1&&!(year&3)) < ++day
- X ) {
- X if (11 < ++mon) {
- X ++year;
- X mon = 0;
- X }
- X day = 1;
- X }
- X }
- X if (zone < -24*60 || 24*60 < zone)
- X return -1;
- X
- X
- X#ifdef DEBUG
- printf("first YMD: %d %d %d\n",year,mon,day);
- X#endif
- X tp = atm;
- X
- X /* First must find date, using specified year, month, day.
- X * If one of these is unspecified, it defaults either to the
- X * current date (if no more global spec was given) or to the
- X * zero-value for that spec (i.e. a more global spec was seen).
- X * Reject times that do not fit in time_t,
- X * without assuming that time_t is 32 bits or is signed.
- X */
- X if (given(tp->tm_year))
- X {
- X year = tp->tm_year;
- X mon = 0; /* Since year was given, default */
- X day = 1; /* for remaining specs is zero */
- X }
- X if (year < 69) /* 1969/12/31 OK in some timezones. */
- X return -1; /* ERR: year out of range */
- X leap = !(year&3) && (year%100 || !((year+300)%400));
- X year -= 70; /* UNIX time starts at 1970 */
- X
- X /*
- X * Find day of year.
- X */
- X {
- X if (given(tp->tm_mon))
- X { mon = tp->tm_mon; /* Month was specified */
- X day = 1; /* so set remaining default */
- X }
- X if (11 < (unsigned)mon)
- X return -1; /* ERR: bad month */
- X if (given(tp->tm_mday)) day = tp->tm_mday;
- X if(day < 1
- X || (((daytb[mon+1]-daytb[mon]) < day)
- X && (day!=29 || mon!=1 || !leap) ))
- X return -1; /* ERR: bad day */
- X yday = daytb[mon] /* Add # of days in months so far */
- X + ((leap /* Leap year, and past Feb? If */
- X && mon>1)? 1:0) /* so, add leap day for this year */
- X + day-1; /* And finally add # days this mon */
- X
- X }
- X if (leap+365 <= (unsigned)yday)
- X return -1; /* ERR: bad YDAY */
- X
- X if (year < 0) {
- X if (yday != 364)
- X return -1; /* ERR: too early */
- X t = -1;
- X } else {
- X tres = year*365; /* Get # days of years so far */
- X if (tres/365 != year)
- X return -1; /* ERR: overflow */
- X t = tres
- X + ((year+1)>>2) /* plus # of leap days since 1970 */
- X + yday; /* and finally add # days this year */
- X if (t+4 < tres)
- X return -1; /* ERR: overflow */
- X }
- X tres = t;
- X
- X if (given(i = tp->tm_wday)) /* Check WDAY if present */
- X if (i != (tres+4)%7) /* 1970/01/01 was Thu = 4 */
- X return -1; /* ERR: bad WDAY */
- X
- X#ifdef DEBUG
- printf("YMD: %d %d %d, T=%ld\n",year,mon,day,tres);
- X#endif
- X /*
- X * Now determine time. If not given, default to zeros
- X * (since time is always the least global spec)
- X */
- X tres *= 86400L; /* Get # seconds (24*60*60) */
- X if (tres/86400L != t)
- X return -1; /* ERR: overflow */
- X hour = min = sec = 0;
- X if (given(tp->tm_hour)) hour = tp->tm_hour;
- X if (given(tp->tm_min )) min = tp->tm_min;
- X if (given(tp->tm_sec )) sec = tp->tm_sec;
- X if (60 <= (unsigned)min || 60 < (unsigned)sec)
- X return -1; /* ERR: MS out of range */
- X if (24 <= (unsigned)hour)
- X if(hour != 24 || (min+sec) !=0) /* Allow 24:00 */
- X return -1; /* ERR: H out of range */
- X
- X t = tres;
- X tres += sec + 60L*(zone + min + 60*hour);
- X
- X#ifdef DEBUG
- printf("HMS: %d %d %d T=%ld\n",hour,min,sec,tres);
- X#endif
- X
- X if (!localzone) /* check for overflow */
- X return (year<0 ? (tres<0||86400L<=tres) : tres<t) ? -1 : tres;
- X
- X /* Check results; LT may have had a different GMT offset back then. */
- X tp = localtime(&tres);
- X if (given(atm->tm_sec) && atm->tm_sec != tp->tm_sec)
- X return -1; /* If seconds don't match, we're in trouble. */
- X if (!(
- X given(atm->tm_min) && atm->tm_min != tp->tm_min ||
- X given(atm->tm_hour) && atm->tm_hour != tp->tm_hour ||
- X given(atm->tm_mday) && atm->tm_mday != tp->tm_mday ||
- X given(atm->tm_mon) && atm->tm_mon != tp->tm_mon ||
- X given(atm->tm_year) && atm->tm_year != tp->tm_year
- X ))
- X return tres; /* Everything matches. */
- X
- X } while (--attempts);
- X
- X return -1;
- X}
- X
- X/*
- X* Convert Unix time to struct tm format.
- X* Use Coordinated Universal Time (UTC) if version 5 or newer;
- X* use local time otherwise.
- X*/
- X static struct tm const *
- time2tm(unixtime)
- X time_t unixtime;
- X{
- X struct tm const *tm;
- X# if TZ_must_be_set
- X static char const *TZ;
- X if (!TZ && !(TZ = getenv("TZ")))
- X faterror("TZ is not set");
- X# endif
- X if (!(tm = (RCSversion<VERSION(5) ? localtime : gmtime)(&unixtime)))
- X faterror("UTC is not available; perhaps TZ is not set?");
- X return tm;
- X}
- X
- X/*
- X* Convert Unix time to RCS format.
- X* For compatibility with older versions of RCS,
- X* dates before AD 2000 are stored without the leading "19".
- X*/
- X void
- time2date(unixtime,date)
- X time_t unixtime;
- X char date[datesize];
- X{
- X register struct tm const *tm = time2tm(unixtime);
- X VOID sprintf(date, DATEFORM,
- X tm->tm_year + (tm->tm_year<100 ? 0 : 1900),
- X tm->tm_mon+1, tm->tm_mday,
- X tm->tm_hour, tm->tm_min, tm->tm_sec
- X );
- X}
- X
- X
- X
- X static time_t
- str2time(source)
- X char const *source;
- X/* Parse a free-format date in SOURCE, yielding a Unix format time. */
- X{
- X int zone;
- X time_t unixtime;
- X struct tm parseddate;
- X
- X if (!partime(source, &parseddate, &zone))
- X faterror("can't parse date/time: %s", source);
- X if ((unixtime = maketime(&parseddate, zone)) == -1)
- X faterror("bad date/time: %s", source);
- X return unixtime;
- X}
- X
- X void
- str2date(source, target)
- X char const *source;
- X char target[datesize];
- X/* Parse a free-format date in SOURCE, convert it
- X * into RCS internal format, and store the result into TARGET.
- X */
- X{
- X time2date(str2time(source), target);
- X}
- X
- X int
- setfiledate(file, date)
- X char const *file, date[datesize];
- X/* Set the access and modification time of FILE to DATE. */
- X{
- X static struct utimbuf times; /* static so unused fields are zero */
- X char datebuf[datesize];
- X
- X if (!date)
- X return 0;
- X times.actime = times.modtime = str2time(date2str(date, datebuf));
- X return utime(file, ×);
- X}
- END_OF_FILE
- if test 9481 -ne `wc -c <'src/maketime.c'`; then
- echo shar: \"'src/maketime.c'\" unpacked with wrong size!
- fi
- # end of 'src/maketime.c'
- fi
- if test -f 'src/rcsdiff.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/rcsdiff.c'\"
- else
- echo shar: Extracting \"'src/rcsdiff.c'\" \(11285 characters\)
- sed "s/^X//" >'src/rcsdiff.c' <<'END_OF_FILE'
- X/*
- X * RCS rcsdiff operation
- X */
- X/*****************************************************************************
- X * generate difference between RCS revisions
- X *****************************************************************************
- X */
- X
- X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- X Copyright 1990, 1991 by Paul Eggert
- X Distributed under license by the Free Software Foundation, Inc.
- X
- This file is part of RCS.
- X
- RCS 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.
- X
- RCS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- X
- 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.
- X
- Report problems and direct all questions to:
- X
- X rcs-bugs@cs.purdue.edu
- X
- X*/
- X
- X
- X
- X
- X/* $Log: rcsdiff.c,v $
- X * Revision 5.10 1991/10/07 17:32:46 eggert
- X * Remove lint.
- X *
- X * Revision 5.9 1991/08/19 03:13:55 eggert
- X * Add RCSINIT, -r$. Tune.
- X *
- X * Revision 5.8 1991/04/21 11:58:21 eggert
- X * Add -x, RCSINIT, MS-DOS support.
- X *
- X * Revision 5.7 1990/12/13 06:54:07 eggert
- X * GNU diff 1.15 has -u.
- X *
- X * Revision 5.6 1990/11/01 05:03:39 eggert
- X * Remove unneeded setid check.
- X *
- X * Revision 5.5 1990/10/04 06:30:19 eggert
- X * Accumulate exit status across files.
- X *
- X * Revision 5.4 1990/09/27 01:31:43 eggert
- X * Yield 1, not EXIT_FAILURE, when diffs are found.
- X *
- X * Revision 5.3 1990/09/11 02:41:11 eggert
- X * Simplify -kkvl test.
- X *
- X * Revision 5.2 1990/09/04 17:07:19 eggert
- X * Diff's argv was too small by 1.
- X *
- X * Revision 5.1 1990/08/29 07:13:55 eggert
- X * Add -kkvl.
- X *
- X * Revision 5.0 1990/08/22 08:12:46 eggert
- X * Add -k, -V. Don't use access(). Add setuid support.
- X * Remove compile-time limits; use malloc instead.
- X * Don't pass arguments with leading '+' to diff; GNU DIFF treats them as options.
- X * Add GNU diff's flags. Make lock and temp files faster and safer.
- X * Ansify and Posixate.
- X *
- X * Revision 4.6 89/05/01 15:12:27 narten
- X * changed copyright header to reflect current distribution rules
- X *
- X * Revision 4.5 88/08/09 19:12:41 eggert
- X * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R.
- X *
- X * Revision 4.4 87/12/18 11:37:46 narten
- X * changes Jay Lepreau made in the 4.3 BSD version, to add support for
- X * "-i", "-w", and "-t" flags and to permit flags to be bundled together,
- X * merged in.
- X *
- X * Revision 4.3 87/10/18 10:31:42 narten
- X * Updating version numbers. Changes relative to 1.1 actually
- X * relative to 4.1
- X *
- X * Revision 1.3 87/09/24 13:59:21 narten
- X * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- X * warnings)
- X *
- X * Revision 1.2 87/03/27 14:22:15 jenkins
- X * Port to suns
- X *
- X * Revision 4.1 83/05/03 22:13:19 wft
- X * Added default branch, option -q, exit status like diff.
- X * Added fterror() to replace faterror().
- X *
- X * Revision 3.6 83/01/15 17:52:40 wft
- X * Expanded mainprogram to handle multiple RCS files.
- X *
- X * Revision 3.5 83/01/06 09:33:45 wft
- X * Fixed passing of -c (context) option to diff.
- X *
- X * Revision 3.4 82/12/24 15:28:38 wft
- X * Added call to catchsig().
- X *
- X * Revision 3.3 82/12/10 16:08:17 wft
- X * Corrected checking of return code from diff; improved error msgs.
- X *
- X * Revision 3.2 82/12/04 13:20:09 wft
- X * replaced getdelta() with gettree(). Changed diagnostics.
- X *
- X * Revision 3.1 82/11/28 19:25:04 wft
- X * Initial revision.
- X *
- X */
- X#include "rcsbase.h"
- X
- X#if DIFF_L
- static char const *setup_label P((struct buf*,char const*,char const[datesize]));
- X#endif
- static void cleanup P((void));
- X
- static int exitstatus;
- static RILE *workptr;
- static struct stat workstat;
- X
- mainProg(rcsdiffId, "rcsdiff", "$Id: rcsdiff.c,v 5.10 1991/10/07 17:32:46 eggert Exp $")
- X{
- X static char const cmdusage[] =
- X "\nrcsdiff usage: rcsdiff [-q] [-rrev1 [-rrev2]] [-Vn] [diff options] file ...";
- X
- X int revnums; /* counter for revision numbers given */
- X char const *rev1, *rev2; /* revision numbers from command line */
- X char const *xrev1, *xrev2; /* expanded revision numbers */
- X char const *expandarg, *lexpandarg, *versionarg;
- X#if DIFF_L
- X static struct buf labelbuf[2];
- X int file_labels;
- X char const **diff_label1, **diff_label2;
- X char date2[datesize];
- X#endif
- X char const *cov[9];
- X char const **diffv, **diffp; /* argv for subsidiary diff */
- X char const **pp, *p, *diffvstr;
- X struct buf commarg;
- X struct buf numericrev; /* expanded revision number */
- X struct hshentries *gendeltas; /* deltas to be generated */
- X struct hshentry * target;
- X char *a, *dcp, **newargv;
- X register c;
- X
- X exitstatus = DIFF_SUCCESS;
- X
- X bufautobegin(&commarg);
- X bufautobegin(&numericrev);
- X revnums = 0;
- X rev1 = rev2 = xrev2 = nil;
- X#if DIFF_L
- X file_labels = 0;
- X#endif
- X expandarg = versionarg = 0;
- X suffixes = X_DEFAULT;
- X
- X /* Room for args + 2 i/o [+ 2 labels] + 1 file + 1 trailing null. */
- X diffp = diffv = tnalloc(char const*, argc + 4 + 2*DIFF_L);
- X *diffp++ = nil;
- X *diffp++ = nil;
- X *diffp++ = DIFF;
- X
- X argc = getRCSINIT(argc, argv, &newargv);
- X argv = newargv;
- X while (a = *++argv, 0<--argc && *a++=='-') {
- X dcp = a;
- X while (c = *a++) switch (c) {
- X case 'r':
- X switch (++revnums) {
- X case 1: rev1=a; break;
- X case 2: rev2=a; break;
- X default: faterror("too many revision numbers");
- X }
- X goto option_handled;
- X#if DIFF_L
- X case 'L':
- X if (++file_labels == 2)
- X faterror("too many -L options");
- X /* fall into */
- X#endif
- X case 'C': case 'D': case 'F': case 'I':
- X *dcp++ = c;
- X if (*a)
- X do *dcp++ = *a++;
- X while (*a);
- X else {
- X if (!--argc)
- X faterror("-%c needs following argument%s",
- X c, cmdusage
- X );
- X *diffp++ = *argv++;
- X }
- X break;
- X case 'B': case 'H': case 'T':
- X case '0': case '1': case '2': case '3': case '4':
- X case '5': case '6': case '7': case '8': case '9':
- X case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- X case 'h': case 'i': case 'n': case 'p':
- X case 't': case 'u': case 'w':
- X *dcp++ = c;
- X break;
- X case 'q':
- X quietflag=true;
- X break;
- X case 'x':
- X suffixes = *argv + 2;
- X goto option_handled;
- X case 'V':
- X versionarg = *argv;
- X setRCSversion(versionarg);
- X goto option_handled;
- X case 'k':
- X expandarg = *argv;
- X if (0 <= str2expmode(expandarg+2))
- X goto option_handled;
- X /* fall into */
- X default:
- X faterror("unknown option: %s%s", *argv, cmdusage);
- X };
- X option_handled:
- X if (dcp != *argv+1) {
- X *dcp = 0;
- X *diffp++ = *argv;
- X }
- X } /* end of option processing */
- X
- X if (argc<1) faterror("no input file%s", cmdusage);
- X
- X for (pp = diffv+3, c = 0; pp<diffp; )
- X c += strlen(*pp++) + 1;
- X diffvstr = a = tnalloc(char, c + 1);
- X for (pp = diffv+3; pp<diffp; ) {
- X p = *pp++;
- X *a++ = ' ';
- X while ((*a = *p++))
- X a++;
- X }
- X *a = 0;
- X
- X#if DIFF_L
- X diff_label1 = diff_label2 = nil;
- X if (file_labels < 2) {
- X if (!file_labels)
- X diff_label1 = diffp++;
- X diff_label2 = diffp++;
- X }
- X#endif
- X diffp[2] = nil;
- X
- X cov[0] = 0;
- X cov[2] = CO;
- X cov[3] = "-q";
- X
- X /* now handle all filenames */
- X do {
- X ffree();
- X
- X if (pairfilenames(argc, argv, rcsreadopen, true, false) <= 0)
- X continue;
- X diagnose("===================================================================\nRCS file: %s\n",RCSfilename);
- X if (!rev2) {
- X /* Make sure work file is readable, and get its status. */
- X if (!(workptr = Iopen(workfilename,FOPEN_R_WORK,&workstat))) {
- X eerror(workfilename);
- X continue;
- X }
- X }
- X
- X
- X gettree(); /* reads in the delta tree */
- X
- X if (Head==nil) {
- X error("no revisions present");
- X continue;
- X }
- X if (revnums==0 || !*rev1)
- X rev1 = Dbranch ? Dbranch : Head->num;
- X
- X if (!fexpandsym(rev1, &numericrev, workptr)) continue;
- X if (!(target=genrevs(numericrev.string,(char *)nil,(char *)nil,(char *)nil,&gendeltas))) continue;
- X xrev1=target->num;
- X#if DIFF_L
- X if (diff_label1)
- X *diff_label1 = setup_label(&labelbuf[0], target->num, target->date);
- X#endif
- X
- X lexpandarg = expandarg;
- X if (revnums==2) {
- X if (!fexpandsym(
- X *rev2 ? rev2 : Dbranch ? Dbranch : Head->num,
- X &numericrev,
- X workptr
- X ))
- X continue;
- X if (!(target=genrevs(numericrev.string,(char *)nil,(char *)nil,(char *)nil,&gendeltas))) continue;
- X xrev2=target->num;
- X } else if (
- X target->lockedby
- X && !lexpandarg
- X && Expand == KEYVAL_EXPAND
- X && WORKMODE(RCSstat.st_mode,true) == workstat.st_mode
- X )
- X lexpandarg = "-kkvl";
- X Izclose(&workptr);
- X#if DIFF_L
- X if (diff_label2)
- X if (revnums == 2)
- X *diff_label2 = setup_label(&labelbuf[1], target->num, target->date);
- X else {
- X time2date(workstat.st_mtime, date2);
- X *diff_label2 = setup_label(&labelbuf[1], workfilename, date2);
- X }
- X#endif
- X
- X diagnose("retrieving revision %s\n", xrev1);
- X bufscpy(&commarg, "-p");
- X bufscat(&commarg, xrev1);
- X
- X cov[1] = diffp[0] = maketemp(0);
- X pp = &cov[4];
- X *pp++ = commarg.string;
- X if (lexpandarg)
- X *pp++ = lexpandarg;
- X if (versionarg)
- X *pp++ = versionarg;
- X *pp++ = RCSfilename;
- X *pp = 0;
- X
- X if (runv(cov)) {
- X error("co failed");
- X continue;
- X }
- X if (!rev2) {
- X diffp[1] = workfilename;
- X if (workfilename[0] == '+') {
- X /* Some diffs have options with leading '+'. */
- X char *dp = ftnalloc(char, strlen(workfilename)+3);
- X diffp[1] = dp;
- X *dp++ = '.';
- X *dp++ = SLASH;
- X VOID strcpy(dp, workfilename);
- X }
- X } else {
- X diagnose("retrieving revision %s\n",xrev2);
- X bufscpy(&commarg, "-p");
- X bufscat(&commarg, xrev2);
- X cov[1] = diffp[1] = maketemp(1);
- X cov[4] = commarg.string;
- X if (runv(cov)) {
- X error("co failed");
- X continue;
- X }
- X }
- X if (!rev2)
- X diagnose("diff%s -r%s %s\n", diffvstr, xrev1, workfilename);
- X else
- X diagnose("diff%s -r%s -r%s\n", diffvstr, xrev1, xrev2);
- X
- X switch (runv(diffv)) {
- X case DIFF_SUCCESS:
- X break;
- X case DIFF_FAILURE:
- X if (exitstatus == DIFF_SUCCESS)
- X exitstatus = DIFF_FAILURE;
- X break;
- X default:
- X error("diff failed");
- X }
- X } while (cleanup(),
- X ++argv, --argc >=1);
- X
- X
- X tempunlink();
- X exitmain(exitstatus);
- X}
- X
- X static void
- cleanup()
- X{
- X if (nerror) exitstatus = DIFF_TROUBLE;
- X Izclose(&finptr);
- X Izclose(&workptr);
- X}
- X
- X#if lint
- X# define exiterr rdiffExit
- X#endif
- X exiting void
- exiterr()
- X{
- X tempunlink();
- X _exit(DIFF_TROUBLE);
- X}
- X
- X#if DIFF_L
- X static char const *
- setup_label(b, name, date)
- X struct buf *b;
- X char const *name;
- X char const date[datesize];
- X{
- X char *p;
- X size_t l = strlen(name) + 3;
- X bufalloc(b, l+datesize);
- X p = b->string;
- X VOID sprintf(p, "-L%s\t", name);
- X VOID date2str(date, p+l);
- X return p;
- X}
- X#endif
- END_OF_FILE
- if test 11285 -ne `wc -c <'src/rcsdiff.c'`; then
- echo shar: \"'src/rcsdiff.c'\" unpacked with wrong size!
- fi
- # end of 'src/rcsdiff.c'
- fi
- if test -f 'src/rcsfcmp.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/rcsfcmp.c'\"
- else
- echo shar: Extracting \"'src/rcsfcmp.c'\" \(8406 characters\)
- sed "s/^X//" >'src/rcsfcmp.c' <<'END_OF_FILE'
- X/*
- X * RCS file comparison
- X */
- X/*****************************************************************************
- X * rcsfcmp()
- X * Testprogram: define FCMPTEST
- X *****************************************************************************
- X */
- X
- X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- X Copyright 1990, 1991 by Paul Eggert
- X Distributed under license by the Free Software Foundation, Inc.
- X
- This file is part of RCS.
- X
- RCS 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.
- X
- RCS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- X
- 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.
- X
- Report problems and direct all questions to:
- X
- X rcs-bugs@cs.purdue.edu
- X
- X*/
- X
- X
- X
- X
- X
- X/* $Log: rcsfcmp.c,v $
- X * Revision 5.9 1991/10/07 17:32:46 eggert
- X * Count log lines correctly.
- X *
- X * Revision 5.8 1991/08/19 03:13:55 eggert
- X * Tune.
- X *
- X * Revision 5.7 1991/04/21 11:58:22 eggert
- X * Fix errno bug. Add MS-DOS support.
- X *
- X * Revision 5.6 1991/02/28 19:18:47 eggert
- X * Open work file at most once.
- X *
- X * Revision 5.5 1990/11/27 09:26:05 eggert
- X * Fix comment leader bug.
- X *
- X * Revision 5.4 1990/11/01 05:03:42 eggert
- X * Permit arbitrary data in logs and comment leaders.
- X *
- X * Revision 5.3 1990/09/11 02:41:15 eggert
- X * Don't ignore differences inside keyword strings if -ko is set.
- X *
- X * Revision 5.1 1990/08/29 07:13:58 eggert
- X * Clean old log messages too.
- X *
- X * Revision 5.0 1990/08/22 08:12:49 eggert
- X * Don't append "checked in with -k by " log to logs,
- X * so that checking in a program with -k doesn't change it.
- X * Ansify and Posixate. Remove lint.
- X *
- X * Revision 4.5 89/05/01 15:12:42 narten
- X * changed copyright header to reflect current distribution rules
- X *
- X * Revision 4.4 88/08/09 19:12:50 eggert
- X * Shrink stdio code size.
- X *
- X * Revision 4.3 87/12/18 11:40:02 narten
- X * lint cleanups (Guy Harris)
- X *
- X * Revision 4.2 87/10/18 10:33:06 narten
- X * updting version number. Changes relative to 1.1 actually relative to
- X * 4.1
- X *
- X * Revision 1.2 87/03/27 14:22:19 jenkins
- X * Port to suns
- X *
- X * Revision 4.1 83/05/10 16:24:04 wft
- X * Marker matching now uses trymatch(). Marker pattern is now
- X * checked precisely.
- X *
- X * Revision 3.1 82/12/04 13:21:40 wft
- X * Initial revision.
- X *
- X */
- X
- X/*
- X#define FCMPTEST
- X*/
- X/* Testprogram; prints out whether two files are identical,
- X * except for keywords
- X */
- X
- X#include "rcsbase.h"
- X
- libId(fcmpId, "$Id: rcsfcmp.c,v 5.9 1991/10/07 17:32:46 eggert Exp $")
- X
- X static int
- discardkeyval(c, f)
- X register int c;
- X register RILE *f;
- X{
- X for (;;)
- X switch (c) {
- X case KDELIM:
- X case '\n':
- X return c;
- X default:
- X Igeteof(f, c, return EOF;);
- X break;
- X }
- X}
- X
- X int
- rcsfcmp(xfp, xstatp, ufname, delta)
- X register RILE *xfp;
- X struct stat const *xstatp;
- X char const *ufname;
- X struct hshentry const *delta;
- X/* Compare the files xfp and ufname. Return zero
- X * if xfp has the same contents as ufname and neither has keywords,
- X * otherwise -1 if they are the same ignoring keyword values,
- X * and 1 if they differ even ignoring
- X * keyword values. For the LOG-keyword, rcsfcmp skips the log message
- X * given by the parameter delta in xfp. Thus, rcsfcmp returns nonpositive
- X * if xfp contains the same as ufname, with the keywords expanded.
- X * Implementation: character-by-character comparison until $ is found.
- X * If a $ is found, read in the marker keywords; if they are real keywords
- X * and identical, read in keyword value. If value is terminated properly,
- X * disregard it and optionally skip log message; otherwise, compare value.
- X */
- X{
- X register int xc, uc;
- X char xkeyword[keylength+2];
- X int eqkeyvals;
- X register RILE *ufp;
- X register int xeof, ueof;
- X register char * tp;
- X register char const *sp;
- X int result;
- X enum markers match1;
- X struct stat ustat;
- X
- X if (!(ufp = Iopen(ufname, FOPEN_R_WORK, &ustat))) {
- X efaterror(ufname);
- X }
- X xeof = ueof = false;
- X if (Expand==OLD_EXPAND) {
- X if (!(result = xstatp->st_size!=ustat.st_size)) {
- X# if has_mmap && large_memory
- X result = !!memcmp(xfp->base,ufp->base,(size_t)xstatp->st_size);
- X# else
- X for (;;) {
- X /* get the next characters */
- X Igeteof(xfp, xc, xeof=true;);
- X Igeteof(ufp, uc, ueof=true;);
- X if (xeof | ueof)
- X goto eof;
- X if (xc != uc)
- X goto return1;
- X }
- X# endif
- X }
- X } else {
- X xc = 0;
- X uc = 0; /* Keep lint happy. */
- X result = 0;
- X
- X for (;;) {
- X if (xc != KDELIM) {
- X /* get the next characters */
- X Igeteof(xfp, xc, xeof=true;);
- X Igeteof(ufp, uc, ueof=true;);
- X if (xeof | ueof)
- X goto eof;
- X } else {
- X /* try to get both keywords */
- X tp = xkeyword;
- X for (;;) {
- X Igeteof(xfp, xc, xeof=true;);
- X Igeteof(ufp, uc, ueof=true;);
- X if (xeof | ueof)
- X goto eof;
- X if (xc != uc)
- X break;
- X switch (xc) {
- X default:
- X if (xkeyword+keylength <= tp)
- X break;
- X *tp++ = xc;
- X continue;
- X case '\n': case KDELIM: case VDELIM:
- X break;
- X }
- X break;
- X }
- X if (
- X (xc==KDELIM || xc==VDELIM) && (uc==KDELIM || uc==VDELIM) &&
- X (*tp = xc, (match1 = trymatch(xkeyword)) != Nomatch)
- X ) {
- X#ifdef FCMPTEST
- X VOID printf("found common keyword %s\n",xkeyword);
- X#endif
- X result = -1;
- X for (;;) {
- X if (xc != uc) {
- X xc = discardkeyval(xc, xfp);
- X uc = discardkeyval(uc, ufp);
- X if ((xeof = xc==EOF) | (ueof = uc==EOF))
- X goto eof;
- X eqkeyvals = false;
- X break;
- X }
- X switch (xc) {
- X default:
- X Igeteof(xfp, xc, xeof=true;);
- X Igeteof(ufp, uc, ueof=true;);
- X if (xeof | ueof)
- X goto eof;
- X continue;
- X
- X case '\n': case KDELIM:
- X eqkeyvals = true;
- X break;
- X }
- X break;
- X }
- X if (xc != uc)
- X goto return1;
- X if (xc==KDELIM) {
- X /* Skip closing KDELIM. */
- X Igeteof(xfp, xc, xeof=true;);
- X Igeteof(ufp, uc, ueof=true;);
- X if (xeof | ueof)
- X goto eof;
- X /* if the keyword is LOG, also skip the log message in xfp*/
- X if (match1==Log) {
- X /* first, compute the number of line feeds in log msg */
- X unsigned lncnt;
- X size_t ls, ccnt;
- X sp = delta->log.string;
- X ls = delta->log.size;
- X if (ls<sizeof(ciklog)-1 || memcmp(sp,ciklog,sizeof(ciklog)-1)) {
- X /* This log message was inserted. */
- X lncnt = 3;
- X while (ls--) if (*sp++=='\n') lncnt++;
- X for (;;) {
- X if (xc=='\n')
- X if(--lncnt==0) break;
- X Igeteof(xfp, xc, goto returnresult;);
- X }
- X /* skip last comment leader */
- X /* Can't just skip another line here, because there may be */
- X /* additional characters on the line (after the Log....$) */
- X for (ccnt=Comment.size; ccnt--; ) {
- X Igeteof(xfp, xc, goto returnresult;);
- X if(xc=='\n') break;
- X /*
- X * Read to the end of the comment leader or '\n',
- X * whatever comes first. Some editors strip
- X * trailing white space from a leader like " * ".
- X */
- X }
- X }
- X }
- X } else {
- X /* both end in the same character, but not a KDELIM */
- X /* must compare string values.*/
- X#ifdef FCMPTEST
- X VOID printf("non-terminated keywords %s, potentially different values\n",xkeyword);
- X#endif
- X if (!eqkeyvals)
- X goto return1;
- X }
- X }
- X }
- X if (xc != uc)
- X goto return1;
- X }
- X }
- X
- X eof:
- X if (xeof==ueof)
- X goto returnresult;
- X return1:
- X result = 1;
- X returnresult:
- X Ifclose(ufp);
- X return result;
- X}
- X
- X
- X
- X#ifdef FCMPTEST
- X
- char const cmdid[] = "rcsfcmp";
- X
- main(argc, argv)
- int argc; char *argv[];
- X/* first argument: comment leader; 2nd: log message, 3rd: expanded file,
- X * 4th: unexpanded file
- X */
- X{ struct hshentry delta;
- X
- X Comment.string = argv[1];
- X Comment.size = strlen(argv[1]);
- X delta.log.string = argv[2];
- X delta.log.size = strlen(argv[2]);
- X if (rcsfcmp(Iopen(argv[3], FOPEN_R_WORK, (struct stat*)0), argv[4], &delta))
- X VOID printf("files are the same\n");
- X else VOID printf("files are different\n");
- X}
- X#endif
- END_OF_FILE
- if test 8406 -ne `wc -c <'src/rcsfcmp.c'`; then
- echo shar: \"'src/rcsfcmp.c'\" unpacked with wrong size!
- fi
- # end of 'src/rcsfcmp.c'
- fi
- if test -f 'src/rcskeep.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/rcskeep.c'\"
- else
- echo shar: Extracting \"'src/rcskeep.c'\" \(10028 characters\)
- sed "s/^X//" >'src/rcskeep.c' <<'END_OF_FILE'
- X/*
- X * RCS keyword extraction
- X */
- X/*****************************************************************************
- X * main routine: getoldkeys()
- X * Testprogram: define KEEPTEST
- X *****************************************************************************
- X */
- X
- X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- X Copyright 1990, 1991 by Paul Eggert
- X Distributed under license by the Free Software Foundation, Inc.
- X
- This file is part of RCS.
- X
- RCS 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.
- X
- RCS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- X
- 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.
- X
- Report problems and direct all questions to:
- X
- X rcs-bugs@cs.purdue.edu
- X
- X*/
- X
- X
- X
- X/* $Log: rcskeep.c,v $
- X * Revision 5.4 1991/08/19 03:13:55 eggert
- X * Tune.
- X *
- X * Revision 5.3 1991/04/21 11:58:25 eggert
- X * Shorten names to keep them distinct on shortname hosts.
- X *
- X * Revision 5.2 1990/10/04 06:30:20 eggert
- X * Parse time zone offsets; future RCS versions may output them.
- X *
- X * Revision 5.1 1990/09/20 02:38:56 eggert
- X * ci -k now checks dates more thoroughly.
- X *
- X * Revision 5.0 1990/08/22 08:12:53 eggert
- X * Retrieve old log message if there is one.
- X * Don't require final newline.
- X * Remove compile-time limits; use malloc instead. Tune.
- X * Permit dates past 1999/12/31. Ansify and Posixate.
- X *
- X * Revision 4.6 89/05/01 15:12:56 narten
- X * changed copyright header to reflect current distribution rules
- X *
- X * Revision 4.5 88/08/09 19:13:03 eggert
- X * Remove lint and speed up by making FILE *fp local, not global.
- X *
- X * Revision 4.4 87/12/18 11:44:21 narten
- X * more lint cleanups (Guy Harris)
- X *
- X * Revision 4.3 87/10/18 10:35:50 narten
- X * Updating version numbers. Changes relative to 1.1 actually relative
- X * to 4.1
- X *
- X * Revision 1.3 87/09/24 14:00:00 narten
- X * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- X * warnings)
- X *
- X * Revision 1.2 87/03/27 14:22:29 jenkins
- X * Port to suns
- X *
- X * Revision 4.1 83/05/10 16:26:44 wft
- X * Added new markers Id and RCSfile; extraction added.
- X * Marker matching with trymatch().
- X *
- X * Revision 3.2 82/12/24 12:08:26 wft
- X * added missing #endif.
- X *
- X * Revision 3.1 82/12/04 13:22:41 wft
- X * Initial revision.
- X *
- X */
- X
- X/*
- X#define KEEPTEST
- X*/
- X/* Testprogram; prints out the keyword values found. */
- X
- X#include "rcsbase.h"
- X
- libId(keepId, "$Id: rcskeep.c,v 5.4 1991/08/19 03:13:55 eggert Exp $")
- X
- static int checknum P((char const*,int));
- static int getval P((RILE*,struct buf*,int));
- static int get0val P((int,RILE*,struct buf*,int));
- static int keepdate P((RILE*));
- static int keepid P((int,RILE*,struct buf*));
- static int keeprev P((RILE*));
- X
- int prevkeys;
- struct buf prevauthor, prevdate, prevrev, prevstate;
- X
- X int
- getoldkeys(fp)
- X register RILE *fp;
- X/* Function: Tries to read keyword values for author, date,
- X * revision number, and state out of the file fp.
- X * If FNAME is nonnull, it is opened and closed instead of using FP.
- X * The results are placed into
- X * prevauthor, prevdate, prevrev, prevstate.
- X * Aborts immediately if it finds an error and returns false.
- X * If it returns true, it doesn't mean that any of the
- X * values were found; instead, check to see whether the corresponding arrays
- X * contain the empty string.
- X */
- X{
- X register int c;
- X char keyword[keylength+1];
- X register char * tp;
- X int needs_closing;
- X
- X if (prevkeys)
- X return true;
- X
- X needs_closing = false;
- X if (!fp) {
- X if (!(fp = Iopen(workfilename, FOPEN_R_WORK, (struct stat*)0))) {
- X eerror(workfilename);
- X return false;
- X }
- X needs_closing = true;
- X }
- X
- X /* initialize to empty */
- X bufscpy(&prevauthor, "");
- X bufscpy(&prevdate, "");
- X bufscpy(&prevrev, "");
- X bufscpy(&prevstate, "");
- X
- X c = '\0'; /* anything but KDELIM */
- X for (;;) {
- X if ( c==KDELIM) {
- X do {
- X /* try to get keyword */
- X tp = keyword;
- X for (;;) {
- X Igeteof(fp, c, goto ok;);
- X switch (c) {
- X default:
- X if (keyword+keylength <= tp)
- X break;
- X *tp++ = c;
- X continue;
- X
- X case '\n': case KDELIM: case VDELIM:
- X break;
- X }
- X break;
- X }
- X } while (c==KDELIM);
- X if (c!=VDELIM) continue;
- X *tp = c;
- X Igeteof(fp, c, break;);
- X switch (c) {
- X case ' ': case '\t': break;
- X default: continue;
- X }
- X
- X switch (trymatch(keyword)) {
- X case Author:
- X if (!keepid(0, fp, &prevauthor))
- X return false;
- X c = 0;
- X break;
- X case Date:
- X if (!(c = keepdate(fp)))
- X return false;
- X break;
- X case Header:
- X case Id:
- X if (!(
- X getval(fp, (struct buf*)nil, false) &&
- X keeprev(fp) &&
- X (c = keepdate(fp)) &&
- X keepid(c, fp, &prevauthor) &&
- X keepid(0, fp, &prevstate)
- X ))
- X return false;
- X /* Skip either ``who'' (new form) or ``Locker: who'' (old). */
- X if (getval(fp, (struct buf*)nil, true) &&
- X getval(fp, (struct buf*)nil, true))
- X c = 0;
- X else if (nerror)
- X return false;
- X else
- X c = KDELIM;
- X break;
- X case Locker:
- X case Log:
- X case RCSfile:
- X case Source:
- X if (!getval(fp, (struct buf*)nil, false))
- X return false;
- X c = 0;
- X break;
- X case Revision:
- X if (!keeprev(fp))
- X return false;
- X c = 0;
- X break;
- X case State:
- X if (!keepid(0, fp, &prevstate))
- X return false;
- X c = 0;
- X break;
- X default:
- X continue;
- X }
- X if (!c)
- X Igeteof(fp, c, c=0;);
- X if (c != KDELIM) {
- X error("closing %c missing on keyword", KDELIM);
- X return false;
- X }
- X if (*prevauthor.string && *prevdate.string && *prevrev.string && *prevstate.string) {
- X break;
- X }
- X }
- X Igeteof(fp, c, break;);
- X }
- X
- X ok:
- X if (needs_closing)
- X Ifclose(fp);
- X else
- X Irewind(fp);
- X prevkeys = true;
- X return true;
- X}
- X
- X static int
- badly_terminated()
- X{
- X error("badly terminated keyword value");
- X return false;
- X}
- X
- X static int
- getval(fp, target, optional)
- X register RILE *fp;
- X struct buf *target;
- X int optional;
- X/* Reads a keyword value from FP into TARGET.
- X * Returns true if one is found, false otherwise.
- X * Does not modify target if it is nil.
- X * Do not report an error if OPTIONAL is set and KDELIM is found instead.
- X */
- X{
- X int c;
- X Igeteof(fp, c, return badly_terminated(););
- X return get0val(c, fp, target, optional);
- X}
- X
- X static int
- get0val(c, fp, target, optional)
- X register int c;
- X register RILE *fp;
- X struct buf *target;
- X int optional;
- X/* Reads a keyword value from C+FP into TARGET, perhaps OPTIONALly.
- X * Same as getval, except C is the lookahead character.
- X */
- X{ register char * tp;
- X char const *tlim;
- X register int got1;
- X
- X if (target) {
- X bufalloc(target, 1);
- X tp = target->string;
- X tlim = tp + target->size;
- X } else
- X tlim = tp = 0;
- X got1 = false;
- X for (;;) {
- X switch (c) {
- X default:
- X got1 = true;
- X if (tp) {
- X *tp++ = c;
- X if (tlim <= tp)
- X tp = bufenlarge(target, &tlim);
- X }
- X break;
- X
- X case ' ':
- X case '\t':
- X if (tp) {
- X *tp = 0;
- X# ifdef KEEPTEST
- X VOID printf("getval: %s\n", target);
- X# endif
- X }
- X if (!got1)
- X error("too much white space in keyword value");
- X return got1;
- X
- X case KDELIM:
- X if (!got1 && optional)
- X return false;
- X /* fall into */
- X case '\n':
- X case 0:
- X return badly_terminated();
- X }
- X Igeteof(fp, c, return badly_terminated(););
- X }
- X}
- X
- X
- X static int
- keepdate(fp)
- X RILE *fp;
- X/* Function: reads a date prevdate; checks format
- X * Return 0 on error, lookahead character otherwise.
- X */
- X{
- X struct buf prevday, prevtime, prevzone;
- X register char const *p;
- X register int c;
- X
- X c = 0;
- X bufautobegin(&prevday);
- X if (getval(fp,&prevday,false)) {
- X bufautobegin(&prevtime);
- X if (getval(fp,&prevtime,false)) {
- X bufautobegin(&prevzone);
- X bufscpy(&prevzone, "");
- X Igeteof(fp, c, c=0;);
- X if (c=='-' || c=='+')
- X if (!get0val(c,fp,&prevzone,false))
- X c = 0;
- X else
- X Igeteof(fp, c, c=0;);
- X if (c) {
- X p = prevday.string;
- X bufalloc(&prevdate, strlen(p) + strlen(prevtime.string) + strlen(prevzone.string) + 5);
- X VOID sprintf(prevdate.string, "%s%s %s %s",
- X /* Parse dates put out by old versions of RCS. */
- X isdigit(p[0]) && isdigit(p[1]) && p[2]=='/' ? "19" : "",
- X p, prevtime.string, prevzone.string
- X );
- X }
- X bufautoend(&prevzone);
- X }
- X bufautoend(&prevtime);
- X }
- X bufautoend(&prevday);
- X return c;
- X}
- X
- X static int
- keepid(c, fp, b)
- X int c;
- X RILE *fp;
- X struct buf *b;
- X/* Get previous identifier from C+FP into B. */
- X{
- X if (!c)
- X Igeteof(fp, c, return false;);
- X if (!get0val(c, fp, b, false))
- X return false;
- X checksid(b->string);
- X return true;
- X}
- X
- X static int
- keeprev(fp)
- X RILE *fp;
- X/* Get previous revision from FP into prevrev. */
- X{
- X return getval(fp,&prevrev,false) && checknum(prevrev.string,-1);
- X}
- X
- X
- X static int
- checknum(sp,fields)
- X register char const *sp;
- X int fields;
- X{ register int dotcount;
- X dotcount=0;
- X while(*sp) {
- X if (*sp=='.') dotcount++;
- X else if (!isdigit(*sp)) return false;
- X sp++;
- X }
- X return fields<0 ? dotcount&1 : dotcount==fields;
- X}
- X
- X
- X
- X#ifdef KEEPTEST
- X
- char const cmdid[] ="keeptest";
- X
- X int
- main(argc, argv)
- int argc; char *argv[];
- X{
- X while (*(++argv)) {
- X workfilename = *argv;
- X getoldkeys((RILE*)0);
- X VOID printf("%s: revision: %s, date: %s, author: %s, state: %s\n",
- X *argv, prevrev.string, prevdate.string, prevauthor.string, prevstate.string);
- X }
- X exitmain(EXIT_SUCCESS);
- X}
- X#endif
- END_OF_FILE
- if test 10028 -ne `wc -c <'src/rcskeep.c'`; then
- echo shar: \"'src/rcskeep.c'\" unpacked with wrong size!
- fi
- # end of 'src/rcskeep.c'
- fi
- if test -f 'src/rcsmerge.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/rcsmerge.c'\"
- else
- echo shar: Extracting \"'src/rcsmerge.c'\" \(6990 characters\)
- sed "s/^X//" >'src/rcsmerge.c' <<'END_OF_FILE'
- X/*
- X * rcsmerge operation
- X */
- X/*****************************************************************************
- X * join 2 revisions with respect to a third
- X *****************************************************************************
- X */
- X
- X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- X Copyright 1990, 1991 by Paul Eggert
- X Distributed under license by the Free Software Foundation, Inc.
- X
- This file is part of RCS.
- X
- RCS 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.
- X
- RCS is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- X
- 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.
- X
- Report problems and direct all questions to:
- X
- X rcs-bugs@cs.purdue.edu
- X
- X*/
- X
- X
- X
- X/* $Log: rcsmerge.c,v $
- X * Revision 5.7 1991/11/20 17:58:09 eggert
- X * Don't Iopen(f, "r+"); it's not portable.
- X *
- X * Revision 5.6 1991/08/19 03:13:55 eggert
- X * Add -r$. Tune.
- X *
- X * Revision 5.5 1991/04/21 11:58:27 eggert
- X * Add -x, RCSINIT, MS-DOS support.
- X *
- X * Revision 5.4 1991/02/25 07:12:43 eggert
- X * Merging a revision to itself is no longer an error.
- X *
- X * Revision 5.3 1990/11/01 05:03:50 eggert
- X * Remove unneeded setid check.
- X *
- X * Revision 5.2 1990/09/04 08:02:28 eggert
- X * Check for I/O error when reading working file.
- X *
- X * Revision 5.1 1990/08/29 07:14:04 eggert
- X * Add -q. Pass -L options to merge.
- X *
- X * Revision 5.0 1990/08/22 08:13:41 eggert
- X * Propagate merge's exit status.
- X * Remove compile-time limits; use malloc instead.
- X * Make lock and temp files faster and safer. Ansify and Posixate. Add -V.
- X * Don't use access(). Tune.
- X *
- X * Revision 4.5 89/05/01 15:13:16 narten
- X * changed copyright header to reflect current distribution rules
- X *
- X * Revision 4.4 88/08/09 19:13:13 eggert
- X * Beware merging into a readonly file.
- X * Beware merging a revision to itself (no change).
- X * Use execv(), not system(); yield exit status like diff(1)'s.
- X *
- X * Revision 4.3 87/10/18 10:38:02 narten
- X * Updating version numbers. Changes relative to version 1.1
- X * actually relative to 4.1
- X *
- X * Revision 1.3 87/09/24 14:00:31 narten
- X * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- X * warnings)
- X *
- X * Revision 1.2 87/03/27 14:22:36 jenkins
- X * Port to suns
- X *
- X * Revision 4.1 83/03/28 11:14:57 wft
- X * Added handling of default branch.
- X *
- X * Revision 3.3 82/12/24 15:29:00 wft
- X * Added call to catchsig().
- X *
- X * Revision 3.2 82/12/10 21:32:02 wft
- X * Replaced getdelta() with gettree(); improved error messages.
- X *
- X * Revision 3.1 82/11/28 19:27:44 wft
- X * Initial revision.
- X *
- X */
- X#include "rcsbase.h"
- X
- static char const co[] = CO;
- X
- mainProg(rcsmergeId, "rcsmerge", "$Id: rcsmerge.c,v 5.7 1991/11/20 17:58:09 eggert Exp $")
- X{
- X static char const cmdusage[] =
- X "\nrcsmerge usage: rcsmerge -rrev1 [-rrev2] [-p] [-Vn] file";
- X static char const quietarg[] = "-q";
- X
- X register int i;
- X char *a, **newargv;
- X char const *arg[3];
- X char const *rev[2]; /*revision numbers*/
- X char const *expandarg, *versionarg;
- X int tostdout;
- X int status;
- X RILE *workptr;
- X struct buf commarg;
- X struct buf numericrev; /* holds expanded revision number */
- X struct hshentries *gendeltas; /* deltas to be generated */
- X struct hshentry * target;
- X
- X bufautobegin(&commarg);
- X bufautobegin(&numericrev);
- X rev[0] = rev[1] = nil;
- X status = 0; /* Keep lint happy. */
- X tostdout = false;
- X expandarg = versionarg = quietarg; /* i.e. a no-op */
- X suffixes = X_DEFAULT;
- X
- X argc = getRCSINIT(argc, argv, &newargv);
- X argv = newargv;
- X while (a = *++argv, 0<--argc && *a++=='-') {
- X switch (*a++) {
- X case 'p':
- X tostdout=true;
- X goto revno;
- X
- X case 'q':
- X quietflag = true;
- X revno:
- X if (!*a)
- X break;
- X /* falls into -r */
- X case 'r':
- X if (!rev[0])
- X rev[0] = a;
- X else if (!rev[1])
- X rev[1] = a;
- X else
- X faterror("too many revision numbers");
- X break;
- X case 'x':
- X suffixes = a;
- X break;
- X case 'V':
- X versionarg = *argv;
- X setRCSversion(versionarg);
- X break;
- X
- X case 'k':
- X expandarg = *argv;
- X if (0 <= str2expmode(expandarg+2))
- X break;
- X /* fall into */
- X default:
- X faterror("unknown option: %s%s", *argv, cmdusage);
- X };
- X } /* end of option processing */
- X
- X if (argc<1) faterror("no input file%s", cmdusage);
- X if (!rev[0]) faterror("no base revision number given");
- X
- X /* now handle all filenames */
- X
- X if (0 < pairfilenames(argc, argv, rcsreadopen, true, false)) {
- X
- X if (argc>2 || (argc==2&&argv[1]!=nil))
- X warn("too many arguments");
- X diagnose("RCS file: %s\n", RCSfilename);
- X if (!(workptr = Iopen(workfilename,
- X FOPEN_R_WORK,
- X (struct stat*)0
- X )))
- X efaterror(workfilename);
- X
- X gettree(); /* reads in the delta tree */
- X
- X if (Head==nil) faterror("no revisions present");
- X
- X if (!*rev[0])
- X rev[0] = Dbranch ? Dbranch : Head->num;
- X if (!fexpandsym(rev[0], &numericrev, workptr))
- X goto end;
- X if (!(target=genrevs(numericrev.string, (char *)nil, (char *)nil, (char *)nil,&gendeltas))) goto end;
- X rev[0] = target->num;
- X if (!rev[1] || !*rev[1])
- X rev[1] = Dbranch ? Dbranch : Head->num;
- X if (!fexpandsym(rev[1], &numericrev, workptr))
- X goto end;
- X if (!(target=genrevs(numericrev.string, (char *)nil, (char *)nil, (char *)nil,&gendeltas))) goto end;
- X rev[1] = target->num;
- X
- X if (strcmp(rev[0],rev[1]) == 0) {
- X if (tostdout) {
- X FILE *o;
- X# if text_equals_binary_stdio || text_work_stdio
- X o = stdout;
- X# else
- X if (!(o=fdopen(STDOUT_FILENO,FOPEN_W_WORK)))
- X efaterror("stdout");
- X# endif
- X fastcopy(workptr,o);
- X Ofclose(o);
- X }
- X goto end;
- X }
- X Izclose(&workptr);
- X
- X for (i=0; i<2; i++) {
- X diagnose("retrieving revision %s\n", rev[i]);
- X bufscpy(&commarg, "-p");
- X bufscat(&commarg, rev[i]);
- X if (run(
- X (char*)0,
- X /* Do not collide with merger.c maketemp(). */
- X arg[i+1] = maketemp(i+3),
- X co, quietarg, commarg.string, expandarg,
- X versionarg, RCSfilename, (char*)0
- X ))
- X faterror("co failed");
- X }
- X diagnose("Merging differences between %s and %s into %s%s\n",
- X rev[0], rev[1], workfilename,
- X tostdout?"; result to stdout":"");
- X
- X arg[0] = rev[0] = workfilename;
- X status = merge(tostdout, rev, arg);
- X }
- X
- end:
- X Izclose(&workptr);
- X tempunlink();
- X exitmain(nerror ? DIFF_TROUBLE : status);
- X}
- X
- X#if lint
- X# define exiterr rmergeExit
- X#endif
- X exiting void
- exiterr()
- X{
- X tempunlink();
- X _exit(DIFF_TROUBLE);
- X}
- END_OF_FILE
- if test 6990 -ne `wc -c <'src/rcsmerge.c'`; then
- echo shar: \"'src/rcsmerge.c'\" unpacked with wrong size!
- fi
- # end of 'src/rcsmerge.c'
- fi
- if test -f 'src/rcstest' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/rcstest'\"
- else
- echo shar: Extracting \"'src/rcstest'\" \(9809 characters\)
- sed "s/^X//" >'src/rcstest' <<'END_OF_FILE'
- X#!/bin/sh
- X
- X# Test RCS's functions.
- X# The RCS commands are searched for in the PATH as usual;
- X# to test the working directory's commands, prepend . to your PATH.
- X
- X# Test RCS by creating files RCS/a.* and RCS/a.c.
- X# If all goes well, output nothing, and remove the temporary files.
- X# Otherwise, send a message to standard output.
- X# Exit status is 0 if OK, 1 if an RCS bug is found, and 2 if scaffolding fails.
- X# With the -v option, output more debugging info.
- X
- X# If diff outputs `No differences encountered' when comparing identical files,
- X# then rcstest may also output these noise lines; ignore them.
- X
- X# The current directory and ./RCS must be readable, writable, and searchable.
- X
- X# $Id: rcstest,v 5.8 1991/11/20 17:58:10 eggert Exp $
- X
- X
- X# Copyright 1990, 1991 by Paul Eggert
- X# Distributed under license by the Free Software Foundation, Inc.
- X#
- X# This file is part of RCS.
- X#
- X# RCS is free software; you can redistribute it and/or modify
- X# it under the terms of the GNU General Public License as published by
- X# the Free Software Foundation; either version 2, or (at your option)
- X# any later version.
- X#
- X# RCS is distributed in the hope that it will be useful,
- X# but WITHOUT ANY WARRANTY; without even the implied warranty of
- X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X# GNU General Public License for more details.
- X#
- X# You should have received a copy of the GNU General Public License
- X# along with RCS; see the file COPYING. If not, write to
- X# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- X#
- X# Report problems and direct all questions to:
- X#
- X# rcs-bugs@cs.purdue.edu
- X
- RCSINIT=-x
- export RCSINIT
- X
- SLASH=/
- RCSfile=RCS${SLASH}a.c
- RCS_alt=RCS${SLASH}a.d
- lockfile=RCS${SLASH}a._
- X
- case $1 in
- X-v) q=; set -x;;
- X'') q=-q;;
- X*) echo >&2 "$0: usage: $0 [-v]"; exit 2
- esac
- X
- test -d RCS || {
- X echo >&2 "$0: RCS: not a directory; please \`mkdir RCS' first."
- X exit 1
- X}
- X
- rm -f a.* $RCSfile $RCS_alt $lockfile &&
- echo 1.1 >a.11 &&
- echo 1.1.1.1 >a.3x1 &&
- echo 1.2 >a.12 || { echo "#initialization failed"; exit 2; }
- X
- case `diff -c a.11 a.3x1` in
- X*'! 1.1.1.1')
- X diff='diff -c';;
- X*)
- X echo "#warning: diff -c does not work, so diagnostics may be cryptic"
- X diff=diff
- esac
- X
- rcs -i -L -ta.11 $q a.c &&
- X<$RCSfile || {
- X echo "#rcs -i -L failed; perhaps RCS is not properly installed."
- X exit 1
- X}
- X
- rlog a.c >/dev/null || { echo "#rlog failed on empty RCS file"; exit 1; }
- rm -f $RCSfile || exit 2
- X
- cp a.11 a.c &&
- ci -ta.11 -mm $q a.c &&
- X<$RCSfile &&
- rcs -L $q a.c || { echo "#ci+rcs -L failed"; exit 1; }
- test ! -f a.c || { echo "#ci did not remove working file"; exit 1; }
- for l in '' '-l'
- do
- X co $l $q a.c &&
- X test -f a.c || { echo '#co' $l did not create working file; exit 1; }
- X $diff a.11 a.c || { echo '#ci' followed by co $l is not a no-op; exit 1; }
- done
- X
- cp a.12 a.c &&
- ci -mm $q a.c &&
- co $q a.c &&
- X$diff a.12 a.c || { echo "#ci+co failed"; exit 1; }
- X
- co -r1.1 $q a.c &&
- X$diff a.11 a.c || { echo "#can't retrieve first revision"; exit 1; }
- X
- rm -f a.c &&
- cp a.3x1 a.c &&
- ci -r1.1.1 -mm $q a.c &&
- co -r1.1.1.1 $q a.c &&
- X$diff a.3x1 a.c || { echo "#branches failed"; exit 1; }
- X
- co -l $q a.c &&
- ci -f -mm $q a.c &&
- co -r1.3 $q a.c &&
- X$diff a.12 a.c || { echo "#(co -l; ci -f) failed"; exit 1; }
- X
- co -l $q a.c &&
- echo 1.4 >a.c &&
- ci -l -mm $q a.c &&
- echo error >a.c &&
- ci -mm $q a.c || { echo "#ci -l failed"; exit 1; }
- X
- co -l $q a.c &&
- echo 1.5 >a.c &&
- ci -u -mm $q a.c &&
- X<a.c || { echo "#ci -u didn't create a working file"; exit 1; }
- rm -f a.c &&
- echo error >a.c || exit 2
- ci -mm $q a.c 2>/dev/null && { echo "#ci -u didn't unlock the file"; exit 1; }
- X
- rm -f a.c &&
- rcs -l $q a.c &&
- co -u $q a.c || { echo "#rcs -l + co -u failed"; exit 1; }
- rm -f a.c &&
- echo error >a.c || exit 2
- ci -mm $q a.c 2>/dev/null && { echo "#co -u didn't unlock the file"; exit 1; }
- X
- rm -f a.c &&
- cp a.11 a.c &&
- co -f $q a.c || { echo "#co -f failed"; exit 1; }
- X$diff a.11 a.c >/dev/null && { echo "#co -f had no effect"; exit 1; }
- X
- co -p1.1 $q a.c >a.t &&
- X$diff a.11 a.t || { echo "#co -p failed"; exit 1; }
- X
- for n in n N
- do
- X rm -f a.c &&
- X co -l $q a.c &&
- X echo $n >a.$n &&
- X cp a.$n a.c &&
- X ci -${n}n -mm $q a.c &&
- X co -rn $q a.c &&
- X $diff a.$n a.c || { echo "#ci -$n failed"; exit 1; }
- done
- X
- case $LOGNAME in
- X?*) me=$LOGNAME;;
- X*)
- X case $USER in
- X ?*) me=$USER;;
- X *)
- X me=`who am i` || exit 2
- X me=`echo "$me" | sed -e 's/ .*//' -e 's/.*!//'`
- X case $me in
- X '') echo >&2 "$0: cannot deduce user name"; exit 2
- X esac
- X esac
- esac
- date=`date -u 2>/dev/null` ||
- date=`TZ=GMT0 date 2>/dev/null` ||
- date=`TZ= date` || exit 2
- set $date
- case $2 in
- Jan) m=01;; Feb) m=02;; Mar) m=03;; Apr) m=04;; May) m=05;; Jun) m=06;;
- Jul) m=07;; Aug) m=08;; Sep) m=09;; Oct) m=10;; Nov) m=11;; Dec) m=12;;
- X*) echo >&2 "$0: $2: unknown month name"; exit 2
- esac
- case $3 in
- X?) d=0$3;;
- X*) d=$3
- esac
- case $6 in
- X[0-9][0-9][0-9][0-9]*) D=$6/$m/$d;;
- X*)
- X case $5 in
- X [0-9][0-9][0-9][0-9]*) D=$5/$m/$d;;
- X *) echo >&2 "$0: bad date format: $date"; exit 2
- X esac
- esac
- T=$4
- case $PWD in
- X'') PWD=`pwd`
- esac &&
- co -l $q a.c &&
- sed 's/@/$/g' >a.kv <<EOF
- X@Author: w @
- X@Date: $D $T @
- X@Header: $PWD$SLASH$RCSfile 2.1 $D $T w s @
- X@Id: a.c 2.1 $D $T w s @
- X@Locker: @
- X@Log: a.c @
- X * Revision 2.1 $D $T w
- X * m
- X *
- X@RCSfile: a.c @
- X@Revision: 2.1 @
- X@Source: $PWD$SLASH$RCSfile @
- X@State: s @
- XEOF
- test $? = 0 &&
- sed 's/:.*\$/$/' a.kv >a.k &&
- sed -e 's/w s [$]/w s '"$me"' $/' -e 's/[$]Locker: /&'"$me/" a.kv >a.kvl &&
- sed -e '/^\$/!d' -e 's/\$$/: old $/' a.k >a.o &&
- sed -e 's/\$[^ ]*: //' -e 's/ \$//' a.kv >a.v &&
- cp a.o a.c &&
- ci -d"$date" -ss -ww -u2.1 -mm $q a.c &&
- X$diff a.kv a.c || { echo "#keyword expansion failed"; exit 1; }
- co -p -ko $q a.c >a.oo &&
- X$diff a.o a.oo || { echo "#co -p -ko failed"; exit 1; }
- cp a.kv a.o || exit 2
- rcs -o2.1 $q a.c &&
- rcs -l $q a.c &&
- ci -k -u $q a.c &&
- X$diff a.kv a.c || { echo "#ci -k failed"; exit 1; }
- sed '/^[^$]/d' a.kv >a.i &&
- ident a.c >a.i1 &&
- sed -e 1d -e 's/^[ ]*//' a.i1 >a.i2 &&
- X$diff a.i a.i2 || { echo "#ident failed"; exit 1; }
- X
- rcs -i $q a.c 2>/dev/null && { echo "#rcs -i permitted existing file"; exit 1; }
- X
- co -l $q a.c &&
- echo 2.2 >a.c &&
- ci -mm $q a.c &&
- echo 1.1.1.2 >a.c &&
- rcs -l1.1.1 $q a.c &&
- ci -r1.1.1.2 -mm $q a.c &&
- rcs -b1.1.1 $q a.c &&
- test " `co -p $q a.c`" = ' 1.1.1.2' || { echo "#rcs -b1.1.1 failed"; exit 1; }
- rcs -b $q a.c &&
- test " `co -p $q a.c`" = ' 2.2' || { echo "#rcs -b failed"; exit 1; }
- X
- echo 2.3 >a.c || exit 2
- rcs -U $q a.c || { echo "#rcs -U failed"; exit 1; }
- ci -mm $q a.c || { echo "#rcs -U didn't unset strict locking"; exit 1; }
- rcs -L $q a.c || { echo "#rcs -L failed"; exit 1; }
- echo error >a.c || exit 2
- ci -mm $q a.c 2>/dev/null && { echo "#ci retest failed"; exit 1; }
- X
- rm -f a.c &&
- log0=`rlog -h a.c` &&
- co -l $q a.c &&
- ci -mm $q a.c &&
- log1=`rlog -h a.c` &&
- test " $log0" = " $log1" || { echo "#unchanged ci didn't revert"; exit 1; }
- X
- rm -f a.c &&
- rcs -nN:1.1 $q a.c &&
- co -rN $q a.c &&
- X$diff a.11 a.c || { echo "#rcs -n failed"; exit 1; }
- X
- rcs -NN:2.1 $q a.c &&
- co -rN $q a.c &&
- X$diff a.kv a.c || { echo "#rcs -N failed"; exit 1; }
- X
- co -l $q a.c &&
- rcs -c':::' $q a.c &&
- echo '$''Log$' >a.c &&
- ci -u -mm $q a.c &&
- test " `sed '$!d' a.c`" = ' :::' || { echo "#rcs -c failed"; exit 1; }
- X
- rcs -o2.2: $q a.c &&
- co $q a.c &&
- X$diff a.kv a.c || { echo "#rcs -o failed"; exit 1; }
- X
- rcsdiff -r1.1 -r2.1 $q a.c >a.0
- case $? in
- X1) ;;
- X*) echo "#rcsdiff bad status"; exit 1
- esac
- diff a.11 a.kv >a.1
- X$diff a.0 a.1 || { echo "#rcsdiff failed"; exit 1; }
- X
- rcs -l2.1 $q a.c || { echo "#rcs -l2.1 failed"; exit 1; }
- for i in k kv kvl o v
- do
- X rm -f a.c &&
- X cp a.$i a.c &&
- X rcsdiff -k$i $q a.c || { echo "#rcsdiff -k$i failed"; exit 1; }
- done
- co -p1.1 -ko $q a.c >a.t &&
- X$diff a.11 a.t || { echo "#co -p1.1 -ko failed"; exit 1; }
- rcs -u2.1 $q a.c || { echo "#rcs -u2.1 failed"; exit 1; }
- X
- rm -f a.c &&
- co -l $q a.c &&
- cat >a.c <<'EOF'
- X2.2
- a
- b
- c
- d
- XEOF
- test $? = 0 &&
- ci -l -mm $q a.c &&
- co -p2.2 $q a.c | sed -e s/2.2/2.3/ -e s/b/b1/ >a.c &&
- ci -l -mm $q a.c &&
- co -p2.2 $q a.c | sed -e s/2.2/new/ -e s/d/d1/ >a.c || exit 2
- cat >a.0 <<'EOF'
- X2.3
- a
- b1
- c
- d1
- XEOF
- cat >a.1 <<'EOF'
- X<<<<<<< a.c
- new
- X=======
- X2.3
- X>>>>>>> 2.3
- a
- b1
- c
- d1
- XEOF
- rcsmerge -r2.2 -r2.3 $q a.c
- case $? in
- X0)
- X if $diff a.0 a.c >/dev/null
- X then echo "#warning: diff3 -E does not work, " \
- X "so merge and rcsmerge ignore overlaps and suppress overlap lines."
- X else
- X $diff a.1 a.c || { echo "#rcsmerge failed (status 0)"; exit 1; }
- X echo "#warning: The diff3 lib program exit status ignores overlaps," \
- X "so rcsmerge does not warn about overlap lines that it generates."
- X fi
- X ;;
- X1)
- X $diff a.1 a.c || { echo "#rcsmerge failed (status 1)"; exit 1; }
- X ;;
- X*)
- X echo "#rcsmerge bad status"; exit 1
- esac
- X
- nl='
- X'
- X{
- X co -p $q a.c | tr "$nl" '\200' >a.24 &&
- X cp a.24 a.c &&
- X ciOut=`(ci -l -mm $q a.c 2>&1)` &&
- X case $ciOut in
- X ?*) echo >&2 "$ciOut"
- X esac &&
- X co -p $q a.c | tr '\200' "$nl" >a.c &&
- X rcsdiff -r2.3 $q a.c >/dev/null &&
- X
- X echo 2.5 >a.c &&
- X ci -l -mm $q a.c &&
- X cp a.24 a.c &&
- X rcsdiff -r2.4 $q a.c >/dev/null
- X} || echo "#warning: Traditional diff is used, so RCS is limited to text files."
- X
- rcs -u -o2.4: $q a.c || { echo "#rcs -u -o failed"; exit 1; }
- X
- rcs -i -Aa.c -t- $q a.d || { echo "#rcs -i -A failed"; exit 1; }
- X
- rlog -r2.1 a.c >a.t &&
- grep '^checked in with -k' a.t >/dev/null &&
- sed '/^checked in with -k/d' a.t >a.u &&
- X$diff - a.u <<EOF
- X
- RCS file: $RCSfile
- Working file: a.c
- head: 2.3
- branch:
- locks: strict
- access list:
- symbolic names:
- X N: 2.1
- X n: 1.8
- comment leader: ":::"
- keyword substitution: kv
- total revisions: 13; selected revisions: 1
- description:
- X1.1
- X----------------------------
- revision 2.1
- date: $D $T; author: w; state: s; lines: +13 -1
- X=============================================================================
- XEOF
- test $? = 0 || { echo "#rlog failed"; exit 1; }
- X
- X
- test ! -f $lockfile || { echo "#lock file not removed"; exit 1; }
- X
- exec rm -f a.* $RCSfile $RCS_alt
- END_OF_FILE
- if test 9809 -ne `wc -c <'src/rcstest'`; then
- echo shar: \"'src/rcstest'\" unpacked with wrong size!
- fi
- chmod +x 'src/rcstest'
- # end of 'src/rcstest'
- fi
- echo shar: End of archive 2 \(of 11\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 11 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-