[comp.sources.unix] v24i009: RCS source control system, Part09/12

rsalz@bbn.com (Rich Salz) (02/23/91)

Submitted-by: Adam Hammer <hammer@cs.purdue.edu>
Posting-number: Volume 24, Issue 9
Archive-name: rcs/part09

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  man/ci.1 man/co.1 src/conf.sh src/rcsgen.c
# Wrapped by rsalz@litchi.bbn.com on Thu Feb 21 14:37:07 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive 9 (of 12)."'
if test -f 'man/ci.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man/ci.1'\"
else
  echo shar: Extracting \"'man/ci.1'\" \(10006 characters\)
  sed "s/^X//" >'man/ci.1' <<'END_OF_FILE'
X.de Id
X.ds Rv \\$3
X.ds Dt \\$4
X..
X.Id $Id: ci.1,v 5.4 1990/12/04 05:18:31 eggert Exp $
X.ds r \s-1RCS\s0
X.if n .ds - \%--
X.if t .ds - \(em
X.TH CI 1 \*(Dt GNU
X.SH NAME
Xci \- check in RCS revisions
X.SH SYNOPSIS
X.B ci
X.RI [ options ] " file " .\|.\|.
X.SH DESCRIPTION
X.B ci
Xstores new revisions into \*r files.
XEach file name ending in
X.B ,v
Xis taken to be an \*r file.
XAll others
Xare assumed to be working files containing new revisions.
X.B ci
Xdeposits the contents of each working file
Xinto the corresponding \*r file.
XIf only a working file is given,
X.B ci
Xtries to find the corresponding \*r file in an \*r subdirectory
Xand then in the working file's directory.
XFor more details, see
X.SM "FILE NAMING"
Xbelow.
X.PP
XFor
X.B ci
Xto work, the caller's login must be on the access list,
Xexcept if the access list is empty or the caller is the superuser or the
Xowner of the file.
XTo append a new revision to an existing branch, the tip revision on
Xthat branch must be locked by the caller.  Otherwise, only a
Xnew branch can be created.  This restriction is not enforced
Xfor the owner of the file if non-strict locking is used
X(see
X.BR rcs (1)).
XA lock held by someone else may be broken with the
X.B rcs
Xcommand.
X.PP
XNormally,
X.B ci
Xchecks whether the revision to be deposited is different
Xfrom the preceding one.  If it is not different,
X.B ci
Xaborts the deposit, asking beforehand if possible.
XA deposit can be forced with the
X.B \-f
Xoption.
X.PP
XFor each revision deposited,
X.B ci
Xprompts for a log message.
XThe log message should summarize the change and must be terminated by
Xend-of-file or by a line containing
X.BR \&. "\ by"
Xitself.
XIf several files are checked in
X.B ci
Xasks whether to reuse the
Xprevious log message.
XIf the standard input is not a terminal,
X.B ci
Xsuppresses the prompt
Xand uses the same log message for all files.
XSee also
X.BR \-m .
X.PP
XThe number of the deposited revision can be given by any of the options
X.BR \-f ,
X.BR \-I ,
X.BR \-k ,
X.BR \-l ,
X.BR \-q ,
X.BR \-r ,
Xor
X.BR \-u .
X.PP
XIf the \*r file does not exist,
X.B ci
Xcreates it and
Xdeposits the contents of the working file as the initial revision
X(default number:
X.BR 1.1 ).
XThe access list is initialized to empty.
XInstead of the log message,
X.B ci
Xrequests descriptive text (see
X.B \-t
Xbelow).
X.SH OPTIONS
X.TP
X.BR \-r [\f2rev\fP]
Xassigns the revision number
X.I rev
Xto the checked-in revision, releases the corresponding lock, and
Xdeletes the working file.  This is the default.
X.I rev
Xmay be symbolic, numeric, or mixed.
X.RS
X.PP
XIf
X.I rev
Xis a revision number, it must be higher than the latest
Xone on the branch to which
X.I rev
Xbelongs, or must start a new branch.
X.PP
XIf
X.I rev
Xis a branch rather than a revision number,
Xthe new revision is appended to that branch.  The level number is obtained
Xby incrementing the tip revision number of that branch.
XIf
X.I rev
Xindicates a non-existing branch,
Xthat branch is created with the initial revision numbered
X.IB rev .1\f1.\fP
X.br
X.ne 8
X.PP
XIf
X.I rev
Xis omitted,
X.B ci
Xtries to derive the new revision number from
Xthe caller's last lock.  If the caller has locked the tip revision of a branch,
Xthe new revision is appended to that branch.
XThe new revision number is obtained
Xby incrementing the tip revision number.
XIf the caller locked a non-tip revision, a new branch is started at
Xthat revision by incrementing the highest branch number at that revision.
XThe default initial branch and level numbers are
X.BR 1 .
X.PP
XIf
X.I rev
Xis omitted and the caller has no lock, but owns
Xthe file and locking
Xis not set to
X.IR strict ,
Xthen the revision is appended to the
Xdefault branch (normally the trunk; see the
X.B \-b
Xoption of
X.BR rcs (1)).
X.PP
XException: On the trunk, revisions can be appended to the end, but
Xnot inserted.
X.RE
X.TP
X.BR \-f [\f2rev\fP]
Xforces a deposit; the new revision is deposited even it is not different
Xfrom the preceding one.
X.TP
X.BR \-k [\f2rev\fP]
Xsearches the working file for keyword values to determine its revision number,
Xcreation date, state, and author (see
X.BR co (1)),
Xand assigns these
Xvalues to the deposited revision, rather than computing them locally.
XIt also generates a default login message noting the login of the caller
Xand the actual checkin date.
XThis option is useful for software distribution.  A revision that is sent to
Xseveral sites should be checked in with the
X.B \-k
Xoption at these sites to
Xpreserve the original number, date, author, and state.
XThe extracted keyword values and the default log message may be overridden
Xwith the options
X.BR \-d ,
X.BR \-m ,
X.BR \-s ,
X.BR \-w ,
Xand any option that carries a revision number.
X.TP
X.BR \-l [\f2rev\fP]
Xworks like
X.BR \-r ,
Xexcept it performs an additional
X.B "co\ \-l"
Xfor the
Xdeposited revision.  Thus, the deposited revision is immediately
Xchecked out again and locked.
XThis is useful for saving a revision although one wants to continue
Xediting it after the checkin.
X.TP
X.BR \-u [\f2rev\fP]
Xworks like
X.BR \-l ,
Xexcept that the deposited revision is not locked.
XThis lets one read the working file
Ximmediately after checkin.
X.TP
X.BR \-q [\f2rev\fP]
Xquiet mode; diagnostic output is not printed.
XA revision that is not different from the preceding one is not deposited,
Xunless
X.B \-f
Xis given.
X.TP
X.BR \-I [\f2rev\fP]
Xinteractive mode;
Xthe user is prompted and questioned
Xeven if the standard input is not a terminal.
X.TP
X.BR \-d "[\f2date\fP]"
Xuses
X.I date
Xfor the checkin date and time.
XThe
X.I date
Xis specified in free format as explained in
X.BR co (1).
XThis is useful for lying about the checkin date, and for
X.B \-k
Xif no date is available.
XIf
X.I date
Xis empty, the working file's time of last modification is used.
X.TP
X.BI \-m "msg"
Xuses the string
X.I msg
Xas the log message for all revisions checked in.
X.TP
X.BI \-n "name"
Xassigns the symbolic name
X.I name
Xto the number of the checked-in revision.
X.B ci
Xprints an error message if
X.I name
Xis already assigned to another
Xnumber.
X.TP
X.BI \-N "name"
Xsame as
X.BR \-n ,
Xexcept that it overrides a previous assignment of
X.IR name .
X.TP
X.BI \-s "state"
Xsets the state of the checked-in revision to the identifier
X.IR state .
XThe default state is
X.BR Exp .
X.TP
X.BI \-t file
Xwrites descriptive text from the contents of the named
X.I file
Xinto the \*r file,
Xdeleting the existing text.
XThe
X.I file
Xname may not begin with
X.BR \- .
X.TP
X.BI \-t\- string
XWrite descriptive text from the
X.I string
Xinto the \*r file, deleting the existing text.
X.RS
X.PP
XThe
X.B \-t
Xoption, in both its forms, has effect only during an initial checkin;
Xit is silently ignored otherwise.
X.PP
XDuring the initial checkin, if
X.B \-t
Xis not given,
X.B ci
Xobtains the text from standard input,
Xterminated by end-of-file or by a line containing
X.BR \&. "\ by"
Xitself.
XThe user is prompted for the text if interaction is possible; see
X.BR \-I .
X.PP
XFor backward compatibility with older versions of \*r, a bare
X.B \-t
Xoption is ignored.
X.RE
X.TP
X.BI \-w "login"
Xuses
X.I login
Xfor the author field of the deposited revision.
XUseful for lying about the author, and for
X.B \-k
Xif no author is available.
X.TP
X.BI \-V n
XEmulate \*r version
X.IR n .
XSee
X.BR co (1)
Xfor details.
X.SH "FILE NAMING"
XPairs of \*r files and working files may be specified in three ways
X(see also the
Xexample section of
X.BR co (1)).
X.PP
X1) Both the \*r file and the working file are given.  The \*r file name is of
Xthe form
X.IB path1 / workfile ,v
Xand the working file name is of the form
X.IB path2 / workfile
Xwhere
X.IB path1 /
Xand
X.IB path2 /
Xare (possibly different or empty) paths and
X.I workfile
Xis a file name.
X.PP
X2) Only the \*r file is given.  Then the working file is created in the current
Xdirectory and its name is derived from the name of the \*r file
Xby removing
X.IB path1 /
Xand the suffix
X.BR ,v .
X.PP
X3) Only the working file is given.
XThen
X.B ci
Xlooks for an \*r file of the form
X.IB path2 /RCS/ workfile ,v
Xor
X.IB path2 / workfile ,v
X(in this order).
X.PP
XIf the \*r file is specified without a path in 1) and 2), then
X.B ci
Xlooks for the \*r file first in the directory
X.B ./RCS
Xand then in the current
Xdirectory.
X.SH "FILE MODES"
XAn \*r file created by
X.B ci
Xinherits the read and execute permissions
Xfrom the working file.  If the \*r file exists already,
X.B ci
Xpreserves its read and execute permissions.
X.B ci
Xalways turns off all write permissions of \*r files.
X.SH FILES
XSeveral temporary files may be created.
XA semaphore file is created in the directory containing the \*r file.
XThe effective user+group must be able to read the \*r file
Xand to search and write the directory containing the \*r file.
XNormally, the real user+group must be able to read the working file
Xand to search and write the directory containing the working file;
Xhowever, some older hosts that do not conform to Posix 1003.1-1990
Xcannot easily switch between real and effective ids,
Xso on these hosts the effective user+group is used for all accesses.
XThe effective user+group is the same as the real user+group
Xunless your copy of \*r has setuid or setgid privileges.
XThese privileges yield extra security if \*r files are protected so that
Xonly the effective user+group can write \*r directories.
XFurther protection can be achieved by granting access
Xonly to the effective user+group.
X.PP
X.B ci
Xnever changes an \*r or working file;
Xinstead, it unlinks the file and creates a new one.
XThis strategy breaks hard links to such files,
Xbut does not affect symbolic links.
X.SH DIAGNOSTICS
XFor each revision,
X.B ci
Xprints the \*r file, the working file, and the number
Xof both the deposited and the preceding revision.
XThe exit status is zero if and only if all operations were successful.
X.SH IDENTIFICATION
XAuthor: Walter F. Tichy.
X.br
XRevision Number: \*(Rv; Release Date: \*(Dt.
X.br
XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
X.br
XCopyright \(co 1990 by Paul Eggert.
X.SH "SEE ALSO"
Xco(1), ident(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1),
Xrcsfile(5)
X.br
XWalter F. Tichy,
X\*r\*-A System for Version Control,
X.I "Software\*-Practice & Experience"
X.BR 15 ,
X7 (July 1985), 637-654.
END_OF_FILE
  if test 10006 -ne `wc -c <'man/ci.1'`; then
    echo shar: \"'man/ci.1'\" unpacked with wrong size!
  fi
  # end of 'man/ci.1'
fi
if test -f 'man/co.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'man/co.1'\"
else
  echo shar: Extracting \"'man/co.1'\" \(14638 characters\)
  sed "s/^X//" >'man/co.1' <<'END_OF_FILE'
X.de Id
X.ds Rv \\$3
X.ds Dt \\$4
X..
X.Id $Id: co.1,v 5.4 1990/12/04 05:18:32 eggert Exp $
X.ds g \s-1GMT\s0
X.ds r \s-1RCS\s0
X.if n .ds - \%--
X.if t .ds - \(em
X.TH CO 1 \*(Dt GNU
X.SH NAME
Xco \- check out RCS revisions
X.SH SYNOPSIS
X.B co
X.RI [ options ] " file " .\|.\|.
X.SH DESCRIPTION
X.B co
Xretrieves a revision from each \*r file and stores it into
Xthe corresponding working file.
XEach file name ending in
X.B ,v
Xis taken to be an \*r file;
Xall other files are assumed to be working files.
XIf only a working file is given,
X.B co
Xtries to find the corresponding \*r file in the directory
X.B ./RCS
Xand then in the current directory.
XFor more details, see
X.SM "FILE NAMING"
Xbelow.
X.PP
XRevisions of an \*r file may be checked out locked or unlocked.  Locking a
Xrevision prevents overlapping updates.  A revision checked out for reading or
Xprocessing (e.g., compiling) need not be locked.  A revision checked out
Xfor editing and later checkin must normally be locked.  Checkout with locking
Xfails if the revision to be checked out is currently locked by another user.
X(A lock may be broken with
X.BR rcs "(1).)\ \&"
XCheckout with locking also requires the caller to be on the access list of
Xthe \*r file, unless he is the owner of the
Xfile or the superuser, or the access list is empty.
XCheckout without locking is not subject to accesslist restrictions, and is
Xnot affected by the presence of locks.
X.PP
XA revision is selected by options for revision or branch number,
Xcheckin date/time, author, or state.
XWhen the selection options
Xare applied in combination,
X.B co
Xretrieves the latest revision
Xthat satisfies all of them.
XIf none of the selection options
Xis specified,
X.B co
Xretrieves the latest revision
Xon the default branch (normally the trunk, see the
X.B \-b
Xoption of
X.BR rcs (1)).
XA revision or branch number may be attached
Xto any of the options
X.BR \-f ,
X.BR \-I ,
X.BR \-l ,
X.BR \-p ,
X.BR \-q ,
X.BR \-r ,
Xor
X.BR \-u .
XThe options
X.B \-d
X(date),
X.B \-s
X(state), and
X.B \-w
X(author)
Xretrieve from a single branch, the
X.I selected
Xbranch,
Xwhich is either specified by one of
X.BR \-f,
X\&.\|.\|.,
X.BR \-u ,
Xor the default branch.
X.PP
XA
X.B co
Xcommand applied to an \*r
Xfile with no revisions creates a zero-length working file.
X.B co
Xalways performs keyword substitution (see below).
X.SH OPTIONS
X.TP
X.BR \-r [\f2rev\fP]
Xretrieves the latest revision whose number is less than or equal to
X.I rev.
XIf
X.I rev
Xindicates a branch rather than a revision,
Xthe latest revision on that branch is retrieved.
XIf
X.I rev
Xis omitted, the latest revision on the default branch
X(see the
X.B \-b
Xoption of
X.BR rcs (1))
Xis retrieved.
XA revision is composed of one or more numeric or symbolic fields
Xseparated by periods.  The numeric equivalent of a symbolic field
Xis specified with the
X.B \-n
Xoption of the commands
X.BR ci (1)
Xand
X.BR rcs (1).
X.TP
X.BR \-l [\f2rev\fP]
Xsame as
X.BR \-r ,
Xexcept that it also locks the retrieved revision for
Xthe caller.
X.TP
X.BR \-u [\f2rev\fP]
Xsame as
X.BR \-r ,
Xexcept that it unlocks the retrieved revision if it was
Xlocked by the caller.  If
X.I rev
Xis omitted,
X.B \-u
Xretrieves the latest revision locked by the caller; if no such lock exists,
Xit retrieves the latest revision on the default branch.
X.TP
X.BR \-f [\f2rev\fP]
Xforces the overwriting of the working file;
Xuseful in connection with
X.BR \-q .
XSee also
X.SM "FILE MODES"
Xbelow.
X.TP
X.B \-kkv
XGenerate keyword strings using the default form, e.g.\&
X.B "$\&Revision: \*(Rv $"
Xfor the
X.B Revision
Xkeyword.
XA locker's name is inserted in the value of the
X.BR Header ,
X.BR Id ,
Xand
X.B Locker
Xkeyword strings
Xonly as a file is being locked,
Xi.e. by
X.B "ci\ \-l"
Xand
X.BR "co\ \-l".
XThis is the default.
X.TP
X.B \-kkvl
XLike
X.BR \-kkv ,
Xexcept that a locker's name is always inserted
Xif the given revision is currently locked.
X.TP
X.BR \-kk
XGenerate only keyword names in keyword strings; omit their values.
XSee
X.SM "KEYWORD SUBSTITUTION"
Xbelow.
XFor example, for the
X.B Revision
Xkeyword, generate the string
X.B $\&Revision$
Xinstead of
X.BR "$\&Revision: \*(Rv $".
XThis option is useful to ignore differences due to keyword substitution
Xwhen comparing different revisions of a file.
X.TP
X.BR \-ko
XGenerate the old keyword string,
Xpresent in the working file just before it was checked in.
XFor example, for the
X.B Revision
Xkeyword, generate the string
X.B "$\&Revision: 1.1 $"
Xinstead of
X.B "$\&Revision: \*(Rv $"
Xif that is how the string appeared when the file was checked in.
XThis can be useful for binary file formats
Xthat cannot tolerate any changes to substrings
Xthat happen to take the form of keyword strings.
X.TP
X.BR \-kv
XGenerate only keyword values for keyword strings.
XFor example, for the
X.B Revision
Xkeyword, generate the string
X.B \*(Rv
Xinstead of
X.BR "$\&Revision: \*(Rv $".
XThis can help generate files in programming languages where it is hard to
Xstrip keyword delimiters like
X.B "$\&Revision:\ $"
Xfrom a string.
XHowever, further keyword substitution cannot be performed once the
Xkeyword names are removed, so this option should be used with care.
XBecause of this danger of losing keywords,
Xthis option cannot be combined with
X.BR \-l ,
Xand the owner write permission of the working file is turned off;
Xto edit the file later, check it out again without
X.BR \-kv .
X.TP
X.BR \-p [\f2rev\fP]
Xprints the retrieved revision on the standard output rather than storing it
Xin the working file.
XThis option is useful when
X.B co
Xis part of a pipe.
X.TP
X.BR \-q [\f2rev\fP]
Xquiet mode; diagnostics are not printed.
X.TP
X.BR \-I [\f2rev\fP]
Xinteractive mode;
Xthe user is prompted and questioned
Xeven if the standard input is not a terminal.
X.TP
X.BI \-d date
Xretrieves the latest revision on the selected branch whose checkin date/time is
Xless than or equal to
X.I date.
XThe date and time may be given in free format.
XThe time zone
X.B LT
Xstands for local time;
Xother common time zone names are understood.
XFor example, the following
X.IR date s
Xare equivalent
Xif local time is January 11, 1990, 8pm Pacific Standard Time
X(eight hours west of \*g):
X.RS
X.LP
X.RS
X.nf
X.ta \w'\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP  'u
X.ne 9
X\f38:00 pm lt\fP
X\f34:00 AM, Jan. 12, 1990\fP	note: default is \*g
X\f31990/01/12 04:00:00\fP	\*r date format
X\f3Thu Jan 11 20:00:00 1990 LT\fP	output of \f3ctime\fP(3) + \f3LT\fP
X\f3Thu Jan 11 20:00:00 PST 1990\fP	output of \f3date\fP(1)
X\f3Fri Jan 12 04:00:00 GMT 1990\fP
X\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP
X\f3Fri-JST, 1990, 1pm Jan 12\fP
X\f312-January-1990, 04:00-WET\fP
X.ta 4n +4n +4n +4n
X.fi
X.RE
X.LP
XMost fields in the date and time may be defaulted.
XThe default time zone is \*g.
XThe other defaults are determined in the order year, month, day,
Xhour, minute, and second (most to least significant).  At least one of these
Xfields must be provided.  For omitted fields that are of higher significance
Xthan the highest provided field, the time zone's current values are assumed.
XFor all other omitted fields,
Xthe lowest possible values are assumed.
XFor example, the date
X.B "20, 10:30"
Xdefaults to
X10:30:00 \*g of the 20th of the \*g time zone's current month and year.
XThe date/time must be quoted if it contains spaces.
X.RE
X.TP
X.BI \-s state
Xretrieves the latest revision on the selected branch whose state is set to
X.I state.
X.TP
X.BR \-w [\f2login\fP]
Xretrieves the latest revision on the selected branch which was checked in
Xby the user with login name
X.I login.
XIf the argument
X.I login
Xis
Xomitted, the caller's login is assumed.
X.TP
X.BI \-j joinlist
Xgenerates a new revision which is the join of the revisions on
X.I joinlist.
XThis option is largely obsoleted by
X.BR rcsmerge (1)
Xbut is retained for backwards compatibility.
X.RS
X.PP
XThe
X.I joinlist
Xis a comma-separated list of pairs of the form
X.IB rev2 : rev3,
Xwhere
X.I rev2
Xand
X.I rev3
Xare (symbolic or numeric)
Xrevision numbers.
XFor the initial such pair,
X.I rev1
Xdenotes the revision selected
Xby the above options
X.BR \-f,
X\&.\|.\|.,
X.BR \-w .
XFor all other pairs,
X.I rev1
Xdenotes the revision generated by the previous pair.
X(Thus, the output
Xof one join becomes the input to the next.)
X.PP
XFor each pair,
X.B co
Xjoins revisions
X.I rev1
Xand
X.I rev3
Xwith respect to
X.I rev2.
XThis means that all changes that transform
X.I rev2
Xinto
X.I rev1
Xare applied to a copy of
X.I rev3.
XThis is particularly useful if
X.I rev1
Xand
X.I rev3
Xare the ends of two branches that have
X.I rev2
Xas a common ancestor.  If
X.IR rev1 < rev2 < rev3
Xon the same branch,
Xjoining generates a new revision which is like
X.I rev3,
Xbut with all changes that lead from
X.I rev1
Xto
X.I rev2
Xundone.
XIf changes from
X.I rev2
Xto
X.I rev1
Xoverlap with changes from
X.I rev2
Xto
X.I rev3,
X.B co
Xprints a warning and includes the
Xoverlapping sections, delimited by the lines
X.BI <<<<<<< "\ rev1,"
X.BR ======= ,
Xand
X.BI >>>>>>> "\ rev3."
X.PP
XFor the initial pair,
X.I rev2
Xmay be omitted.  The default is the common
Xancestor.
XIf any of the arguments indicate branches, the latest revisions
Xon those branches are assumed.
XThe options
X.B \-l
Xand
X.B \-u
Xlock or unlock
X.I rev1.
X.RE
X.TP
X.BI \-V n
XEmulate \*r version
X.I n,
Xwhere
X.I n
Xmay be
X.BR 3 ,
X.BR 4 ,
Xor
X.BR 5 .
XThis may be useful when interchanging \*r files with others who are
Xrunning older versions of \*r.
XTo see which version of \*r your correspondents are running, have them invoke
X.B rlog
Xon an \*r file;
Xif none of the first few lines of output contain the string
X.B branch:
Xit is version 3;
Xif the dates' years have just two digits, it is version 4;
Xotherwise, it is version 5.
XAn \*r file generated while emulating version 3 will lose its default branch.
XAn \*r revision generated while emulating version 4 or earlier will have
Xa timestamp that is off by up to 13 hours.
XA revision extracted while emulating version 4 or earlier will contain
Xdates of the form
X.IB yy / mm / dd
Xinstead of
X.IB yyyy / mm / dd
Xand may also contain different white space in the substitution for
X.BR $\&Log$ .
X.SH "KEYWORD SUBSTITUTION"
XStrings of the form
X.BI $ keyword $
Xand
X.BI $ keyword : .\|.\|. $
Xembedded in
Xthe text are replaced
Xwith strings of the form
X.BI $ keyword : value $
Xwhere
X.I keyword
Xand
X.I value
Xare pairs listed below.
XKeywords may be embedded in literal strings
Xor comments to identify a revision.
X.PP
XInitially, the user enters strings of the form
X.BI $ keyword $ .
XOn checkout,
X.B co
Xreplaces these strings with strings of the form
X.BI $ keyword : value $ .
XIf a revision containing strings of the latter form
Xis checked back in, the value fields will be replaced during the next
Xcheckout.
XThus, the keyword values are automatically updated on checkout.
XThis automatic substitution can be modified by the
X.B \-k
Xoptions.
X.PP
XKeywords and their corresponding values:
X.TP
X.B $\&Author$
XThe login name of the user who checked in the revision.
X.TP
X.B $\&Date$
XThe date and time (\*g) the revision was checked in.
X.TP
X.B $\&Header$
XA standard header containing the full pathname of the \*r file, the
Xrevision number, the date (\*g), the author, the state,
Xand the locker (if locked).
X.TP
X.B $\&Id$
XSame as
X.BR $\&Header$ ,
Xexcept that the \*r file name is without a path.
X.TP
X.B $\&Locker$
XThe login name of the user who locked the revision (empty if not locked).
X.TP
X.B $\&Log$
XThe log message supplied during checkin, preceded by a header
Xcontaining the \*r file name, the revision number, the author, and the date
X(\*g).
XExisting log messages are
X.I not
Xreplaced.
XInstead, the new log message is inserted after
X.BR $\&Log: .\|.\|. $ .
XThis is useful for
Xaccumulating a complete change log in a source file.
X.TP
X.B $\&RCSfile$
XThe name of the \*r file without a path.
X.TP
X.B $\&Revision$
XThe revision number assigned to the revision.
X.TP
X.B $\&Source$
XThe full pathname of the \*r file.
X.TP
X.B $\&State$
XThe state assigned to the revision with the
X.B \-s
Xoption of
X.BR rcs (1)
Xor
X.BR ci (1).
X.SH "FILE NAMING"
XPairs of \*r files and working files may be specified in three ways
X(see also the
Xexample section).
X.PP
X1) Both the \*r file and the working file are given.  The \*r file name is of
Xthe form
X.IB path1 / workfile ,v
Xand the working file name is of the form
X.IB path2 / workfile
Xwhere
X.IB path1 /
Xand
X.IB path2 /
Xare (possibly different or empty) paths and
X.I workfile
Xis a file name.
X.PP
X2) Only the \*r file is given.  Then the working file is created in the current
Xdirectory and its name is derived from the name of the \*r file
Xby removing
X.IB path1 /
Xand the suffix
X.BR ,v .
X.PP
X3) Only the working file is given.
XThen
X.B co
Xlooks for an \*r file of the form
X.IB path2 /RCS/ workfile ,v
Xor
X.IB path2 / workfile ,v
X(in this order).
X.PP
XIf the \*r file is specified without a path in 1) and 2), then
X.B co
Xlooks for the \*r file first in the directory
X.B ./RCS
Xand then in the current
Xdirectory.
X.SH EXAMPLES
XSuppose the current directory contains a subdirectory
X.B RCS
Xwith an \*r file
X.BR io.c,v .
XThen all of the following commands retrieve the latest
Xrevision from
X.B RCS/io.c,v
Xand store it into
X.BR io.c .
X.LP
X.RS
X.nf
X.ft 3
Xco  io.c;    co  RCS/io.c,v;   co  io.c,v;
Xco  io.c  RCS/io.c,v;    co  io.c  io.c,v;
Xco  RCS/io.c,v  io.c;    co  io.c,v  io.c;
X.ft
X.fi
X.RE
X.SH "FILE MODES"
XThe working file inherits the read and execute permissions from the \*r
Xfile.  In addition, the owner write permission is turned on, unless
X.B \-kv
Xis set or the file
Xis checked out unlocked and locking is set to strict (see
X.BR rcs (1)).
X.PP
XIf a file with the name of the working file exists already and has write
Xpermission,
X.B co
Xaborts the checkout,
Xasking beforehand if possible.
XIf the existing working file is
Xnot writable or
X.B \-f
Xis given, the working file is deleted without asking.
X.SH FILES
X.B co
Xaccesses files much as
X.BR ci (1)
Xdoes, except that it does not need to read the working file.
X.SH DIAGNOSTICS
XThe \*r file name, the working file name,
Xand the revision number retrieved are
Xwritten to the diagnostic output.
XThe exit status is zero if and only if all operations were successful.
X.SH IDENTIFICATION
XAuthor: Walter F. Tichy.
X.br
XRevision Number: \*(Rv; Release Date: \*(Dt.
X.br
XCopyright \(co 1982, 1988, 1989 by Walter F. Tichy.
X.br
XCopyright \(co 1990 by Paul Eggert.
X.SH "SEE ALSO"
Xci(1), ctime(3), date(1), ident(1),
Xrcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1),
Xrcsfile(5)
X.br
XWalter F. Tichy,
X\*r\*-A System for Version Control,
X.I "Software\*-Practice & Experience"
X.BR 15 ,
X7 (July 1985), 637-654.
X.SH LIMITS
XLinks to the \*r and working files are not preserved.
X.PP
XThere is no way to selectively suppress the expansion of keywords, except
Xby writing them differently.  In nroff and troff, this is done by embedding the
Xnull-character
X.B \e&
Xinto the keyword.
X.SH BUGS
XThe
X.B \-d
Xoption sometimes gets confused, and accepts no date before 1970.
END_OF_FILE
  if test 14638 -ne `wc -c <'man/co.1'`; then
    echo shar: \"'man/co.1'\" unpacked with wrong size!
  fi
  # end of 'man/co.1'
fi
if test -f 'src/conf.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/conf.sh'\"
else
  echo shar: Extracting \"'src/conf.sh'\" \(14859 characters\)
  sed "s/^X//" >'src/conf.sh' <<'END_OF_FILE'
X#!/bin/sh
X# Output RCS compile-time configuration.
XId='$Id: conf.sh,v 5.6 1990/11/01 05:03:28 eggert Exp $'
X#	Copyright 1990 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 1, 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
X
X# Direct standard output to "a.h"; later parts of this procedure need it.
X# Standard error can be ignored if a.h is OK,
X# and can be inspected for clues otherwise.
Xexec >a.h || exit
X
X# The Makefile overrides the following defaults.
X: ${C='cc -O'}
X: ${COMPAT2=0}
X: ${DIFF_FLAGS=-an}
X: ${DIFF_L=1}
X: ${RCSPREFIX=/usr/local/bin/}
X: ${SENDMAIL=/usr/lib/sendmail}
X: ${L=}
X: ${DIFF=${RCSPREFIX}diff}
X
X
Xcat <<EOF || exit
X/* RCS compile-time configuration */
X
X	/* $Id */
X
X/*
X * This file is generated automatically.
X * If you edit it by hand your changes may be lost.
X * Instead, please try to fix conf.sh,
X * and send your fixes to rcs-bugs@cs.purdue.edu.
X */
X
XEOF
X
X: exitmain
Xcat >a.c <<EOF && $C a.c $L >&2 || exit
X#include "a.h"
Xint main(argc,argv) int argc; char **argv; { return argc-1; }
XEOF
Xe='(n) ? (exit(n),(n)) : (n) /* lint fodder */'
Xif ./a.out -
Xthen :
Xelif ./a.out
Xthen e=n
Xfi
Xecho "#define exitmain(n) return $e /* how to exit from main() */"
X
X: standard includes
XstandardIncludes=
Xfor h in stdio sys/types sys/stat fcntl limits stdlib string unistd vfork
Xdo
X	cat >a.c <<EOF || exit
X#include "a.h"
X$standardIncludes
X#include <$h.h>
Xint main(){ exitmain(0); }
XEOF
X	if ($C a.c $L && ./a.out) >&2
X	then i="#	include <$h.h>"
X	else
X		case $h in
X		string)
X			i='#	include <strings.h>';;
X		*)
X			i="	/* #include <$h.h> does not work.  */"
X		esac
X	fi || exit
X	standardIncludes="$standardIncludes
X$i"
Xdone
X
Xcat <<EOF || exit
X#if !MAKEDEPEND$standardIncludes
X#endif /* !MAKEDEPEND */
XEOF
X
X# has_sys_*_h
Xfor H in dir param wait
Xdo
X	: has_sys_${H}_h
X	cat >a.c <<EOF || exit
X#include "a.h"
X#include <sys/$H.h>
Xint main() { exitmain(0); }
XEOF
X	if ($C a.c $L && ./a.out) >&2
X	then h=1
X	else h=0
X	fi
X	echo "#define has_sys_${H}_h $h /* Does #include <sys/$H.h> work?  */"
Xdone
X
X: const, volatile
Xfor i in const volatile
Xdo
X	cat >a.c <<EOF || exit
X#	include "a.h"
X	$i int * $i * zero;
XEOF
X	if $C -S a.c >&2
X	then echo "/* #define $i */ /* The '$i' keyword works.  */"
X	else echo "#define $i /* The '$i' keyword does not work.  */"
X	fi
Xdone
X
X# *_t
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#include <signal.h>
Xt x;
XEOF
Xfor t in gid_t mode_t pid_t sig_atomic_t size_t time_t uid_t
Xdo
X	: $t
X	case $t in
X	time_t) i=long;;
X	*) i=int;;
X	esac
X	if $C -S -Dt=$t a.c >&2
X	then echo "/* typedef $i $t; */ /* Standard headers define $t.  */"
X	else echo "typedef $i $t; /* Standard headers do not define $t.  */"
X	fi
Xdone
X
X: has_prototypes
Xcat >a.c <<'EOF' || exit
X#include "a.h"
Xint main(int, char**);
Xint main(int argc, char **argv) { exitmain(!argv[argc-1]); }
XEOF
Xif $C -S a.c >&2
Xthen h=1
Xelse h=0
Xfi
Xcat <<EOF
X#define has_prototypes $h /* Do function prototypes work?  */
X#if has_prototypes
X#	define P(params) params
X#	if !MAKEDEPEND
X#		include <stdarg.h>
X#	endif
X#	define vararg_start(ap,p) va_start(ap,p)
X#else
X#	define P(params) ()
X#	if !MAKEDEPEND
X#		include <varargs.h>
X#	endif
X#	define vararg_start(ap,p) va_start(ap)
X#endif
XEOF
X
X: has_getuid
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef getuid
X	uid_t getuid();
X#endif
Xint main() { exitmain(getuid()!=getuid()); }
XEOF
Xif ($C a.c $L && ./a.out) >&2
Xthen h=1
Xelse h=0
Xfi
Xecho "#define has_getuid $h /* Does getuid() work?  */"
X
X: declare_getpwuid
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#include <pwd.h>
Xd
Xint main() { exitmain(!getpwuid(0)); }
XEOF
XD='struct passwd *getpwuid P((uid_t));'
Xif ($C -Dd="$D" a.c $L && ./a.out) >&2
Xthen define="#define declare_getpwuid $D"
Xelif ($C -Dd= a.c $L && ./a.out) >&2
Xthen define="#define declare_getpwuid /* $D */"
Xelse define="/* #define declare_getpwuid $D */"
Xfi
Xecho "$define"
X
X: has_rename, bad_rename
Xcat >a.c <<'EOF' && rm -f a.d || exit
X#include "a.h"
X#ifndef rename
X	int rename();
X#endif
Xint main() { exitmain(rename("a.c","a.d")); }
XEOF
Xif ($C a.c $L && ./a.out && test -f a.d) >&2
Xthen
X	h=1
X	echo x >a.c
X	if ./a.out && test ! -f a.c -a -f a.d
X	then b=0
X	else b=1
X	fi
Xelse h=0 b=0
Xfi
Xecho "#define has_rename $h /* Does rename() work?  */"
Xecho "#define bad_rename $b /* Does rename(A,B) fail if B exists?  */"
X
X: void, VOID
Xcat >a.c <<'EOF' || exit
X#include "a.h"
Xvoid f() {}
Xint main() {f(); exitmain(0);}
XEOF
Xif $C -S a.c >&2
Xthen
X	v='(void) '
Xelse
X	v=
X	echo 'typedef int void;'
Xfi
Xecho "#define VOID $v/* 'VOID e;' discards the value of an expression 'e'.  */"
X
X: signal_type, sig_zaps_handler
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#include <signal.h>
X#ifndef getpid
X	pid_t getpid();
X#endif
X#ifndef kill
X	int kill();
X#endif
X#ifndef signal
X	signal_type (*signal P((int,signal_type(*)P((int)))))P((int));
X#endif
Xsignal_type nothing(i) int i; {}
Xint main(argc, argv) int argc; char **argv;
X{
X	signal(SIGINT, nothing);
X	while (--argc)
X		kill(getpid(), SIGINT);
X	exitmain(0);
X}
XEOF
Xfor signal_type in void int bad
Xdo
X	case $signal_type in
X	bad) echo >&2 "cannot deduce signal_type"; exit 1
X	esac
X	($C -Dsignal_type=$signal_type a.c $L && ./a.out 1) >&2 && break
Xdone
Xecho "#define signal_type $signal_type /* type returned by signal handlers */"
Xif ./a.out 1 2 >&2
Xthen z=0
Xelse z=1
Xfi
Xecho "#define sig_zaps_handler $z /* Must a signal handler reinvoke signal()?  */"
X
X: has_seteuid
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef geteuid
X	uid_t geteuid();
X#endif
Xint main() {
X/* Guess, don't test.  Ugh.  Testing would require running conf.sh setuid.  */
X#if !_POSIX_VERSION || _POSIX_VERSION==198808L&&!defined(sun)&&!defined(__sun__)
X	exitmain(1);
X#else
X	exitmain(seteuid(geteuid()) < 0);
X#endif
X}
XEOF
Xif ($C a.c $L && ./a.out) >&2
Xthen h=1
Xelse h=0
Xfi
Xecho "#define has_seteuid $h /* Does seteuid() obey Posix 1003.1-1990?  */"
X
X: has_sigaction
Xcat >a.c <<'EOF' || exit
X#include <signal.h>
Xstruct sigaction s;
XEOF
Xif $C -S a.c >&2
Xthen h=1
Xelse h=0
Xfi
Xecho "#define has_sigaction $h /* Does struct sigaction work?  */"
X
X: has_sigblock
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#include <signal.h>
X#ifndef sigblock
X	int sigblock();
X#endif
Xint main() { sigblock(0); exitmain(0); }
XEOF
Xif ($C a.c $L && ./a.out) >&2
Xthen h=1
Xelse h=0
Xfi
Xecho "#define has_sigblock $h /* Does sigblock() work?  */"
X
X: has_sys_siglist
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef sys_siglist
X	extern const char *sys_siglist[];
X#endif
Xint main() { exitmain(!sys_siglist[1][0]); }
XEOF
Xif ($C a.c $L && ./a.out) >&2
Xthen h=1
Xelse h=0
Xfi
Xecho "#define has_sys_siglist $h /* Does sys_siglist[] work?  */"
X
X: exit_type, underscore_exit_type
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef exit
X	void exit();
X#endif
Xint main() { exit(0); }
XEOF
Xif $C -S a.c >&2
Xthen t=void
Xelse t=int
Xfi
Xecho "#define exit_type $t /* type returned by exit() */"
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef _exit
X	void _exit();
X#endif
Xint main() { _exit(0); }
XEOF
Xif $C -S a.c >&2
Xthen t=void
Xelse t=int
Xfi
Xecho "#define underscore_exit_type $t /* type returned by _exit() */"
X
X: fread_type
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef fread
X	size_t fread();
X#endif
Xint main() { char b; exitmain(!(fread(&b,1,1,stdin)==1 && b=='#')); }
XEOF
Xif $C -S a.c $L >&2
Xthen t=size_t
Xelse t=int
Xfi
Xecho "typedef $t fread_type; /* type returned by fread() and fwrite() */"
X
X: malloc_type
Xcat >a.c <<'EOF' || exit
X#include "a.h"
Xtypedef void *malloc_type;
X#ifndef malloc
X	malloc_type malloc();
X#endif
Xint main() { exitmain(!malloc(1)); }
XEOF
Xif $C -S a.c >&2
Xthen t=void
Xelse t=char
Xfi
Xecho "typedef $t *malloc_type; /* type returned by malloc() */"
X
X: free_type
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef malloc
X	malloc_type malloc();
X#endif
X#ifndef free
X	void free();
X#endif
Xint main() { free(malloc(1)); exitmain(0); }
XEOF
Xif $C -S a.c >&2
Xthen t=void
Xelse t=int
Xfi
Xecho "#define free_type $t /* type returned by free() */"
X
X: strlen_type
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef strlen
X	size_t strlen();
X#endif
Xint main() { exitmain(strlen("")); }
XEOF
Xif $C -S a.c >&2
Xthen t=size_t
Xelse t=int
Xfi
Xecho "typedef $t strlen_type; /* type returned by strlen() */"
X
X: has_getcwd
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef getcwd
X	char *getcwd();
X#endif
Xchar buf[10000];
Xint main() { exitmain(!getcwd(buf,10000)); }
XEOF
Xif ($C a.c $L && ./a.out) >&2
Xthen has_getcwd=1
Xelse has_getcwd=0
Xfi
Xecho "#define has_getcwd $has_getcwd /* Does getcwd() work?  */"
X
X: has_getwd
Xcase $has_getcwd in
X0)
X	cat >a.c <<'EOF' || exit
X#include "a.h"
X#include <sys/param.h>
X#ifndef getwd
X	char *getwd();
X#endif
Xchar buf[MAXPATHLEN];
Xint main() { exitmain(!getwd(buf)); }
XEOF
X	if ($C a.c $L && ./a.out) >&2
X	then h=1
X	else h=0
X	fi
X	echo "#define has_getwd $h /* Does getwd() work?  */";;
X1)
X	echo "/* #define has_getwd ? */ /* Does getwd() work?  */"
Xesac
X
X: has_vfork
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#if has_sys_wait_h
X#	include <sys/wait.h>
X#endif
X#ifndef _exit
X	underscore_exit_type _exit();
X#endif
X#ifndef getpid
X	pid_t getpid();
X#endif
X#ifndef wait
X	pid_t wait();
X#endif
Xpid_t child;
Xint status;
Xstruct stat st;
Xint main()
X{
X	pid_t parent = getpid();
X	if (!(child = vfork())) {
X		/* Tickle vfork/compiler bug (e.g. sparc gcc -O (1.37.1).  */
X		pid_t i = getpid(), j = getpid();
X		if (i!=getpid() || j!=getpid())
X			_exit(!i);
X		/* Tickle file descriptor bug (e.g. IRIX 3.3).  */
X		_exit(close(1) < 0);
X	} else {
X		while (wait(&status) != child)
X			;
X		/* Test for presence of bugs.  */
X		exitmain(status  ||  parent != getpid()  ||  fstat(1, &st) < 0);
X	}
X}
XEOF
Xif ($C a.c $L && ./a.out) >&2
Xthen h=1
Xelse h=0
Xfi
Xecho "#define has_vfork $h /* Does vfork() work?  */"
X
X: has_vfprintf
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#if has_prototypes
Xint p(const char *format,...)
X#else
X/*VARARGS1*/ int p(format, va_alist) char *format; va_dcl
X#endif
X{
X	int r;
X	va_list args;
X	vararg_start(args, format);
X	r = vfprintf(stderr, format, args);
X	va_end(args);
X	return r;
X}
Xint main() { exitmain(p("")); }
XEOF
Xif ($C a.c $L && ./a.out) >&2
Xthen h=1
Xelse h=0
Xfi
Xecho "#define has_vfprintf $h /* Does vfprintf() work?  */"
X
X: strrchr
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef strrchr
X	char *strrchr();
X#endif
Xint main() {exitmain(!strrchr("abc", 'c'));}
XEOF
X($C a.c $L && ./a.out) >&2 ||
X  echo "#define strrchr rindex /* Use old-fashioned name for strrchr(). */"
X
X: CO
Xecho "#define CO \"${RCSPREFIX}co\" /* name of 'co' program */"
X
X: COMPAT2
Xecho "#define COMPAT2 $COMPAT2 /* Are version 2 files supported?  */"
X
X: DATEFORM
Xcat >a.c <<'EOF' || exit
X#include "a.h"
Xint main() { printf("%.2d", 1); exitmain(0); }
XEOF
X$C a.c $L >&2 && r=`./a.out` || exit
Xcase $r in
X01)	f=%.2d;;
X*)	f=%02d
Xesac
Xecho "#define DATEFORM \"$f.$f.$f.$f.$f.$f\" /* e.g. 01.01.01.01.01.01 */"
X
X: DIFF
Xecho "#define DIFF \"$DIFF\" /* name of 'diff' program */"
X
X: DIFF_FLAGS
Xdfs=
Xfor df in $DIFF_FLAGS
Xdo dfs="$dfs, \"$df\""
Xdone
Xecho "#define DIFF_FLAGS $dfs /* Make diff output suitable for RCS.  */"
X
X: DIFF_L
Xecho "#define DIFF_L $DIFF_L /* Does diff -L work? */"
X
X: EXECRCS
Xe=execv
Xfor i in "$DIFF" "$RCSPREFIX" "$SENDMAIL"
Xdo
X	case $i in
X	*/*) ;;
X	*) e=execvp break
X	esac
Xdone
Xecho "#define EXECRCS $e /* variant of execv() to use on subprograms */"
X
X: MERGE
Xecho "#define MERGE \"${RCSPREFIX}merge\" /* name of 'merge' program */"
X
X: RCSDIR, SLASH, TMPDIR
Xrm -fr a.RCS && mkdir a.RCS && echo x >a.RCS/x &&
Xcat >a.c <<'EOF' || exit
X#include "a.h"
Xmain() { exitmain(!fopen(NAME,"r")); }
XEOF
Xfor NAME in a.RCS/x 'a.rcs/x' 'A.RCS\\x' bad
Xdo ($C -DNAME="\"$NAME\"" a.c $L && ./a.out) && break
Xdone
Xcase $NAME in
Xa.RCS/x) RCSDIR=RCS/ SLASH=/ TMPDIR=/tmp/;;
Xa.rcs/x) RCSDIR=rcs/ SLASH=/ TMPDIR=/tmp/;;
X'A.RCS\\X') RCSDIR='RCS\\' SLASH='\\' TMPDIR='\\TMP\\';;
X*) echo >&2 "cannot deduce RCSDIR"; exit 1;;
Xesac
Xrm -fr a.RCS
Xecho "#define RCSDIR \"$RCSDIR\" /* subdirectory for RCS files */"
Xecho "#define SLASH '$SLASH' /* path name separator */"
Xecho "#define TMPDIR \"$TMPDIR\" /* default directory for temporary files */"
X
X: DIFF_PATH_HARDWIRED
Xcase $DIFF in
X"$SLASH"*) h=1;;
X*) h=0
Xesac
Xecho "#define DIFF_PATH_HARDWIRED $h /* Is DIFF absolute, not relative?  */"
X
X: ROOTPATH
Xcase `pwd` in
X[/\\]*)
X	echo '#define ROOTPATH(p) ((p)[0]==SLASH)';;
X?:[/\\]*)
X	echo '#define ROOTPATH(p) ((p)[0] && (p)[1]==':' && (p)[2]==SLASH)';;
X*)
X	echo >&2 "cannot deduce ROOTPATH"; exit 1;;
Xesac
X
X: RCSSEP
Xif echo x >a.1234567890,v && ($C -DNAME=\"a.1234567890,v\" a.c $L && ./a.out)
Xthen RCSSEP=','
Xelse RCSSEP='\0'
Xfi
Xecho "#define RCSSEP '$RCSSEP' /* separator for RCSSUF */"
X
X: SENDMAIL
Xecho "#define SENDMAIL $SENDMAIL /* how to send mail */"
X
X: fprintf, printf, vfprintf
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef printf
X	int printf P((const char*,...));
X#endif
Xint main() { printf(""); exitmain(0); }
XEOF
Xif $C -S a.c >&2
Xthen a='1 /* These agree with <stdio.h>.  */'
Xelse a='0 /* These conflict with <stdio.h>.  */'
Xfi
Xcat <<EOF || exit
X#if $a
X	int fprintf P((FILE*,const char*,...));
X	int printf P((const char*,...));
X#	if has_vfprintf
X		int vfprintf P((FILE*,const char*,...));
X#	else
X		void _doprnt P((const char*,...));
X#	endif
X#endif
XEOF
X
X: sprintf and other routines with '...' and default promotion problems
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#ifndef sprintf
X	int sprintf();
X#endif
Xint main()
X{
X	char buf[1];
X	exitmain(sprintf(buf, "") != 0);
X}
XEOF
Xif ($C a.c $L && ./a.out) >&2
Xthen t='int '
Xelse t='char *'
Xfi
Xcat >a.c <<'EOF' || exit
X#include "a.h"
X#if has_sys_wait_h
X#	include <sys/wait.h>
X#endif
Xdeclaration
Xint main() { exitmain(0); }
XEOF
Xfor declaration in \
X	"${t}sprintf P((char*,const char*,...));" \
X	'int chmod P((const char*,mode_t));' \
X	'int fcntl P((int,int,...));' \
X	'int open P((const char*,int,...));' \
X	'mode_t umask P((mode_t));' \
X	'pid_t wait P((int*));'
Xdo
X	if $C -S -Ddeclaration="$declaration" a.c >&2
X	then echo "$declaration"
X	else echo "/* $declaration */"
X	fi
Xdone
Xfor i in '
X#ifndef O_CREAT
X	int creat P((const char*,mode_t));
X#endif' '
X#if has_seteuid
X	int setegid P((gid_t));
X	int seteuid P((uid_t));
X#endif'
X	# See declare_getpwuid for how getpwuid() is handled.
Xdo
X	echo '#include "a.h"
X		int main() { exitmain(0); }'"$i" >a.c || exit
X	if $C -S a.c >&2
X	then sed 1,2d a.c
X	else sed '1,2d; s|.*|/* & */|' a.c
X	fi
Xdone
END_OF_FILE
  if test 14859 -ne `wc -c <'src/conf.sh'`; then
    echo shar: \"'src/conf.sh'\" unpacked with wrong size!
  fi
  # end of 'src/conf.sh'
fi
if test -f 'src/rcsgen.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/rcsgen.c'\"
else
  echo shar: Extracting \"'src/rcsgen.c'\" \(11524 characters\)
  sed "s/^X//" >'src/rcsgen.c' <<'END_OF_FILE'
X/*
X *                     RCS revision generation
X */
X
X/* Copyright (C) 1982, 1988, 1989 Walter Tichy
X   Copyright 1990 by Paul Eggert
X   Distributed under license by the Free Software Foundation, Inc.
X
XThis file is part of RCS.
X
XRCS is free software; you can redistribute it and/or modify
Xit under the terms of the GNU General Public License as published by
Xthe Free Software Foundation; either version 1, or (at your option)
Xany later version.
X
XRCS is distributed in the hope that it will be useful,
Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
XGNU General Public License for more details.
X
XYou should have received a copy of the GNU General Public License
Xalong with RCS; see the file COPYING.  If not, write to
Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
X
XReport problems and direct all questions to:
X
X    rcs-bugs@cs.purdue.edu
X
X*/
X
X
X
X/* $Log: rcsgen.c,v $
X * Revision 5.6  1990/12/27  19:54:26  eggert
X * Fix bug: rcs -t inserted \n, making RCS file grow.
X *
X * Revision 5.5  1990/12/04  05:18:45  eggert
X * Use -I for prompts and -q for diagnostics.
X *
X * Revision 5.4  1990/11/01  05:03:47  eggert
X * Add -I and new -t behavior.  Permit arbitrary data in logs.
X *
X * Revision 5.3  1990/09/21  06:12:43  hammer
X * made putdesc() treat stdin the same whether or not it was from a terminal
X * by making it recognize that a single '.' was then end of the
X * description always
X *
X * Revision 5.2  1990/09/04  08:02:25  eggert
X * Fix `co -p1.1 -ko' bug.  Standardize yes-or-no procedure.
X *
X * Revision 5.1  1990/08/29  07:14:01  eggert
X * Clean old log messages too.
X *
X * Revision 5.0  1990/08/22  08:12:52  eggert
X * Remove compile-time limits; use malloc instead.
X * Ansify and Posixate.
X *
X * Revision 4.7  89/05/01  15:12:49  narten
X * changed copyright header to reflect current distribution rules
X * 
X * Revision 4.6  88/08/28  14:59:10  eggert
X * Shrink stdio code size; allow cc -R; remove lint; isatty() -> ttystdin()
X * 
X * Revision 4.5  87/12/18  11:43:25  narten
X * additional lint cleanups, and a bug fix from the 4.3BSD version that
X * keeps "ci" from sticking a '\377' into the description if you run it
X * with a zero-length file as the description. (Guy Harris)
X * 
X * Revision 4.4  87/10/18  10:35:10  narten
X * Updating version numbers. Changes relative to 1.1 actually relative to
X * 4.2
X * 
X * Revision 1.3  87/09/24  13:59:51  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:27  jenkins
X * Port to suns
X * 
X * Revision 4.2  83/12/02  23:01:39  wft
X * merged 4.1 and 3.3.1.1 (clearerr(stdin)).
X * 
X * Revision 4.1  83/05/10  16:03:33  wft
X * Changed putamin() to abort if trying to reread redirected stdin.
X * Fixed getdesc() to output a prompt on initial newline.
X * 
X * Revision 3.3.1.1  83/10/19  04:21:51  lepreau
X * Added clearerr(stdin) for re-reading description from stdin.
X * 
X * Revision 3.3  82/11/28  21:36:49  wft
X * 4.2 prerelease
X * 
X * Revision 3.3  82/11/28  21:36:49  wft
X * Replaced ferror() followed by fclose() with ffclose().
X * Putdesc() now suppresses the prompts if stdin
X * is not a terminal. A pointer to the current log message is now
X * inserted into the corresponding delta, rather than leaving it in a
X * global variable.
X *
X * Revision 3.2  82/10/18  21:11:26  wft
X * I added checks for write errors during editing, and improved
X * the prompt on putdesc().
X *
X * Revision 3.1  82/10/13  15:55:09  wft
X * corrected type of variables assigned to by getc (char --> int)
X */
X
X
X
X
X#include "rcsbase.h"
X
XlibId(genId, "$Id: rcsgen.c,v 5.6 1990/12/27 19:54:26 eggert Exp $")
X
Xint interactiveflag;  /* Should we act as if stdin is a tty?  */
Xstruct cbuf curlogmsg;  /* buffer for current log message */
Xstruct buf curlogbuf;  /* same, including allocated but unused bytes */
X
Xenum stringwork {copy, edit, expand, edit_expand };
X
Xstatic void scandeltatext P((struct hshentry*,enum stringwork));
X
X
X
X
X	const char *
Xbuildrevision(deltas, target, tostdout, expandflag)
X	const struct hshentries *deltas;
X	struct hshentry *target;
X	int tostdout;
X	int expandflag;
X/* Function: Generates the revision given by target
X * by retrieving all deltas given by parameter deltas and combining them.
X * If tostdout is set, the revision is printed on the standard output,
X * otherwise written into a temporary file.
X * Temporary files are put into tmp unless the caller has already set up
X * the temp file directory by invoking initeditfiles(), which sets fcopy.
X * if expandflag is set, keyword expansion is performed.
X * Returns nil on errors, the name of the file with the revision otherwise.
X *
X * Algorithm: Copy initial revision unchanged.  Then edit all revisions but
X * the last one into it, alternating input and output files (resultfile and
X * editfile). The last revision is then edited in, performing simultaneous
X * keyword substitution (this saves one extra pass).
X * All this simplifies if only one revision needs to be generated,
X * or no keyword expansion is necessary, or if output goes to stdout.
X */
X{
X	static const char nonnil[] = ""; /* some char* value that isn't nil */
X
X	if (deltas->first == target) {
X                /* only latest revision to generate */
X		if (tostdout) {
X                        fcopy=stdout;
X			scandeltatext(target, expandflag?expand:copy);
X			return nonnil;
X                } else {
X			if (!fcopy)
X				inittmpeditfiles();
X                        scandeltatext(target,expandflag?expand:copy);
X                        ffclose(fcopy);
X                        return(resultfile);
X                }
X        } else {
X                /* several revisions to generate */
X		if (!fcopy)
X			inittmpeditfiles();
X                /* write initial revision into fcopy, no keyword expansion */
X		scandeltatext(deltas->first, copy);
X		while ((deltas=deltas->rest)->rest) {
X                        /* do all deltas except last one */
X			scandeltatext(deltas->first, edit);
X                }
X		if (expandflag | tostdout) {
X                        /* first, get to beginning of file*/
X			finishedit((struct hshentry *)nil);
X			swapeditfiles(tostdout);
X                }
X		scandeltatext(deltas->first, expandflag ? edit_expand : edit);
X		finishedit(expandflag ? deltas->first : (struct hshentry*)nil);
X		if (tostdout)
X			return nonnil;
X		ffclose(fcopy);
X		return resultfile;
X        }
X}
X
X
X
X	static void
Xscandeltatext(delta,func)
Xstruct hshentry * delta; enum stringwork func;
X/* Function: Scans delta text nodes up to and including the one given
X * by delta. For the one given by delta, the log message is saved into
X * curlogmsg and the text is processed according to parameter func.
X * Assumes the initial lexeme must be read in first.
X * Does not advance nexttok after it is finished.
X */
X{
X	const struct hshentry *nextdelta;
X	struct cbuf cb;
X
X        for (;;) {
X                nextlex();
X                if (!(nextdelta=getnum())) {
X		    fatserror("can't find delta for revision %s", delta->num);
X                }
X		getkeystring(Klog);
X		if (delta==nextdelta) {
X			cb = savestring(&curlogbuf);
X			delta->log = curlogmsg =
X				cleanlogmsg(curlogbuf.string, cb.size);
X                } else {readstring();
X                }
X                nextlex();
X		while (nexttok==ID && strcmp(NextString,Ktext)!=0)
X			ignorephrase();
X		getkeystring(Ktext);
X
X		if (delta==nextdelta)
X			break;
X		readstring(); /* skip over it */
X
X	}
X	switch (func) {
X		case copy: copystring(); break;
X		case expand: xpandstring(delta); break;
X		case edit: editstring((struct hshentry *)nil); break;
X		case edit_expand: editstring(delta); break;
X	}
X}
X
X	struct cbuf
Xcleanlogmsg(m, s)
X	char *m;
X	size_t s;
X{
X	register char *t = m;
X	register const char *f = t;
X	struct cbuf r;
X	while (s) {
X	    --s;
X	    if ((*t++ = *f++) == '\n')
X		while (m < --t)
X		    if (t[-1]!=' ' && t[-1]!='\t') {
X			*t++ = '\n';
X			break;
X		    }
X	}
X	while (m < t  &&  (t[-1]==' ' || t[-1]=='\t' || t[-1]=='\n'))
X	    --t;
X	r.string = m;
X	r.size = t - m;
X	return r;
X}
X
X
Xint ttystdin()
X{
X	static int initialized;
X	if (!initialized) {
X		if (!interactiveflag)
X			interactiveflag = isatty(STDIN_FILENO);
X		initialized = true;
X	}
X	return interactiveflag;
X}
X
X	int
Xgetcstdin()
X{
X	register int c = getchar();
X	if (c == EOF) {
X		if (ferror(stdin))
X			IOerror();
X		if (ttystdin()) {
X			clearerr(stdin);
X			afputc('\n',stderr);
X		}
X	}
X	return c;
X}
X
X#if has_prototypes
X	int
Xyesorno(int default_answer, const char *question, ...)
X#else
X		/*VARARGS2*/ int
X	yesorno(default_answer, question, va_alist)
X		int default_answer; const char *question; va_dcl
X#endif
X{
X	va_list args;
X	register int c, r;
X	if (!quietflag && ttystdin()) {
X		oflush();
X		vararg_start(args, question);
X		fvfprintf(stderr, question, args);
X		va_end(args);
X		eflush();
X		r = c = getcstdin();
X		while (c!='\n' && c!=EOF)
X			c = getcstdin();
X		if (r=='y' || r=='Y')
X			return true;
X		if (r=='n' || r=='N')
X			return false;
X	}
X	return default_answer;
X}
X
X
X	void
Xputdesc(textflag, textfile)
X	int textflag;
X	const char *textfile;
X/* Function: puts the descriptive text into file frewrite.
X * if finptr && !textflag, the text is copied from the old description.
X * Otherwise, if the textfile!=nil, the text is read from that
X * file, or from stdin, if textfile==nil.
X * A textfile with a leading '-' is treated as a string, not a file name.
X * If finptr, the old descriptive text is discarded.
X */
X{       register FILE * txt; register int c, old1, old2;
X	register FILE * frew;
X
X	frew = frewrite;
X	if (finptr && !textflag) {
X                /* copy old description */
X		aprintf(frew,"\n\n%s%c",Kdesc,nextc);
X		foutptr = frewrite;
X		getdesc(false);
X        } else {
X                /* get new description */
X		if (finptr) {
X                        /*skip old description*/
X			foutptr = NULL;
X			getdesc(false);
X                }
X		aprintf(frew,"\n\n%s\n%c",Kdesc,SDELIM);
X                if (textfile) {
X                        old1='\n';
X                        /* copy textfile */
X			txt = NULL;
X			if (*textfile=='-' || (txt=fopen(textfile,"r"))) {
X				while (txt ? (c=getc(txt))!=EOF : (c = *++textfile)) {
X					if (c==SDELIM) afputc(c,frew); /*double up*/
X					afputc(c,frew);
X                                        old1=c;
X                                }
X				if (old1!='\n') afputc('\n',frew);
X				if (txt) ffclose(txt);
X				aprintf(frew, "%c\n", SDELIM);
X				return;
X                        } else {
X				efaterror(textfile);
X                        }
X                }
X                /* read text from stdin */
X		if (feof(stdin))
X		    faterror("can't reread redirected stdin for description; use -t-<description>");
X		if (ttystdin())
X		    aputs("enter description, terminated with single '.' or end of file:\nNOTE: This is NOT the log message!\n>> ",stderr);
X		if ((old1=getcstdin()) != EOF) {
X		     old2 = '\n';
X		     for (;;) {
X			    if (old1=='\n' && ttystdin())
X				    aputs(">> ",stderr);
X			    c = getcstdin();
X                            if (c==EOF) {
X				    afputc(old1,frew);
X				    if (old1!='\n') afputc('\n',frew);
X                                    break;
X                            }
X			    if (c=='\n' && old1=='.' && old2=='\n') {
X                                    break;
X                            }
X			    if (old1==SDELIM) afputc(old1,frew); /* double up*/
X			    afputc(old1,frew);
X                            old2=old1;
X                            old1=c;
X                    } /* end for */
X		}
X		aprintf(frew, "%c\n", SDELIM);
X        }
X}
END_OF_FILE
  if test 11524 -ne `wc -c <'src/rcsgen.c'`; then
    echo shar: \"'src/rcsgen.c'\" unpacked with wrong size!
  fi
  # end of 'src/rcsgen.c'
fi
echo shar: End of archive 9 \(of 12\).
cp /dev/null ark9isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 12 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still must unpack the following archives:
    echo "        " ${MISSING}
fi
exit 0
exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.