summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
authoreadler <eadler@FreeBSD.org>2013-10-07 02:23:00 +0000
committereadler <eadler@FreeBSD.org>2013-10-07 02:23:00 +0000
commitba3f99676351684264da1513884a8aae3359a3fb (patch)
tree5fdf6b3f346166d536a79653631f395ca5f6a1fc /gnu
parent34d055e746b4dad0722315b2096024ed9e08cd69 (diff)
downloadFreeBSD-src-ba3f99676351684264da1513884a8aae3359a3fb.zip
FreeBSD-src-ba3f99676351684264da1513884a8aae3359a3fb.tar.gz
Good bye RCS. You will be missed.
(devel/rcs and devel/rcs57 are available as alternatives) Approved by: core Approved by: re (hrs)
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/Makefile5
-rw-r--r--gnu/usr.bin/rcs/CREDITS24
-rw-r--r--gnu/usr.bin/rcs/Makefile3
-rw-r--r--gnu/usr.bin/rcs/Makefile.inc3
-rw-r--r--gnu/usr.bin/rcs/NEWS548
-rw-r--r--gnu/usr.bin/rcs/REFS90
-rw-r--r--gnu/usr.bin/rcs/ci/Makefile8
-rw-r--r--gnu/usr.bin/rcs/ci/ci.1898
-rw-r--r--gnu/usr.bin/rcs/ci/ci.c1318
-rw-r--r--gnu/usr.bin/rcs/co/Makefile8
-rw-r--r--gnu/usr.bin/rcs/co/co.1736
-rw-r--r--gnu/usr.bin/rcs/co/co.c826
-rw-r--r--gnu/usr.bin/rcs/doc/rcs.ms1518
-rw-r--r--gnu/usr.bin/rcs/doc/rcs_func.ms95
-rw-r--r--gnu/usr.bin/rcs/ident/Makefile8
-rw-r--r--gnu/usr.bin/rcs/ident/ident.1182
-rw-r--r--gnu/usr.bin/rcs/ident/ident.c270
-rw-r--r--gnu/usr.bin/rcs/lib/Makefile14
-rw-r--r--gnu/usr.bin/rcs/lib/conf.h400
-rw-r--r--gnu/usr.bin/rcs/lib/maketime.c344
-rw-r--r--gnu/usr.bin/rcs/lib/maketime.h39
-rw-r--r--gnu/usr.bin/rcs/lib/merger.c148
-rw-r--r--gnu/usr.bin/rcs/lib/partime.c701
-rw-r--r--gnu/usr.bin/rcs/lib/partime.h71
-rw-r--r--gnu/usr.bin/rcs/lib/rcsbase.h762
-rw-r--r--gnu/usr.bin/rcs/lib/rcsedit.c1958
-rw-r--r--gnu/usr.bin/rcs/lib/rcsfcmp.c354
-rw-r--r--gnu/usr.bin/rcs/lib/rcsfnms.c1132
-rw-r--r--gnu/usr.bin/rcs/lib/rcsgen.c681
-rw-r--r--gnu/usr.bin/rcs/lib/rcskeep.c452
-rw-r--r--gnu/usr.bin/rcs/lib/rcskeys.c186
-rw-r--r--gnu/usr.bin/rcs/lib/rcslex.c1568
-rw-r--r--gnu/usr.bin/rcs/lib/rcsmap.c69
-rw-r--r--gnu/usr.bin/rcs/lib/rcsrev.c911
-rw-r--r--gnu/usr.bin/rcs/lib/rcssyn.c681
-rw-r--r--gnu/usr.bin/rcs/lib/rcstime.c191
-rw-r--r--gnu/usr.bin/rcs/lib/rcsutil.c1398
-rw-r--r--gnu/usr.bin/rcs/lib/version.c2
-rw-r--r--gnu/usr.bin/rcs/merge/Makefile8
-rw-r--r--gnu/usr.bin/rcs/merge/merge.1137
-rw-r--r--gnu/usr.bin/rcs/merge/merge.c113
-rw-r--r--gnu/usr.bin/rcs/rcs/Makefile10
-rw-r--r--gnu/usr.bin/rcs/rcs/rcs.1454
-rw-r--r--gnu/usr.bin/rcs/rcs/rcs.c1629
-rw-r--r--gnu/usr.bin/rcs/rcs/rcsfile.5425
-rw-r--r--gnu/usr.bin/rcs/rcs/rcsintro.1302
-rw-r--r--gnu/usr.bin/rcs/rcsclean/Makefile8
-rw-r--r--gnu/usr.bin/rcs/rcsclean/rcsclean.1203
-rw-r--r--gnu/usr.bin/rcs/rcsclean/rcsclean.c333
-rw-r--r--gnu/usr.bin/rcs/rcsdiff/Makefile8
-rw-r--r--gnu/usr.bin/rcs/rcsdiff/rcsdiff.1158
-rw-r--r--gnu/usr.bin/rcs/rcsdiff/rcsdiff.c480
-rw-r--r--gnu/usr.bin/rcs/rcsfreeze/Makefile7
-rw-r--r--gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.168
-rw-r--r--gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.sh99
-rw-r--r--gnu/usr.bin/rcs/rcsmerge/Makefile8
-rw-r--r--gnu/usr.bin/rcs/rcsmerge/rcsmerge.1189
-rw-r--r--gnu/usr.bin/rcs/rcsmerge/rcsmerge.c286
-rwxr-xr-xgnu/usr.bin/rcs/rcstest454
-rw-r--r--gnu/usr.bin/rcs/rlog/Makefile8
-rw-r--r--gnu/usr.bin/rcs/rlog/rlog.1318
-rw-r--r--gnu/usr.bin/rcs/rlog/rlog.c1290
62 files changed, 0 insertions, 25597 deletions
diff --git a/gnu/usr.bin/Makefile b/gnu/usr.bin/Makefile
index 663107c..8ece263 100644
--- a/gnu/usr.bin/Makefile
+++ b/gnu/usr.bin/Makefile
@@ -12,7 +12,6 @@ SUBDIR= ${_binutils} \
${_gperf} \
grep \
${_groff} \
- ${_rcs} \
sdiff \
send-pr \
${_texinfo}
@@ -32,10 +31,6 @@ _dtc= dtc
_texinfo= texinfo
.endif
-.if ${MK_RCS} != "no"
-_rcs= rcs
-.endif
-
.if ${MK_BINUTILS} != "no"
_binutils= binutils
.endif
diff --git a/gnu/usr.bin/rcs/CREDITS b/gnu/usr.bin/rcs/CREDITS
deleted file mode 100644
index 589e8b6..0000000
--- a/gnu/usr.bin/rcs/CREDITS
+++ /dev/null
@@ -1,24 +0,0 @@
-RCS was designed and built by Walter F. Tichy of Purdue University.
-RCS version 3 was released in 1983.
-
-Adam Hammer, Thomas Narten, and Daniel Trinkle of Purdue supported RCS through
-version 4.3, released in 1990. Guy Harris of Sun contributed many porting
-fixes. Paul Eggert of System Development Corporation contributed bug fixes
-and tuneups. Jay Lepreau contributed 4.3BSD support.
-
-Paul Eggert of Twin Sun wrote the changes for RCS versions 5.5 and 5.6 (1991).
-Rich Braun of Kronos and Andy Glew of Intel contributed ideas for new options.
-Bill Hahn of Stratus contributed ideas for setuid support.
-Ideas for piece tables came from Joe Berkovitz of Stratus and Walter F. Tichy.
-Matt Cross of Stratus contributed test case ideas.
-Adam Hammer of Purdue QAed.
-
-Paul Eggert wrote most of the changes for this version of RCS,
-currently in beta test. K. Richard Pixley of Cygnus Support
-contributed several bug fixes. Robert Lupton of Princeton
-and Daniel Trinkle contributed ideas for $Name expansion.
-Brendan Kehoe of Cygnus Support suggested rlog's -N option.
-Paul D. Smith of Data General suggested improvements in option
-and error processing. Adam Hammer of Purdue QAed.
-
-$FreeBSD$
diff --git a/gnu/usr.bin/rcs/Makefile b/gnu/usr.bin/rcs/Makefile
deleted file mode 100644
index 4a9fd08..0000000
--- a/gnu/usr.bin/rcs/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-SUBDIR= lib ci co ident merge rcs rcsclean rcsdiff rcsmerge rlog rcsfreeze
-
-.include <bsd.subdir.mk>
diff --git a/gnu/usr.bin/rcs/Makefile.inc b/gnu/usr.bin/rcs/Makefile.inc
deleted file mode 100644
index a46437a..0000000
--- a/gnu/usr.bin/rcs/Makefile.inc
+++ /dev/null
@@ -1,3 +0,0 @@
-# $FreeBSD$
-
-LIBRCS= ${.OBJDIR}/../lib/librcs.a
diff --git a/gnu/usr.bin/rcs/NEWS b/gnu/usr.bin/rcs/NEWS
deleted file mode 100644
index 9920806..0000000
--- a/gnu/usr.bin/rcs/NEWS
+++ /dev/null
@@ -1,548 +0,0 @@
-Recent changes to RCS (and possible future changes)
-
- $FreeBSD$
-
- Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
- This file is part of RCS.
-
- 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.
-
- 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.
-
- 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,
- 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-
-Here is a brief summary of user-visible changes since 5.6.
-
- New options:
- `-kb' supports binary files.
- `-T' preserves the modification time of RCS files.
- `-V' prints the version number.
- `-zLT' causes RCS to use local time in working files and logs.
- `rcsclean -n' outputs what rcsclean would do, without actually doing it.
- `rlog -N' omits symbolic names.
- There is a new keyword `Name'.
- Inserted log lines now have the same prefix as the preceding `$Log' line.
-
-Most changes for RCS version 5.7 are to fix bugs and improve portability.
-RCS now conforms to GNU configuration standards and to Posix 1003.1b-1993.
-
-
-Features new to RCS version 5.7, and possibly incompatible
-in minor ways with previous practice, include:
-
- Inserted log lines now have the same prefix as the preceding `$Log' line.
- E.g. if a $Log line starts with `// $Log', log lines are prefixed with `// '.
- RCS still records the (now obsolescent) comment leader inside RCS files,
- but it ignores the comment leader unless it is emulating older RCS versions.
- If you plan to access a file with both old and new versions of RCS,
- make sure its comment leader matches its `$Log' line prefix.
- For backwards compatibility with older versions of RCS,
- if the log prefix is `/*' or `(*' surrounded by optional white space,
- inserted log lines contain ` *' instead of `/*' or `(*';
- however, this usage is obsolescent and should not be relied on.
-
- $Log string `Revision' times now use the same format as other times.
-
- Log lines are now inserted even if -kk is specified; this simplifies merging.
-
- ci's -rR option (with a nonempty R) now just specifies a revision number R.
- In some beta versions, it also reestablished the default behavior of
- releasing a lock and removing the working file.
- Now, only the bare -r option does this.
-
- With an empty extension, any appearance of a directory named `RCS'
- in a pathname identifies the pathname as being that of an RCS file.
- For example, `a/RCS/b/c' is now an RCS file with an empty extension.
- Formerly, `RCS' had to be the last directory in the pathname.
-
- rlog's -d option by default now uses exclusive time ranges.
- E.g. `rlog -d"<T"' now excludes revisions whose times equal T exactly.
- Use `rlog -d"<=T"' to get the old behavior.
-
- merge now takes up to three -L options, one for each input file.
- Formerly, it took at most two -L options, for the 1st and 3rd input files.
-
- `rcs' now requires at least one option; this is for future expansion.
-
-Other features new to RCS version 5.7 include:
-
- merge and rcsmerge now pass -A, -E, and -e options to the subsidiary diff3.
-
- rcs -kb acts like rcs -ko, except it uses binary I/O on working files.
- This makes no difference under Posix or Unix, but it does matter elsewhere.
- With -kb in effect, rcsmerge refuses to merge;
- this avoids common problems with CVS merging.
-
- The following is for future use by GNU Emacs 19's version control package:
-
- rcs's new -M option causes it to not send mail when you break somebody
- else's lock. This is not meant for casual use; see rcs(1).
-
- ci's new -i option causes an error if the RCS file already exists.
- Similarly, -j causes an error if the RCS file does not already exist.
-
- The new keyword `Name' is supported; its value is the name, if any,
- used to check out the revision. E.g. `co -rN foo' causes foo's
- $Name...$ keyword strings to end in `: N $'.
-
- The new -zZONE option causes RCS to output dates and times using ISO 8601
- format with ZONE as the time zone, and to use ZONE as the default time
- zone for input. Its most common use is the -zLT option, which causes RCS
- to use local time externally. You can also specify foreign time zones;
- e.g. -z+05:30 causes RCS to use India time (5 hours 30 minutes east of UTC).
- This option does not affect RCS files themselves, which always use UTC;
- it affects only output (e.g. rlog output, keyword expansion, diff -c times)
- and interpretation of options (e.g. the -d option of ci, co, and rlog).
- Bare -z restores the default behavior of UTC with no time zone indication,
- and the traditional RCS date separator `/' instead of the ISO 8601 `-'.
- RCSINIT may contain a -z option. ci -k parses UTC offsets.
-
- The new -T option of ci, co, rcs, and rcsclean preserves the modification
- time of the RCS file unless a revision is added or removed.
- ci -T sets the RCS file's modification time to the new revision's time
- if the former precedes the latter and there is a new revision;
- otherwise, it preserves the RCS file's modification time.
- Use this option with care, as it can confuse `make'; see ci(1).
-
- The new -N option of rlog omits symbolic names from the output.
-
- A revision number that starts with `.' is considered to be relative to
- the default branch (normally the trunk). A branch number followed by `.'
- stands for the last revision on that branch.
-
- If someone else already holds the lock, rcs -l now asks whether you want
- to break it, instead of immediately reporting an error.
-
- ci now always unlocks a revision like 3.5 if you check in a revision
- like 3.5.2.1 that is the first of a new branch of that revision.
- Formerly it was inconsistent.
-
- File names may now contain tab, newline, space, and '$'.
- They are represented in keyword strings with \t, \n, \040, and \044.
- \ in a file name is now represented by \\ in a keyword string.
-
- Identifiers may now start with a digit and (unless they are symbolic names)
- may contain `.'. This permits author names like `john.doe' and `4tran'.
-
- A bare -V option now prints the current version number.
-
- rcsdiff outputs more readable context diff headers if diff -L works.
-
- rcsdiff -rN -rN now suppresses needless checkout and comparison
- of identical revisions.
-
- Error messages now contain the names of files to which they apply.
-
- Mach style memory mapping is now supported.
-
- The installation procedure now conforms to the GNU coding standards.
-
- When properly configured, RCS now strictly conforms to Posix 1003.1b-1993.
-
-
-Features new to RCS version 5.6 include:
-
- Security holes have been plugged; setgid use is no longer supported.
-
- co can retrieve old revisions much more efficiently.
- To generate the Nth youngest revision on the trunk,
- the old method used up to N passes through copies of the working file;
- the new method uses a piece table to generate the working file in one pass.
-
- When ci finds no changes in the working file,
- it automatically reverts to the previous revision unless -f is given.
-
- RCS follows symbolic links to RCS files instead of breaking them,
- and warns when it breaks hard links to RCS files.
-
- `$' stands for the revision number taken from working file keyword strings.
- E.g. if F contains an Id keyword string,
- `rcsdiff -r$ F' compares F to its checked-in revision, and
- `rcs -nL:$ F' gives the symbolic name L to F's revision.
-
- co and ci's new -M option sets the modification time
- of the working file to be that of the revision.
- Without -M, ci now tries to avoid changing the working file's
- modification time if its contents are unchanged.
-
- rcs's new -m option changes the log message of an old revision.
-
- RCS is portable to hosts that do not permit `,' in filenames.
- (`,' is not part of the Posix portable filename character set.)
- A new -x option specifies extensions other than `,v' for RCS files.
- The Unix default is `-x,v/', so that the working file `w' corresponds
- to the first file in the list `RCS/w,v', `w,v', `RCS/w' that works.
- The non-Unix default is `-x', so that only `RCS/w' is tried.
- Eventually, the Unix default should change to `-x/,v'
- to encourage interoperability among all Posix hosts.
-
- A new RCSINIT environment variable specifies defaults for options like -x.
-
- The separator for revision ranges has been changed from `-' to `:', because
- the range `A-B' is ambiguous if `A', `B' and `A-B' are all symbolic names.
- E.g. the old `rlog -r1.5-1.7' is now `rlog -r1.5:1.7'; ditto for `rcs -o'.
- For a while RCS will still support (but warn about) the old `-' separator.
-
- RCS manipulates its lock files using a method that is more reliable under NFS.
-
-
-Features new to RCS version 5 include:
-
- RCS can check in arbitrary files, not just text files, if diff -a works.
- RCS can merge lines containing just a single `.' if diff3 -m works.
- GNU diff supports the -a and -m options.
-
- RCS can now be used as a setuid program.
- See ci(1) for how users can employ setuid copies of ci, co, and rcsclean.
- Setuid privileges yield extra security if the effective user owns RCS files
- and directories, and if only the effective user can write RCS directories.
- RCS uses the real user for all accesses other than writing RCS directories.
- As described in ci(1), there are three levels of setuid support.
-
- 1. Setuid works fully if the seteuid() system call lets any
- process switch back and forth between real and effective users,
- as specified in Posix 1003.1a Draft 5.
-
- 2. On hosts with saved setuids (a Posix 1003.1-1990 option) and without
- a modern seteuid(), setuid works unless the real or effective user is root.
-
- 3. On hosts that lack both modern seteuid() and saved setuids,
- setuid does not work, and RCS uses the effective user for all accesses;
- formerly it was inconsistent.
-
- New options to co, rcsdiff, and rcsmerge give more flexibility to keyword
- substitution.
-
- -kkv substitutes the default `$Keyword: value $' for keyword strings.
- However, a locker's name is inserted only as a file is being locked,
- i.e. by `ci -l' and `co -l'. This is normally the default.
-
- -kkvl acts like -kkv, except that a locker's name is always inserted
- if the given revision is currently locked. This was the default in
- version 4. It is now the default only with when using rcsdiff to
- compare a revision to a working file whose mode is that of a file
- checked out for changes.
-
- -kk substitutes just `$Keyword$', which helps to ignore keyword values
- when comparing revisions.
-
- -ko retrieves the old revision's keyword string, thus bypassing keyword
- substitution.
-
- -kv retrieves just `value'. This can ease the use of keyword values, but
- it is dangerous because it causes RCS to lose track of where the keywords
- are, so for safety the owner write permission of the working file is
- turned off when -kv is used; to edit the file later, check it out again
- without -kv.
-
- rcs -ko sets the default keyword substitution to be in the style of co -ko,
- and similarly for the other -k options. This can be useful with file
- formats that cannot tolerate changing the lengths of keyword strings.
- However it also renders a RCS file readable only by RCS version 5 or later.
- Use rcs -kkv to restore the usual default substitution.
-
- RCS can now be used by development groups that span time zone boundaries.
- All times are now displayed in UTC, and UTC is the default time zone.
- To use local time with co -d, append ` LT' to the time.
- When interchanging RCS files with sites running older versions of RCS,
- time stamp discrepancies may prevent checkins; to work around this,
- use `ci -d' with a time slightly in the future.
-
- Dates are now displayed using four-digit years, not two-digit years.
- Years given in -d options must now have four digits.
- This change is required for RCS to continue to work after 1999/12/31.
- The form of dates in version 5 RCS files will not change until 2000/01/01,
- so in the meantime RCS files can still be interchanged with sites
- running older versions of RCS. To make room for the longer dates,
- rlog now outputs `lines: +A -D' instead of `lines added/del: A/D'.
-
- To help prevent diff programs that are broken or have run out of memory
- from trashing an RCS file, ci now checks diff output more carefully.
-
- ci -k now handles the Log keyword, so that checking in a file
- with -k does not normally alter the file's contents.
-
- RCS no longer outputs white space at the ends of lines
- unless the original working file had it.
- For consistency with other keywords,
- a space, not a tab, is now output after `$Log:'.
- Rlog now puts lockers and symbolic names on separate lines in the output
- to avoid generating lines that are too long.
- A similar fix has been made to lists in the RCS files themselves.
-
- RCS no longer outputs the string `Locker: ' when expanding Header or Id
- keywords. This saves space and reverts back to version 3 behavior.
-
- The default branch is not put into the RCS file unless it is nonempty.
- Therefore, files generated by RCS version 5 can be read by RCS version 3
- unless they use the default branch feature introduced in version 4.
- This fixes a compatibility problem introduced by version 4.
-
- RCS can now emulate older versions of RCS; see `co -V'.
- This may be useful to overcome compatibility problems
- due to the above changes.
-
- Programs like Emacs can now interact with RCS commands via a pipe:
- the new -I option causes ci, co, and rcs to run interactively,
- even if standard input is not a terminal.
- These commands now accept multiple inputs from stdin separated by `.' lines.
-
- ci now silently ignores the -t option if the RCS file already exists.
- This simplifies some shell scripts and improves security in setuid sites.
-
- Descriptive text may be given directly in an argument of the form -t-string.
-
- The character set for symbolic names has been upgraded
- from Ascii to ISO 8859.
-
- rcsdiff now passes through all options used by GNU diff;
- this is a longer list than 4.3BSD diff.
-
- merge's new -L option gives tags for merge's overlap report lines.
- This ability used to be present in a different, undocumented form;
- the new form is chosen for compatibility with GNU diff3's -L option.
-
- rcsmerge and merge now have a -q option, just like their siblings do.
-
- rcsclean's new -n option outputs what rcsclean would do,
- without actually doing it.
-
- RCS now attempts to ignore parts of an RCS file that look like they come
- from a future version of RCS.
-
- When properly configured, RCS now strictly conforms with Posix 1003.1-1990.
- RCS can still be compiled in non-Posix traditional Unix environments,
- and can use common BSD and USG extensions to Posix.
- RCS is a conforming Standard C program, and also compiles under traditional C.
-
- Arbitrary limits on internal table sizes have been removed.
- The only limit now is the amount of memory available via malloc().
-
- File temporaries, lock files, signals, and system call return codes
- are now handled more cleanly, portably, and quickly.
- Some race conditions have been removed.
-
- A new compile-time option RCSPREFIX lets administrators avoid absolute path
- names for subsidiary programs, trading speed for flexibility.
-
- The configuration procedure is now more automatic.
-
- Snooping has been removed.
-
-
-Version 4 was the first version distributed by FSF.
-Beside bug fixes, features new to RCS version 4 include:
-
- The notion of default branch has been added; see rcs -b.
-
-
-Version 3 was included in the 4.3BSD distribution.
-
-
-Here are some possible future changes for RCS:
-
- Bring back sccstorcs.
-
- Add an option to `rcsmerge' so that it can use an arbitrary program
- to do the 3-way merge, instead of the default `merge'.
- Likewise for `rcsdiff' and `diff'. It should be possible to pass
- arbitrary options to these programs, and to the subsidiary `co's.
-
- Add format options for finer control over the output of ident and rlog.
- E.g. there should be an easy way for rlog to output lines like
- `src/main.c 2.4 wft', one for each locked revision.
- rlog options should have three orthogonal types: selecting files,
- selecting revisions, and selecting rlog format.
-
- Add format options for finer control over the output of keyword strings.
- E.g. there should be some way to prepend @(#), and there should be some
- way to change $ to some other character to disable further substitution.
- These options should make the resulting files uneditable, like -kv.
-
- Add long options, e.g. `--version'. Unfortunately RCS's option syntax
- is incompatible with getopt. Perhaps the best way is to overload `rcs', e.g.
- `rcs diff --keyword-substitution=old file' instead of `rcsdiff -ko file'.
-
- Add a way to put only the interesting part of the path into the $Header
- keyword expansion.
-
- rlog -rM:N should work even if M and N have different numbers of fields,
- so long as M is an ancestor of N or vice versa.
-
- rcs should evaluate options in order; this allows rcs -oS -nS.
-
- rcs should be able to fix minor mistakes in checkin dates and authors.
-
- Be able to redo your most recent checkin with minor changes.
-
- co -u shouldn't complain about a writable working file if it won't change
- its contents.
-
- Configure the Makefile automatically, as well as conf.h.
-
- Add a new option to rcs that behaves like -o, but that doesn't lose the
- nonempty log messages, but instead merges them with the next revision
- if it exists, perhaps with a 1-line header containing author, date, etc.
-
- Add a `-' option to take the list of pathnames from standard input.
- Perhaps the pathnames should be null-terminated, not newline-terminated,
- so that pathnames that contain newlines are handled properly.
-
- Permit multiple option-pathname pairs, e.g. co -r1.4 a -r1.5 b.
-
- Add options to allow arbitrary combinations of working file names
- with RCS file names -- they shouldn't have to match.
-
- Add an option to break a symbolic link to an RCS file,
- instead of breaking the hard link that it points to.
-
- Add ways to specify the earliest revision, the most recent revision,
- the earliest or latest revision on a particular branch, and
- the parent or child of some other revision.
-
- If a user has multiple locks, perhaps ci should fall back on ci -k's
- method to figure out which revision to use.
-
- Symbolic names need not refer to existing branches and revisions.
- rcs(1)'s BUGS section says this is a bug. Is it? If so, it should be fixed.
-
- Add an option to rcs -o so that old log messages are not deleted if
- the next undeleted revision exists, but are merely appended to the log
- message of that revision.
-
- ci -k should be able to get keyword values from the first `$Log' entry.
-
- Add an option to rcsclean to clean directories recursively.
-
- Write an rcsck program that repairs corrupted RCS files,
- much as fsck repairs corrupted file systems.
- For example, it should remove stale lock files.
-
- Clean up the source code with a consistent indenting style.
-
- Update the date parser to use the more modern getdate.y by Bellovin,
- Salz, and Berets, or the even more modern getdate by Moraes. None of
- these getdate implementations are as robust as RCS's old warhorse in
- avoiding problems like arithmetic overflow, so they'll have to be
- fixed first.
-
- Break up the code into a library so that it's easier to write new programs
- that manipulate RCS files, and so that useless code is removed from the
- existing programs. For example, the rcs command contains unnecessary
- keyword substitution baggage, and the merge command can be greatly pruned.
-
- Make it easier to use your favorite text editor to edit log messages,
- etc. instead of having to type them in irretrievably at the terminal.
-
- Let the user specify a search path for default branches,
- e.g. to use L as the default branch if it works, and M otherwise.
- Let the user require that at least one entry in the default branch path works.
- Let the user say that later entries in the default branch path are read only,
- i.e. one cannot check in changes to them.
- This should be an option settable by RCSINIT.
-
- Add a way for a user to see which revisions affected which lines.
-
- Have `rlog -nN F' print just the revision number that N translates to.
- E.g. `rlog -nB. F' would print the highest revision on the branch B.
- Use this to add an option -bB to rcsbranch, to freeze the named branch.
- This should interact well with default branches.
-
- Add a co option that prints the revision number before each line,
- as SCCS's `get -m' does.
-
-The following projects require a change to RCS file format.
-
- Allow keyword expansion to be changed on a per-revision basis,
- not on a per-file basis as now. This would allow -ko to be used
- on imported revisions, with the default -kkv otherwise.
-
- When two or more branches are merged, record all the ancestors
- of the new revision. The hard part of this is keeping track of all
- the ancestors of a working file while it's checked out.
-
- Add loose locking, which is like non-strict but applies to all users,
- not just the owner of the RCS file.
-
- Be able to store RCS files in compressed format.
- Don't bother to use a .Z extension that would exceed file name length limits;
- just look at the magic number.
-
- Add locker commentary, e.g. `co -l -m"checkout to fix merge bug" foo'
- to tell others why you checked out `foo'.
- Also record the time when the revision was locked,
- and perhaps the working pathname (if applicable).
-
- Let the user mark an RCS revision as deleted; checking out such a revision
- would result in no working file. Similarly, using `co -d' with a date either
- before the initial revision or after the file was marked deleted should
- remove the working file. For extra credit, extend the notion of `deleted' to
- include `renamed'. RCS should support arbitrary combinations of renaming and
- deletion, e.g. renaming A to B and B to A, checking in new revisions to both
- files, and then renaming them back.
-
- Be able to check in an entire directory structure into a single RCS file.
-
- Use a better scheme for locking revisions; the current scheme requires
- changing the RCS file just to lock or unlock a revision.
- The new scheme should coexist as well as possible with older versions of RCS,
- and should avoid the rare NFS bugs mentioned in rcsedit.c.
- E.g. if there's a reliable lockd running, RCS should use it
- instead of relying on NFS.
-
- Add rcs options for changing keyword names, e.g. XConsortium instead of Id.
-
- Add a `$Description' keyword; but this may be tricky, since descriptions can
- contain newlines and $s.
-
- Add a `$Copyright' keyword that expands to a copyright notice.
-
- Add frozen branches a la SCCS. In general, be able to emulate all of
- SCCS, so that an SCCS-to-RCS program can be practical. For example,
- there should be an equivalent to the SCCS prt command.
-
- Add support for distributed RCS, where widely separated
- users cannot easily access each others' RCS files,
- and must periodically distribute and reconcile new revisions.
-
- Be able to create empty branches.
-
- Be able to store just deltas from a read-only principal copy,
- e.g. from source on CD-ROM.
-
- Improve RCS's method for storing binary files.
- Although it is more efficient than SCCS's,
- the diff algorithm is still line oriented,
- and often generates long output for minor changes to an executable file.
-
- From the user's point of view, it would be best if
- RCS detected and handled binary files without human intervention,
- switching expansion methods as needed from revision to revision.
-
- Allow RCS to determine automagically whether -ko or -kb should be the default
- by inspecting the file's contents or name. The magic should be optional
- and user-programmable.
-
- Extend the grammar of RCS files so that keywords need not be in a fixed order.
-
- Internationalize messages; unfortunately, there's no common standard yet.
- This requires a change in RCS file format because of the
- `empty log message' and `checked in with -k' hacks inside RCS files.
-
- Add documentation in texinfo format.
diff --git a/gnu/usr.bin/rcs/REFS b/gnu/usr.bin/rcs/REFS
deleted file mode 100644
index 89fc823..0000000
--- a/gnu/usr.bin/rcs/REFS
+++ /dev/null
@@ -1,90 +0,0 @@
-Here are references to RCS and related free software and documentation.
-Some of this information changes often; see the Frequently Asked Questions
-for more up-to-date references.
-
- $FreeBSD$
-
-
-Frequently Asked Questions (FAQs)
-
-<http://www.qucis.queensu.ca/Software-Engineering/>
-<ftp://rtfm.mit.edu//pub/usenet-by-hierarchy/comp/software-eng/>
- for software engineering; e.g. see
- <http://www.qucis.queensu.ca/Software-Engineering/blurb/rcs>.
-
-<http://www.iac.honeywell.com/Pub/Tech/CM/CMFAQ.html>
-<ftp://rtfm.mit.edu//pub/usenet-by-hierarchy/comp/software/config-mgmt/>
- for configuration management
-
-<http://www.winternet.com/~zoo/cvs/FAQ.txt>
-<ftp://ftp.odi.com/pub/users/dgg/FAQ.gz>
- for CVS (see below)
-
-
-RCS and related GNU project software
-
-<ftp://ftp.cs.purdue.edu/pub/RCS/>
- The RCS project distribution directory also contains beta versions,
- ports, and prebuilt documentation.
-
-<ftp://prep.ai.mit.edu/pub/gnu/>
- The GNU project distribution directory contains:
- diffutils-N-tar.gz
- the latest diffutils release; recommended for RCS
- emacs-N-tar.gz
- The latest Emacs release contains VC, a version-control package
- that makes RCS easier to use.
- make-N-tar.gz
- GNU Make, which can automatically build from RCS files.
- rcs-N-tar.gz
- the latest RCS release
- cvs-N-tar.gz
- the latest official CVS release (see below)
-
-<ftp://ftp.leo.org/pub/comp/os/os2/gnu/devtools/> DOS, OS/2 ports
-<ftp://ftp.cc.utexas.edu/microlib/nt/gnu/> NT port
-
-
-CVS
-
-CVS, the Concurrent Versions System, keeps tracks of source changes
-made by groups of developers working on the same files concurrently,
-allowing them to resync as needed.
-
-<http://www.winternet.com/~zoo/cvs/>
-<http://www.loria.fr/~molli/cvs-index.html>
- These pages have useful information about CVS.
-
-<ftp://prep.ai.mit.edu/pub/gnu/cvs-1.3.tar.gz>
- CVS 1.3 is the latest released version.
-
-<ftp://ftp.delos.com/pub/cvs/alpha/cvs-1.4A2.tar.gz>
- CVS 1.4 is in alpha test, but it is recommended if you are installing CVS
- for the first time, or on a recent operating system.
-
-<ftp://ftp-os2.cdrom.com/pub/os2/unix/> DOS, OS/2 ports
-<ftp://ftp.cc.utexas.edu/microlib/nt/gnu/> NT port
-
-<ftp://ftp.cyclic.com/pub/cvs/>
- Cyclic CVS adds network transparency to CVS; it supports efficient,
- reliable, and authenticated repository access via TCP/IP.
-
-
-Other software that uses RCS
-
-<ftp://ftp.nau.edu/pub/Aegis/>
- Aegis manages revisions, baselines, mandatory reviews, and mandatory testing.
-
-<ftp://ftp.vix.com/pub/patches/csu/>
- BCS, the Baseline Configuration System,
- manages revisions, baselines, and staging areas.
-
-<ftp://riftp.osf.org/pub/ode/>
- ODE, the Open Software Foundation Development Environment,
- manages revisions, builds, and sandboxes.
- OSF uses it for their own development.
-
-<ftp://bellcore.com/pub/Odin/>
- Odin, a `make' replacement, can build directly from arbitrary revisions
- without requiring checkouts of working copies. It also handles
- parallel builds on multiple remote hosts and of multiple variants.
diff --git a/gnu/usr.bin/rcs/ci/Makefile b/gnu/usr.bin/rcs/ci/Makefile
deleted file mode 100644
index 2fbb74f..0000000
--- a/gnu/usr.bin/rcs/ci/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG= ci
-SRCS= ci.c
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/ci/ci.1 b/gnu/usr.bin/rcs/ci/ci.1
deleted file mode 100644
index 1378af2..0000000
--- a/gnu/usr.bin/rcs/ci/ci.1
+++ /dev/null
@@ -1,898 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds i \&\s-1ISO\s0
-.ds r \&\s-1RCS\s0
-.ds u \&\s-1UTC\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.TH CI 1 \*(Dt GNU
-.SH NAME
-ci \- check in RCS revisions
-.SH SYNOPSIS
-.B ci
-.RI [ options ] " file " .\|.\|.
-.SH DESCRIPTION
-.B ci
-stores new revisions into \*r files.
-Each pathname matching an \*r suffix
-is taken to be an \*r file.
-All others
-are assumed to be working files containing new revisions.
-.B ci
-deposits the contents of each working file
-into the corresponding \*r file.
-If only a working file is given,
-.B ci
-tries to find the corresponding \*r file in an \*r subdirectory
-and then in the working file's directory.
-For more details, see
-.SM "FILE NAMING"
-below.
-.PP
-For
-.B ci
-to work, the caller's login must be on the access list,
-except if the access list is empty or the caller is the superuser or the
-owner of the file.
-To append a new revision to an existing branch, the tip revision on
-that branch must be locked by the caller. Otherwise, only a
-new branch can be created. This restriction is not enforced
-for the owner of the file if non-strict locking is used
-(see
-.BR rcs (1)).
-A lock held by someone else can be broken with the
-.B rcs
-command.
-.PP
-Unless the
-.B \-f
-option is given,
-.B ci
-checks whether the revision to be deposited differs from the preceding one.
-If not, instead of creating a new revision
-.B ci
-reverts to the preceding one.
-To revert, ordinary
-.B ci
-removes the working file and any lock;
-.B "ci\ \-l"
-keeps and
-.B "ci\ \-u"
-removes any lock, and then they both generate a new working file much as if
-.B "co\ \-l"
-or
-.B "co\ \-u"
-had been applied to the preceding revision.
-When reverting, any
-.B \-n
-and
-.B \-s
-options apply to the preceding revision.
-.PP
-For each revision deposited,
-.B ci
-prompts for a log message.
-The log message should summarize the change and must be terminated by
-end-of-file or by a line containing
-.BR \&. "\ by"
-itself.
-If several files are checked in
-.B ci
-asks whether to reuse the
-previous log message.
-If the standard input is not a terminal,
-.B ci
-suppresses the prompt
-and uses the same log message for all files.
-See also
-.BR \-m .
-.PP
-If the \*r file does not exist,
-.B ci
-creates it and
-deposits the contents of the working file as the initial revision
-(default number:
-.BR 1.1 ).
-The access list is initialized to empty.
-Instead of the log message,
-.B ci
-requests descriptive text (see
-.B \-t
-below).
-.PP
-The number
-.I rev
-of the deposited revision can be given by any of the options
-.BR \-f ,
-.BR \-i ,
-.BR \-I ,
-.BR \-j ,
-.BR \-k ,
-.BR \-l ,
-.BR \-M ,
-.BR \-q ,
-.BR \-r ,
-or
-.BR \-u .
-.I rev
-can be symbolic, numeric, or mixed.
-Symbolic names in
-.I rev
-must already be defined;
-see the
-.B \-n
-and
-.B \-N
-options for assigning names during checkin.
-If
-.I rev
-is
-.BR $ ,
-.B ci
-determines the revision number from keyword values in the working file.
-.PP
-If
-.I rev
-begins with a period,
-then the default branch (normally the trunk) is prepended to it.
-If
-.I rev
-is a branch number followed by a period,
-then the latest revision on that branch is used.
-.PP
-If
-.I rev
-is a revision number, it must be higher than the latest
-one on the branch to which
-.I rev
-belongs, or must start a new branch.
-.PP
-If
-.I rev
-is a branch rather than a revision number,
-the new revision is appended to that branch. The level number is obtained
-by incrementing the tip revision number of that branch.
-If
-.I rev
-indicates a non-existing branch,
-that branch is created with the initial revision numbered
-.IB rev .1\f1.\fP
-.br
-.ne 8
-.PP
-If
-.I rev
-is omitted,
-.B ci
-tries to derive the new revision number from
-the caller's last lock. If the caller has locked the tip revision of a branch,
-the new revision is appended to that branch.
-The new revision number is obtained
-by incrementing the tip revision number.
-If the caller locked a non-tip revision, a new branch is started at
-that revision by incrementing the highest branch number at that revision.
-The default initial branch and level numbers are
-.BR 1 .
-.PP
-If
-.I rev
-is omitted and the caller has no lock, but owns
-the file and locking
-is not set to
-.IR strict ,
-then the revision is appended to the
-default branch (normally the trunk; see the
-.B \-b
-option of
-.BR rcs (1)).
-.PP
-Exception: On the trunk, revisions can be appended to the end, but
-not inserted.
-.SH OPTIONS
-.TP
-.BI \-r rev
-Check in revision
-.IR rev .
-.TP
-.BR \-r
-The bare
-.B \-r
-option (without any revision) has an unusual meaning in
-.BR ci .
-With other \*r commands, a bare
-.B \-r
-option specifies the most recent revision on the default branch,
-but with
-.BR ci ,
-a bare
-.B \-r
-option reestablishes the default behavior of releasing a lock and
-removing the working file, and is used to override any default
-.B \-l
-or
-.B \-u
-options established by shell aliases or scripts.
-.TP
-.BR \-l [\f2rev\fP]
-works like
-.BR \-r ,
-except it performs an additional
-.B "co\ \-l"
-for the
-deposited revision. Thus, the deposited revision is immediately
-checked out again and locked.
-This is useful for saving a revision although one wants to continue
-editing it after the checkin.
-.TP
-.BR \-u [\f2rev\fP]
-works like
-.BR \-l ,
-except that the deposited revision is not locked.
-This lets one read the working file
-immediately after checkin.
-.RS
-.PP
-The
-.BR \-l ,
-bare
-.BR \-r ,
-and
-.B \-u
-options are mutually exclusive and silently override each other.
-For example,
-.B "ci\ \-u\ \-r"
-is equivalent to
-.B "ci\ \-r"
-because bare
-.B \-r
-overrides
-.BR \-u .
-.RE
-.TP
-.BR \-f [\f2rev\fP]
-forces a deposit; the new revision is deposited even it is not different
-from the preceding one.
-.TP
-.BR \-k [\f2rev\fP]
-searches the working file for keyword values to determine its revision number,
-creation date, state, and author (see
-.BR co (1)),
-and assigns these
-values to the deposited revision, rather than computing them locally.
-It also generates a default login message noting the login of the caller
-and the actual checkin date.
-This option is useful for software distribution. A revision that is sent to
-several sites should be checked in with the
-.B \-k
-option at these sites to
-preserve the original number, date, author, and state.
-The extracted keyword values and the default log message can be overridden
-with the options
-.BR \-d ,
-.BR \-m ,
-.BR \-s ,
-.BR \-w ,
-and any option that carries a revision number.
-.TP
-.BR \-q [\f2rev\fP]
-quiet mode; diagnostic output is not printed.
-A revision that is not different from the preceding one is not deposited,
-unless
-.B \-f
-is given.
-.TP
-.BR \-i [\f2rev\fP]
-initial checkin; report an error if the \*r file already exists.
-This avoids race conditions in certain applications.
-.TP
-.BR \-j [\f2rev\fP]
-just checkin and do not initialize;
-report an error if the \*r file does not already exist.
-.TP
-.BR \-I [\f2rev\fP]
-interactive mode;
-the user is prompted and questioned
-even if the standard input is not a terminal.
-.TP
-.BR \-d "[\f2date\fP]"
-uses
-.I date
-for the checkin date and time.
-The
-.I date
-is specified in free format as explained in
-.BR co (1).
-This is useful for lying about the checkin date, and for
-.B \-k
-if no date is available.
-If
-.I date
-is empty, the working file's time of last modification is used.
-.TP
-.BR \-M [\f2rev\fP]
-Set the modification time on any new working file
-to be the date of the retrieved revision.
-For example,
-.BI "ci\ \-d\ \-M\ \-u" "\ f"
-does not alter
-.IR f 's
-modification time, even if
-.IR f 's
-contents change due to keyword substitution.
-Use this option with care; it can confuse
-.BR make (1).
-.TP
-.BI \-m "msg"
-uses the string
-.I msg
-as the log message for all revisions checked in.
-By convention, log messages that start with
-.B #
-are comments and are ignored by programs like GNU Emacs's
-.B vc
-package.
-Also, log messages that start with
-.BI { clumpname }
-(followed by white space) are meant to be clumped together if possible,
-even if they are associated with different files; the
-.BI { clumpname }
-label is used only for clumping,
-and is not considered to be part of the log message itself.
-.TP
-.BI \-n "name"
-assigns the symbolic name
-.I name
-to the number of the checked-in revision.
-.B ci
-prints an error message if
-.I name
-is already assigned to another
-number.
-.TP
-.BI \-N "name"
-same as
-.BR \-n ,
-except that it overrides a previous assignment of
-.IR name .
-.TP
-.BI \-s "state"
-sets the state of the checked-in revision to the identifier
-.IR state .
-The default state is
-.BR Exp .
-.TP
-.BI \-t file
-writes descriptive text from the contents of the named
-.I file
-into the \*r file,
-deleting the existing text.
-The
-.I file
-cannot begin with
-.BR \- .
-.TP
-.BI \-t\- string
-Write descriptive text from the
-.I string
-into the \*r file, deleting the existing text.
-.RS
-.PP
-The
-.B \-t
-option, in both its forms, has effect only during an initial checkin;
-it is silently ignored otherwise.
-.PP
-During the initial checkin, if
-.B \-t
-is not given,
-.B ci
-obtains the text from standard input,
-terminated by end-of-file or by a line containing
-.BR \&. "\ by"
-itself.
-The user is prompted for the text if interaction is possible; see
-.BR \-I .
-.PP
-For backward compatibility with older versions of \*r, a bare
-.B \-t
-option is ignored.
-.RE
-.TP
-.B \-T
-Set the \*r file's modification time to the new revision's time
-if the former precedes the latter and there is a new revision;
-preserve the \*r file's modification time otherwise.
-If you have locked a revision,
-.B ci
-usually updates the \*r file's modification time to the current time,
-because the lock is stored in the \*r file
-and removing the lock requires changing the \*r file.
-This can create an \*r file newer than the working file in one of two ways:
-first,
-.B "ci\ \-M"
-can create a working file with a date before the current time;
-second, when reverting to the previous revision
-the \*r file can change while the working file remains unchanged.
-These two cases can cause excessive recompilation caused by a
-.BR make (1)
-dependency of the working file on the \*r file.
-The
-.B \-T
-option inhibits this recompilation by lying about the \*r file's date.
-Use this option with care; it can suppress recompilation even when
-a checkin of one working file should affect
-another working file associated with the same \*r file.
-For example, suppose the \*r file's time is 01:00,
-the (changed) working file's time is 02:00,
-some other copy of the working file has a time of 03:00,
-and the current time is 04:00.
-Then
-.B "ci\ \-d\ \-T"
-sets the \*r file's time to 02:00 instead of the usual 04:00;
-this causes
-.BR make (1)
-to think (incorrectly) that the other copy is newer than the \*r file.
-.TP
-.BI \-w "login"
-uses
-.I login
-for the author field of the deposited revision.
-Useful for lying about the author, and for
-.B \-k
-if no author is available.
-.TP
-.BI \-V
-Print \*r's version number.
-.TP
-.BI \-V n
-Emulate \*r version
-.IR n .
-See
-.BR co (1)
-for details.
-.TP
-.BI \-x "suffixes"
-specifies the suffixes for \*r files.
-A nonempty suffix matches any pathname ending in the suffix.
-An empty suffix matches any pathname of the form
-.BI RCS/ path
-or
-.IB path1 /RCS/ path2.
-The
-.B \-x
-option can specify a list of suffixes
-separated by
-.BR / .
-For example,
-.B \-x,v/
-specifies two suffixes:
-.B ,v
-and the empty suffix.
-If two or more suffixes are specified,
-they are tried in order when looking for an \*r file;
-the first one that works is used for that file.
-If no \*r file is found but an \*r file can be created,
-the suffixes are tried in order
-to determine the new \*r file's name.
-The default for
-.IR suffixes
-is installation-dependent; normally it is
-.B ,v/
-for hosts like Unix that permit commas in filenames,
-and is empty (i.e. just the empty suffix) for other hosts.
-.TP
-.BI \-z zone
-specifies the date output format in keyword substitution,
-and specifies the default time zone for
-.I date
-in the
-.BI \-d date
-option.
-The
-.I zone
-should be empty, a numeric \*u offset, or the special string
-.B LT
-for local time.
-The default is an empty
-.IR zone ,
-which uses the traditional \*r format of \*u without any time zone indication
-and with slashes separating the parts of the date;
-otherwise, times are output in \*i 8601 format with time zone indication.
-For example, if local time is January 11, 1990, 8pm Pacific Standard Time,
-eight hours west of \*u,
-then the time is output as follows:
-.RS
-.LP
-.RS
-.nf
-.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u
-.ne 4
-\f2option\fP \f2time output\fP
-\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP
-\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP
-\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP
-.ta 4n +4n +4n +4n
-.fi
-.RE
-.LP
-The
-.B \-z
-option does not affect dates stored in \*r files,
-which are always \*u.
-.SH "FILE NAMING"
-Pairs of \*r files and working files can be specified in three ways
-(see also the
-example section).
-.PP
-1) Both the \*r file and the working file are given. The \*r pathname is of
-the form
-.IB path1 / workfileX
-and the working pathname is of the form
-.IB path2 / workfile
-where
-.IB path1 /
-and
-.IB path2 /
-are (possibly different or empty) paths,
-.I workfile
-is a filename, and
-.I X
-is an \*r suffix.
-If
-.I X
-is empty,
-.IB path1 /
-must start with
-.B RCS/
-or must contain
-.BR /RCS/ .
-.PP
-2) Only the \*r file is given. Then the working file is created in the current
-directory and its name is derived from the name of the \*r file
-by removing
-.IB path1 /
-and the suffix
-.IR X .
-.PP
-3) Only the working file is given.
-Then
-.B ci
-considers each \*r suffix
-.I X
-in turn, looking for an \*r file of the form
-.IB path2 /RCS/ workfileX
-or (if the former is not found and
-.I X
-is nonempty)
-.IB path2 / workfileX.
-.PP
-If the \*r file is specified without a path in 1) and 2),
-.B ci
-looks for the \*r file first in the directory
-.B ./RCS
-and then in the current
-directory.
-.PP
-.B ci
-reports an error if an attempt to open an \*r file fails for an unusual reason,
-even if the \*r file's pathname is just one of several possibilities.
-For example, to suppress use of \*r commands in a directory
-.IR d ,
-create a regular file named
-.IB d /RCS
-so that casual attempts to use \*r commands in
-.I d
-fail because
-.IB d /RCS
-is not a directory.
-.SH EXAMPLES
-Suppose
-.B ,v
-is an \*r suffix and the current directory contains a subdirectory
-.B RCS
-with an \*r file
-.BR io.c,v .
-Then each of the following commands check in a copy of
-.B io.c
-into
-.B RCS/io.c,v
-as the latest revision, removing
-.BR io.c .
-.LP
-.RS
-.nf
-.ft 3
-ci io.c; ci RCS/io.c,v; ci io.c,v;
-ci io.c RCS/io.c,v; ci io.c io.c,v;
-ci RCS/io.c,v io.c; ci io.c,v io.c;
-.ft
-.fi
-.RE
-.PP
-Suppose instead that the empty suffix
-is an \*r suffix and the current directory contains a subdirectory
-.B RCS
-with an \*r file
-.BR io.c .
-The each of the following commands checks in a new revision.
-.LP
-.RS
-.nf
-.ft 3
-ci io.c; ci RCS/io.c;
-ci io.c RCS/io.c;
-ci RCS/io.c io.c;
-.ft
-.fi
-.RE
-.SH "FILE MODES"
-An \*r file created by
-.B ci
-inherits the read and execute permissions
-from the working file. If the \*r file exists already,
-.B ci
-preserves its read and execute permissions.
-.B ci
-always turns off all write permissions of \*r files.
-.SH FILES
-Temporary files are created in the directory containing
-the working file, and also in the temporary directory (see
-.B \s-1TMPDIR\s0
-under
-.BR \s-1ENVIRONMENT\s0 ).
-A semaphore file or files are created in the directory containing the \*r file.
-With a nonempty suffix, the semaphore names begin with
-the first character of the suffix; therefore, do not specify an suffix
-whose first character could be that of a working filename.
-With an empty suffix, the semaphore names end with
-.B _
-so working filenames should not end in
-.BR _ .
-.PP
-.B ci
-never changes an \*r or working file.
-Normally,
-.B ci
-unlinks the file and creates a new one;
-but instead of breaking a chain of one or more symbolic links to an \*r file,
-it unlinks the destination file instead.
-Therefore,
-.B ci
-breaks any hard or symbolic links to any working file it changes;
-and hard links to \*r files are ineffective,
-but symbolic links to \*r files are preserved.
-.PP
-The effective user must be able to
-search and write the directory containing the \*r file.
-Normally, the real user must be able to
-read the \*r and working files
-and to search and write the directory containing the working file;
-however, some older hosts
-cannot easily switch between real and effective users,
-so on these hosts the effective user is used for all accesses.
-The effective user is the same as the real user
-unless your copies of
-.B ci
-and
-.B co
-have setuid privileges.
-As described in the next section,
-these privileges yield extra security if
-the effective user owns all \*r files and directories,
-and if only the effective user can write \*r directories.
-.PP
-Users can control access to \*r files by setting the permissions
-of the directory containing the files; only users with write access
-to the directory can use \*r commands to change its \*r files.
-For example, in hosts that allow a user to belong to several groups,
-one can make a group's \*r directories writable to that group only.
-This approach suffices for informal projects,
-but it means that any group member can arbitrarily change the group's \*r files,
-and can even remove them entirely.
-Hence more formal projects sometimes distinguish between an \*r administrator,
-who can change the \*r files at will, and other project members,
-who can check in new revisions but cannot otherwise change the \*r files.
-.SH "SETUID USE"
-To prevent anybody but their \*r administrator from deleting revisions,
-a set of users can employ setuid privileges as follows.
-.nr n \w'\(bu'+2n-1/1n
-.ds n \nn
-.if \n(.g .if r an-tag-sep .ds n \w'\(bu'u+\n[an-tag-sep]u
-.IP \(bu \*n
-Check that the host supports \*r setuid use.
-Consult a trustworthy expert if there are any doubts.
-It is best if the
-.B seteuid
-system call works as described in Posix 1003.1a Draft 5,
-because \*r can switch back and forth easily
-between real and effective users, even if the real user is
-.BR root .
-If not, the second best is if the
-.B setuid
-system call supports saved setuid
-(the {\s-1_POSIX_SAVED_IDS\s0} behavior of Posix 1003.1-1990);
-this fails only if the real or effective user is
-.BR root .
-If \*r detects any failure in setuid, it quits immediately.
-.IP \(bu \nn
-Choose a user
-.I A
-to serve as \*r administrator for the set of users.
-Only
-.I A
-can invoke the
-.B rcs
-command on the users' \*r files.
-.I A
-should not be
-.B root
-or any other user with special powers.
-Mutually suspicious sets of users should use different administrators.
-.IP \(bu \nn
-Choose a pathname
-.I B
-to be a directory of files to be executed by the users.
-.IP \(bu \nn
-Have
-.I A
-set up
-.I B
-to contain copies of
-.B ci
-and
-.B co
-that are setuid to
-.I A
-by copying the commands from their standard installation directory
-.I D
-as follows:
-.LP
-.RS
-.nf
-.ne 3
-\f3mkdir\fP \f2B\fP
-\f3cp\fP \f2D\fP\^\f3/c[io]\fP \f2B\fP
-\f3chmod go\-w,u+s\fP \f2B\fP\f3/c[io]\fP
-.fi
-.RE
-.IP \(bu \nn
-Have each user prepend
-.I B
-to their path as follows:
-.LP
-.RS
-.nf
-.ne 2
-\f3PATH=\fP\f2B\fP\f3:$PATH; export PATH\fP # ordinary shell
-\f3set path=(\fP\f2B\fP \f3$path)\fP # C shell
-.fi
-.RE
-.IP \(bu \nn
-Have
-.I A
-create each \*r directory
-.I R
-with write access only to
-.I A
-as follows:
-.LP
-.RS
-.nf
-.ne 2
-\f3mkdir\fP \f2R\fP
-\f3chmod go\-w\fP \f2R\fP
-.fi
-.RE
-.IP \(bu \nn
-If you want to let only certain users read the \*r files,
-put the users into a group
-.IR G ,
-and have
-.I A
-further protect the \*r directory as follows:
-.LP
-.RS
-.nf
-.ne 2
-\f3chgrp\fP \f2G R\fP
-\f3chmod g\-w,o\-rwx\fP \f2R\fP
-.fi
-.RE
-.IP \(bu \nn
-Have
-.I A
-copy old \*r files (if any) into
-.IR R ,
-to ensure that
-.I A
-owns them.
-.IP \(bu \nn
-An \*r file's access list limits who can check in and lock revisions.
-The default access list is empty,
-which grants checkin access to anyone who can read the \*r file.
-If you want limit checkin access,
-have
-.I A
-invoke
-.B "rcs\ \-a"
-on the file; see
-.BR rcs (1).
-In particular,
-.BI "rcs\ \-e\ \-a" A
-limits access to just
-.IR A .
-.IP \(bu \nn
-Have
-.I A
-initialize any new \*r files with
-.B "rcs\ \-i"
-before initial checkin, adding the
-.B \-a
-option if you want to limit checkin access.
-.IP \(bu \nn
-Give setuid privileges only to
-.BR ci ,
-.BR co ,
-and
-.BR rcsclean ;
-do not give them to
-.B rcs
-or to any other command.
-.IP \(bu \nn
-Do not use other setuid commands to invoke \*r commands;
-setuid is trickier than you think!
-.SH ENVIRONMENT
-.TP
-.B \s-1RCSINIT\s0
-options prepended to the argument list, separated by spaces.
-A backslash escapes spaces within an option.
-The
-.B \s-1RCSINIT\s0
-options are prepended to the argument lists of most \*r commands.
-Useful
-.B \s-1RCSINIT\s0
-options include
-.BR \-q ,
-.BR \-V ,
-.BR \-x ,
-and
-.BR \-z .
-.TP
-.B \s-1TMPDIR\s0
-Name of the temporary directory.
-If not set, the environment variables
-.B \s-1TMP\s0
-and
-.B \s-1TEMP\s0
-are inspected instead and the first value found is taken;
-if none of them are set,
-a host-dependent default is used, typically
-.BR /tmp .
-.SH DIAGNOSTICS
-For each revision,
-.B ci
-prints the \*r file, the working file, and the number
-of both the deposited and the preceding revision.
-The exit status is zero if and only if all operations were successful.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
-.SH "SEE ALSO"
-co(1),
-ident(1), make(1), rcs(1), rcsclean(1), rcsdiff(1),
-rcsintro(1), rcsmerge(1), rlog(1), setuid(2), rcsfile(5)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.br
diff --git a/gnu/usr.bin/rcs/ci/ci.c b/gnu/usr.bin/rcs/ci/ci.c
deleted file mode 100644
index 749a4cf..0000000
--- a/gnu/usr.bin/rcs/ci/ci.c
+++ /dev/null
@@ -1,1318 +0,0 @@
-/* Check in revisions of RCS files from working files. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.30 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.29 1995/06/01 16:23:43 eggert
- * (main): Add -kb.
- * Use `cmpdate', not `cmpnum', to compare dates.
- * This is for MKS RCS's incompatible 20th-century date format.
- * Don't worry about errno after ftruncate fails.
- * Fix input file rewinding bug when large_memory && !maps_memory
- * and checking in a branch tip.
- *
- * (fixwork): Fall back on chmod if fchmod fails, since it might be ENOSYS.
- *
- * Revision 5.28 1994/03/20 04:52:58 eggert
- * Do not generate a corrupted RCS file if the user modifies the working file
- * while `ci' is running.
- * Do not remove the lock when `ci -l' reverts.
- * Move buffer-flushes out of critical sections, since they aren't critical.
- * Use ORCSerror to clean up after a fatal error.
- * Specify subprocess input via file descriptor, not file name.
- *
- * Revision 5.27 1993/11/09 17:40:15 eggert
- * -V now prints version on stdout and exits. Don't print usage twice.
- *
- * Revision 5.26 1993/11/03 17:42:27 eggert
- * Add -z. Don't subtract from RCS file timestamp even if -T.
- * Scan for and use Name keyword if -k.
- * Don't discard ignored phrases. Improve quality of diagnostics.
- *
- * Revision 5.25 1992/07/28 16:12:44 eggert
- * Add -i, -j, -V. Check that working and RCS files are distinct.
- *
- * Revision 5.24 1992/02/17 23:02:06 eggert
- * `-rREV' now just specifies a revision REV; only bare `-r' reverts to default.
- * Add -T.
- *
- * Revision 5.23 1992/01/27 16:42:51 eggert
- * Always unlock branchpoint if caller has a lock.
- * Add support for bad_chmod_close, bad_creat0. lint -> RCS_lint
- *
- * Revision 5.22 1992/01/06 02:42:34 eggert
- * Invoke utime() before chmod() to keep some buggy systems happy.
- *
- * Revision 5.21 1991/11/20 17:58:07 eggert
- * Don't read the delta tree from a nonexistent RCS file.
- *
- * Revision 5.20 1991/10/07 17:32:46 eggert
- * Fix log bugs. Remove lint.
- *
- * Revision 5.19 1991/09/26 23:10:30 eggert
- * Plug file descriptor leak.
- *
- * Revision 5.18 1991/09/18 07:29:10 eggert
- * Work around a common ftruncate() bug.
- *
- * Revision 5.17 1991/09/10 22:15:46 eggert
- * Fix test for redirected stdin.
- *
- * Revision 5.16 1991/08/19 23:17:54 eggert
- * When there are no changes, revert to previous revision instead of aborting.
- * Add piece tables, -M, -r$. Tune.
- *
- * Revision 5.15 1991/04/21 11:58:14 eggert
- * Ensure that working file is newer than RCS file after ci -[lu].
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.14 1991/02/28 19:18:47 eggert
- * Don't let a setuid ci create a new RCS file; rcs -i -a must be run first.
- * Fix ci -ko -l mode bug. Open work file at most once.
- *
- * Revision 5.13 1991/02/25 07:12:33 eggert
- * getdate -> getcurdate (SVR4 name clash)
- *
- * Revision 5.12 1990/12/31 01:00:12 eggert
- * Don't use uninitialized storage when handling -{N,n}.
- *
- * Revision 5.11 1990/12/04 05:18:36 eggert
- * Use -I for prompts and -q for diagnostics.
- *
- * Revision 5.10 1990/11/05 20:30:10 eggert
- * Don't remove working file when aborting due to no changes.
- *
- * Revision 5.9 1990/11/01 05:03:23 eggert
- * Add -I and new -t behavior. Permit arbitrary data in logs.
- *
- * Revision 5.8 1990/10/04 06:30:09 eggert
- * Accumulate exit status across files.
- *
- * Revision 5.7 1990/09/25 20:11:46 hammer
- * fixed another small typo
- *
- * Revision 5.6 1990/09/24 21:48:50 hammer
- * added cleanups from Paul Eggert.
- *
- * Revision 5.5 1990/09/21 06:16:38 hammer
- * made it handle multiple -{N,n}'s. Also, made it treat re-directed stdin
- * the same as the terminal
- *
- * Revision 5.4 1990/09/20 02:38:51 eggert
- * ci -k now checks dates more thoroughly.
- *
- * Revision 5.3 1990/09/11 02:41:07 eggert
- * Fix revision bug with `ci -k file1 file2'.
- *
- * Revision 5.2 1990/09/04 08:02:10 eggert
- * Permit adjacent revisions with identical time stamps (possible on fast hosts).
- * Improve incomplete line handling. Standardize yes-or-no procedure.
- *
- * Revision 5.1 1990/08/29 07:13:44 eggert
- * Expand locker value like co. Clean old log messages too.
- *
- * Revision 5.0 1990/08/22 08:10:00 eggert
- * Don't require a final newline.
- * Make lock and temp files faster and safer.
- * Remove compile-time limits; use malloc instead.
- * Permit dates past 1999/12/31. Switch to GMT.
- * Add setuid support. Don't pass +args to diff. Check diff's output.
- * Ansify and Posixate. Add -k, -V. Remove snooping. Tune.
- * Check diff's output.
- *
- * Revision 4.9 89/05/01 15:10:54 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.8 88/11/08 13:38:23 narten
- * changes from root@seismo.CSS.GOV (Super User)
- * -d with no arguments uses the mod time of the file it is checking in
- *
- * Revision 4.7 88/08/09 19:12:07 eggert
- * Make sure workfile is a regular file; use its mode if RCSfile doesn't have one.
- * Use execv(), not system(); allow cc -R; remove lint.
- * isatty(fileno(stdin)) -> ttystdin()
- *
- * Revision 4.6 87/12/18 11:34:41 narten
- * lint cleanups (from Guy Harris)
- *
- * Revision 4.5 87/10/18 10:18:48 narten
- * Updating version numbers. Changes relative to revision 1.1 are actually
- * relative to 4.3
- *
- * Revision 1.3 87/09/24 13:57:19 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:21:33 jenkins
- * Port to suns
- *
- * Revision 4.3 83/12/15 12:28:54 wft
- * ci -u and ci -l now set mode of working file properly.
- *
- * Revision 4.2 83/12/05 13:40:54 wft
- * Merged with 3.9.1.1: added calls to clearerr(stdin).
- * made rewriteflag external.
- *
- * Revision 4.1 83/05/10 17:03:06 wft
- * Added option -d and -w, and updated assingment of date, etc. to new delta.
- * Added handling of default branches.
- * Option -k generates std. log message; fixed undef. pointer in reading of log.
- * Replaced getlock() with findlock(), link--unlink with rename(),
- * getpwuid() with getcaller().
- * Moved all revision number generation to new routine addelta().
- * Removed calls to stat(); now done by pairfilenames().
- * Changed most calls to catchints() with restoreints().
- * Directed all interactive messages to stderr.
- *
- * Revision 3.9.1.1 83/10/19 04:21:03 lepreau
- * Added clearerr(stdin) to getlogmsg() for re-reading stdin.
- *
- * Revision 3.9 83/02/15 15:25:44 wft
- * 4.2 prerelease
- *
- * Revision 3.9 83/02/15 15:25:44 wft
- * Added call to fastcopy() to copy remainder of RCS file.
- *
- * Revision 3.8 83/01/14 15:34:05 wft
- * Added ignoring of interrupts while new RCS file is renamed;
- * Avoids deletion of RCS files by interrupts.
- *
- * Revision 3.7 82/12/10 16:09:20 wft
- * Corrected checking of return code from diff.
- *
- * Revision 3.6 82/12/08 21:34:49 wft
- * Using DATEFORM to prepare date of checked-in revision;
- * Fixed return from addbranch().
- *
- * Revision 3.5 82/12/04 18:32:42 wft
- * Replaced getdelta() with gettree(), SNOOPDIR with SNOOPFILE. Updated
- * field lockedby in removelock(), moved getlogmsg() before calling diff.
- *
- * Revision 3.4 82/12/02 13:27:13 wft
- * added option -k.
- *
- * Revision 3.3 82/11/28 20:53:31 wft
- * Added mustcheckin() to check for redundant checkins.
- * Added xpandfile() to do keyword expansion for -u and -l;
- * -m appends linefeed to log message if necessary.
- * getlogmsg() suppresses prompt if stdin is not a terminal.
- * Replaced keeplock with lockflag, fclose() with ffclose(),
- * %02d with %.2d, getlogin() with getpwuid().
- *
- * Revision 3.2 82/10/18 20:57:23 wft
- * An RCS file inherits its mode during the first ci from the working file,
- * otherwise it stays the same, except that write permission is removed.
- * Fixed ci -l, added ci -u (both do an implicit co after the ci).
- * Fixed call to getlogin(), added call to getfullRCSname(), added check
- * for write error.
- * Changed conflicting identifiers.
- *
- * Revision 3.1 82/10/13 16:04:59 wft
- * fixed type of variables receiving from getc() (char -> int).
- * added include file dbm.h for getting BYTESIZ. This is used
- * to check the return code from diff portably.
- */
-
-#include "rcsbase.h"
-
-struct Symrev {
- char const *ssymbol;
- int override;
- struct Symrev * nextsym;
-};
-
-static char const *getcurdate P((void));
-static int addbranch P((struct hshentry*,struct buf*,int));
-static int addelta P((void));
-static int addsyms P((char const*));
-static int fixwork P((mode_t,time_t));
-static int removelock P((struct hshentry*));
-static int xpandfile P((RILE*,struct hshentry const*,char const**,int));
-static struct cbuf getlogmsg P((void));
-static void cleanup P((void));
-static void incnum P((char const*,struct buf*));
-static void addassoclst P((int,char const*));
-
-static FILE *exfile;
-static RILE *workptr; /* working file pointer */
-static struct buf newdelnum; /* new revision number */
-static struct cbuf msg;
-static int exitstatus;
-static int forceciflag; /* forces check in */
-static int keepflag, keepworkingfile, rcsinitflag;
-static struct hshentries *gendeltas; /* deltas to be generated */
-static struct hshentry *targetdelta; /* old delta to be generated */
-static struct hshentry newdelta; /* new delta to be inserted */
-static struct stat workstat;
-static struct Symrev *assoclst, **nextassoc;
-
-mainProg(ciId, "ci", "$FreeBSD$")
-{
- static char const cmdusage[] =
- "\nci usage: ci -{fIklMqru}[rev] -d[date] -mmsg -{nN}name -sstate -ttext -T -Vn -wwho -xsuff -zzone file ...";
- static char const default_state[] = DEFAULTSTATE;
-
- char altdate[datesize];
- char olddate[datesize];
- char newdatebuf[datesize + zonelenmax];
- char targetdatebuf[datesize + zonelenmax];
- char *a, **newargv, *textfile;
- char const *author, *krev, *rev, *state;
- char const *diffname, *expname;
- char const *newworkname;
- int initflag, mustread;
- int lockflag, lockthis, mtimeflag, removedlock, Ttimeflag;
- int r;
- int changedRCS, changework, dolog, newhead;
- int usestatdate; /* Use mod time of file for -d. */
- mode_t newworkmode; /* mode for working file */
- time_t mtime, wtime;
- struct hshentry *workdelta;
-
- setrid();
-
- author = rev = state = textfile = 0;
- initflag = lockflag = mustread = false;
- mtimeflag = false;
- Ttimeflag = false;
- altdate[0]= '\0'; /* empty alternate date for -d */
- usestatdate=false;
- suffixes = X_DEFAULT;
- nextassoc = &assoclst;
-
- argc = getRCSINIT(argc, argv, &newargv);
- argv = newargv;
- while (a = *++argv, 0<--argc && *a++=='-') {
- switch (*a++) {
-
- case 'r':
- if (*a)
- goto revno;
- keepworkingfile = lockflag = false;
- break;
-
- case 'l':
- keepworkingfile = lockflag = true;
- revno:
- if (*a) {
- if (rev) warn("redefinition of revision number");
- rev = a;
- }
- break;
-
- case 'u':
- keepworkingfile=true; lockflag=false;
- goto revno;
-
- case 'i':
- initflag = true;
- goto revno;
-
- case 'j':
- mustread = true;
- goto revno;
-
- case 'I':
- interactiveflag = true;
- goto revno;
-
- case 'q':
- quietflag=true;
- goto revno;
-
- case 'f':
- forceciflag=true;
- goto revno;
-
- case 'k':
- keepflag=true;
- goto revno;
-
- case 'm':
- if (msg.size) redefined('m');
- msg = cleanlogmsg(a, strlen(a));
- if (!msg.size)
- error("missing message for -m option");
- break;
-
- case 'n':
- if (!*a) {
- error("missing symbolic name after -n");
- break;
- }
- checkssym(a);
- addassoclst(false, a);
- break;
-
- case 'N':
- if (!*a) {
- error("missing symbolic name after -N");
- break;
- }
- checkssym(a);
- addassoclst(true, a);
- break;
-
- case 's':
- if (*a) {
- if (state) redefined('s');
- checksid(a);
- state = a;
- } else
- error("missing state for -s option");
- break;
-
- case 't':
- if (*a) {
- if (textfile) redefined('t');
- textfile = a;
- }
- break;
-
- case 'd':
- if (altdate[0] || usestatdate)
- redefined('d');
- altdate[0] = '\0';
- if (!(usestatdate = !*a))
- str2date(a, altdate);
- break;
-
- case 'M':
- mtimeflag = true;
- goto revno;
-
- case 'w':
- if (*a) {
- if (author) redefined('w');
- checksid(a);
- author = a;
- } else
- error("missing author for -w option");
- break;
-
- case 'x':
- suffixes = a;
- break;
-
- case 'V':
- setRCSversion(*argv);
- break;
-
- case 'z':
- zone_set(a);
- break;
-
- case 'T':
- if (!*a) {
- Ttimeflag = true;
- break;
- }
- /* fall into */
- default:
- error("unknown option: %s%s", *argv, cmdusage);
- };
- } /* end processing of options */
-
- /* Handle all pathnames. */
- if (nerror) cleanup();
- else if (argc < 1) faterror("no input file%s", cmdusage);
- else for (; 0 < argc; cleanup(), ++argv, --argc) {
- targetdelta = 0;
- ffree();
-
- switch (pairnames(argc, argv, rcswriteopen, mustread, false)) {
-
- case -1: /* New RCS file */
-# if has_setuid && has_getuid
- if (euid() != ruid()) {
- workerror("setuid initial checkin prohibited; use `rcs -i -a' first");
- continue;
- }
-# endif
- rcsinitflag = true;
- break;
-
- case 0: /* Error */
- continue;
-
- case 1: /* Normal checkin with prev . RCS file */
- if (initflag) {
- rcserror("already exists");
- continue;
- }
- rcsinitflag = !Head;
- }
-
- /*
- * RCSname contains the name of the RCS file, and
- * workname contains the name of the working file.
- * If the RCS file exists, finptr contains the file descriptor for the
- * RCS file, and RCSstat is set. The admin node is initialized.
- */
-
- diagnose("%s <-- %s\n", RCSname, workname);
-
- if (!(workptr = Iopen(workname, FOPEN_R_WORK, &workstat))) {
- eerror(workname);
- continue;
- }
-
- if (finptr) {
- if (same_file(RCSstat, workstat, 0)) {
- rcserror("RCS file is the same as working file %s.",
- workname
- );
- continue;
- }
- if (!checkaccesslist())
- continue;
- }
-
- krev = rev;
- if (keepflag) {
- /* get keyword values from working file */
- if (!getoldkeys(workptr)) continue;
- if (!rev && !*(krev = prevrev.string)) {
- workerror("can't find a revision number");
- continue;
- }
- if (!*prevdate.string && *altdate=='\0' && usestatdate==false)
- workwarn("can't find a date");
- if (!*prevauthor.string && !author)
- workwarn("can't find an author");
- if (!*prevstate.string && !state)
- workwarn("can't find a state");
- } /* end processing keepflag */
-
- /* Read the delta tree. */
- if (finptr)
- gettree();
-
- /* expand symbolic revision number */
- if (!fexpandsym(krev, &newdelnum, workptr))
- continue;
-
- /* splice new delta into tree */
- if ((removedlock = addelta()) < 0)
- continue;
-
- newdelta.num = newdelnum.string;
- newdelta.branches = 0;
- newdelta.lockedby = 0; /* This might be changed by addlock(). */
- newdelta.selector = true;
- newdelta.name = 0;
- clear_buf(&newdelta.ig);
- clear_buf(&newdelta.igtext);
- /* set author */
- if (author)
- newdelta.author=author; /* set author given by -w */
- else if (keepflag && *prevauthor.string)
- newdelta.author=prevauthor.string; /* preserve old author if possible*/
- else newdelta.author=getcaller();/* otherwise use caller's id */
- newdelta.state = default_state;
- if (state)
- newdelta.state=state; /* set state given by -s */
- else if (keepflag && *prevstate.string)
- newdelta.state=prevstate.string; /* preserve old state if possible */
- if (usestatdate) {
- time2date(workstat.st_mtime, altdate);
- }
- if (*altdate!='\0')
- newdelta.date=altdate; /* set date given by -d */
- else if (keepflag && *prevdate.string) {
- /* Preserve old date if possible. */
- str2date(prevdate.string, olddate);
- newdelta.date = olddate;
- } else
- newdelta.date = getcurdate(); /* use current date */
- /* now check validity of date -- needed because of -d and -k */
- if (targetdelta &&
- cmpdate(newdelta.date,targetdelta->date) < 0) {
- rcserror("Date %s precedes %s in revision %s.",
- date2str(newdelta.date, newdatebuf),
- date2str(targetdelta->date, targetdatebuf),
- targetdelta->num
- );
- continue;
- }
-
-
- if (lockflag && addlock(&newdelta, true) < 0) continue;
-
- if (keepflag && *prevname.string)
- if (addsymbol(newdelta.num, prevname.string, false) < 0)
- continue;
- if (!addsyms(newdelta.num))
- continue;
-
-
- putadmin();
- puttree(Head,frewrite);
- putdesc(false,textfile);
-
- changework = Expand < MIN_UNCHANGED_EXPAND;
- dolog = true;
- lockthis = lockflag;
- workdelta = &newdelta;
-
- /* build rest of file */
- if (rcsinitflag) {
- diagnose("initial revision: %s\n", newdelta.num);
- /* get logmessage */
- newdelta.log=getlogmsg();
- putdftext(&newdelta, workptr, frewrite, false);
- RCSstat.st_mode = workstat.st_mode;
- RCSstat.st_nlink = 0;
- changedRCS = true;
- } else {
- diffname = maketemp(0);
- newhead = Head == &newdelta;
- if (!newhead)
- foutptr = frewrite;
- expname = buildrevision(
- gendeltas, targetdelta, (FILE*)0, false
- );
- if (
- !forceciflag &&
- strcmp(newdelta.state, targetdelta->state) == 0 &&
- (changework = rcsfcmp(
- workptr, &workstat, expname, targetdelta
- )) <= 0
- ) {
- diagnose("file is unchanged; reverting to previous revision %s\n",
- targetdelta->num
- );
- if (removedlock < lockflag) {
- diagnose("previous revision was not locked; ignoring -l option\n");
- lockthis = 0;
- }
- dolog = false;
- if (! (changedRCS = lockflag<removedlock || assoclst))
- workdelta = targetdelta;
- else {
- /*
- * We have started to build the wrong new RCS file.
- * Start over from the beginning.
- */
- long hwm = ftell(frewrite);
- int bad_truncate;
- Orewind(frewrite);
-
- /*
- * Work around a common ftruncate() bug:
- * NFS won't let you truncate a file that you
- * currently lack permissions for, even if you
- * had permissions when you opened it.
- * Also, Posix 1003.1b-1993 sec 5.6.7.2 p 128 l 1022
- * says ftruncate might fail because it's not supported.
- */
-# if !has_ftruncate
-# undef ftruncate
-# define ftruncate(fd,length) (-1)
-# endif
- bad_truncate = ftruncate(fileno(frewrite), (off_t)0);
-
- Irewind(finptr);
- Lexinit();
- getadmin();
- gettree();
- if (!(workdelta = genrevs(
- targetdelta->num, (char*)0, (char*)0, (char*)0,
- &gendeltas
- )))
- continue;
- workdelta->log = targetdelta->log;
- if (newdelta.state != default_state)
- workdelta->state = newdelta.state;
- if (lockthis<removedlock && removelock(workdelta)<0)
- continue;
- if (!addsyms(workdelta->num))
- continue;
- if (dorewrite(true, true) != 0)
- continue;
- fastcopy(finptr, frewrite);
- if (bad_truncate)
- while (ftell(frewrite) < hwm)
- /* White out any earlier mistake with '\n's. */
- /* This is unlikely. */
- afputc('\n', frewrite);
- }
- } else {
- int wfd = Ifileno(workptr);
- struct stat checkworkstat;
- char const *diffv[6 + !!OPEN_O_BINARY], **diffp;
-# if large_memory && !maps_memory
- FILE *wfile = workptr->stream;
- long wfile_off;
-# endif
-# if !has_fflush_input && !(large_memory && maps_memory)
- off_t wfd_off;
-# endif
-
- diagnose("new revision: %s; previous revision: %s\n",
- newdelta.num, targetdelta->num
- );
- newdelta.log = getlogmsg();
-# if !large_memory
- Irewind(workptr);
-# if has_fflush_input
- if (fflush(workptr) != 0)
- Ierror();
-# endif
-# else
-# if !maps_memory
- if (
- (wfile_off = ftell(wfile)) == -1
- || fseek(wfile, 0L, SEEK_SET) != 0
-# if has_fflush_input
- || fflush(wfile) != 0
-# endif
- )
- Ierror();
-# endif
-# endif
-# if !has_fflush_input && !(large_memory && maps_memory)
- wfd_off = lseek(wfd, (off_t)0, SEEK_CUR);
- if (wfd_off == -1
- || (wfd_off != 0
- && lseek(wfd, (off_t)0, SEEK_SET) != 0))
- Ierror();
-# endif
- diffp = diffv;
- *++diffp = DIFF;
- *++diffp = DIFFFLAGS;
-# if OPEN_O_BINARY
- if (Expand == BINARY_EXPAND)
- *++diffp = "--binary";
-# endif
- *++diffp = newhead ? "-" : expname;
- *++diffp = newhead ? expname : "-";
- *++diffp = 0;
- switch (runv(wfd, diffname, diffv)) {
- case DIFF_FAILURE: case DIFF_SUCCESS: break;
- default: rcsfaterror("diff failed");
- }
-# if !has_fflush_input && !(large_memory && maps_memory)
- if (lseek(wfd, wfd_off, SEEK_CUR) == -1)
- Ierror();
-# endif
-# if large_memory && !maps_memory
- if (fseek(wfile, wfile_off, SEEK_SET) != 0)
- Ierror();
-# endif
- if (newhead) {
- Irewind(workptr);
- putdftext(&newdelta, workptr, frewrite, false);
- if (!putdtext(targetdelta,diffname,frewrite,true)) continue;
- } else
- if (!putdtext(&newdelta,diffname,frewrite,true)) continue;
-
- /*
- * Check whether the working file changed during checkin,
- * to avoid producing an inconsistent RCS file.
- */
- if (
- fstat(wfd, &checkworkstat) != 0
- || workstat.st_mtime != checkworkstat.st_mtime
- || workstat.st_size != checkworkstat.st_size
- ) {
- workerror("file changed during checkin");
- continue;
- }
-
- changedRCS = true;
- }
- }
-
- /* Deduce time_t of new revision if it is needed later. */
- wtime = (time_t)-1;
- if (mtimeflag | Ttimeflag)
- wtime = date2time(workdelta->date);
-
- if (donerewrite(changedRCS,
- !Ttimeflag ? (time_t)-1
- : finptr && wtime < RCSstat.st_mtime ? RCSstat.st_mtime
- : wtime
- ) != 0)
- continue;
-
- if (!keepworkingfile) {
- Izclose(&workptr);
- r = un_link(workname); /* Get rid of old file */
- } else {
- newworkmode = WORKMODE(RCSstat.st_mode,
- ! (Expand==VAL_EXPAND || lockthis < StrictLocks)
- );
- mtime = mtimeflag ? wtime : (time_t)-1;
-
- /* Expand if it might change or if we can't fix mode, time. */
- if (changework || (r=fixwork(newworkmode,mtime)) != 0) {
- Irewind(workptr);
- /* Expand keywords in file. */
- locker_expansion = lockthis;
- workdelta->name =
- namedrev(
- assoclst ? assoclst->ssymbol
- : keepflag && *prevname.string ? prevname.string
- : rev,
- workdelta
- );
- switch (xpandfile(
- workptr, workdelta, &newworkname, dolog
- )) {
- default:
- continue;
-
- case 0:
- /*
- * No expansion occurred; try to reuse working file
- * unless we already tried and failed.
- */
- if (changework)
- if ((r=fixwork(newworkmode,mtime)) == 0)
- break;
- /* fall into */
- case 1:
- Izclose(&workptr);
- aflush(exfile);
- ignoreints();
- r = chnamemod(&exfile, newworkname,
- workname, 1, newworkmode, mtime
- );
- keepdirtemp(newworkname);
- restoreints();
- }
- }
- }
- if (r != 0) {
- eerror(workname);
- continue;
- }
- diagnose("done\n");
-
- }
-
- tempunlink();
- exitmain(exitstatus);
-} /* end of main (ci) */
-
- static void
-cleanup()
-{
- if (nerror) exitstatus = EXIT_FAILURE;
- Izclose(&finptr);
- Izclose(&workptr);
- Ozclose(&exfile);
- Ozclose(&fcopy);
- ORCSclose();
- dirtempunlink();
-}
-
-#if RCS_lint
-# define exiterr ciExit
-#endif
- void
-exiterr()
-{
- ORCSerror();
- dirtempunlink();
- tempunlink();
- _exit(EXIT_FAILURE);
-}
-
-/*****************************************************************/
-/* the rest are auxiliary routines */
-
-
- static int
-addelta()
-/* Function: Appends a delta to the delta tree, whose number is
- * given by newdelnum. Updates Head, newdelnum, newdelnumlength,
- * and the links in newdelta.
- * Return -1 on error, 1 if a lock is removed, 0 otherwise.
- */
-{
- register char *tp;
- register int i;
- int removedlock;
- int newdnumlength; /* actual length of new rev. num. */
-
- newdnumlength = countnumflds(newdelnum.string);
-
- if (rcsinitflag) {
- /* this covers non-existing RCS file and a file initialized with rcs -i */
- if (newdnumlength==0 && Dbranch) {
- bufscpy(&newdelnum, Dbranch);
- newdnumlength = countnumflds(Dbranch);
- }
- if (newdnumlength==0) bufscpy(&newdelnum, "1.1");
- else if (newdnumlength==1) bufscat(&newdelnum, ".1");
- else if (newdnumlength>2) {
- rcserror("Branch point doesn't exist for revision %s.",
- newdelnum.string
- );
- return -1;
- } /* newdnumlength == 2 is OK; */
- Head = &newdelta;
- newdelta.next = 0;
- return 0;
- }
- if (newdnumlength==0) {
- /* derive new revision number from locks */
- switch (findlock(true, &targetdelta)) {
-
- default:
- /* found two or more old locks */
- return -1;
-
- case 1:
- /* found an old lock */
- /* check whether locked revision exists */
- if (!genrevs(targetdelta->num,(char*)0,(char*)0,(char*)0,&gendeltas))
- return -1;
- if (targetdelta==Head) {
- /* make new head */
- newdelta.next=Head;
- Head= &newdelta;
- } else if (!targetdelta->next && countnumflds(targetdelta->num)>2) {
- /* new tip revision on side branch */
- targetdelta->next= &newdelta;
- newdelta.next = 0;
- } else {
- /* middle revision; start a new branch */
- bufscpy(&newdelnum, "");
- return addbranch(targetdelta, &newdelnum, 1);
- }
- incnum(targetdelta->num, &newdelnum);
- return 1; /* successful use of existing lock */
-
- case 0:
- /* no existing lock; try Dbranch */
- /* update newdelnum */
- if (StrictLocks || !myself(RCSstat.st_uid)) {
- rcserror("no lock set by %s", getcaller());
- return -1;
- }
- if (Dbranch) {
- bufscpy(&newdelnum, Dbranch);
- } else {
- incnum(Head->num, &newdelnum);
- }
- newdnumlength = countnumflds(newdelnum.string);
- /* now fall into next statement */
- }
- }
- if (newdnumlength<=2) {
- /* add new head per given number */
- if(newdnumlength==1) {
- /* make a two-field number out of it*/
- if (cmpnumfld(newdelnum.string,Head->num,1)==0)
- incnum(Head->num, &newdelnum);
- else
- bufscat(&newdelnum, ".1");
- }
- if (cmpnum(newdelnum.string,Head->num) <= 0) {
- rcserror("revision %s too low; must be higher than %s",
- newdelnum.string, Head->num
- );
- return -1;
- }
- targetdelta = Head;
- if (0 <= (removedlock = removelock(Head))) {
- if (!genrevs(Head->num,(char*)0,(char*)0,(char*)0,&gendeltas))
- return -1;
- newdelta.next = Head;
- Head = &newdelta;
- }
- return removedlock;
- } else {
- /* put new revision on side branch */
- /*first, get branch point */
- tp = newdelnum.string;
- for (i = newdnumlength - ((newdnumlength&1) ^ 1); --i; )
- while (*tp++ != '.')
- continue;
- *--tp = 0; /* Kill final dot to get old delta temporarily. */
- if (!(targetdelta=genrevs(newdelnum.string,(char*)0,(char*)0,(char*)0,&gendeltas)))
- return -1;
- if (cmpnum(targetdelta->num, newdelnum.string) != 0) {
- rcserror("can't find branch point %s", newdelnum.string);
- return -1;
- }
- *tp = '.'; /* Restore final dot. */
- return addbranch(targetdelta, &newdelnum, 0);
- }
-}
-
-
-
- static int
-addbranch(branchpoint, num, removedlock)
- struct hshentry *branchpoint;
- struct buf *num;
- int removedlock;
-/* adds a new branch and branch delta at branchpoint.
- * If num is the null string, appends the new branch, incrementing
- * the highest branch number (initially 1), and setting the level number to 1.
- * the new delta and branchhead are in globals newdelta and newbranch, resp.
- * the new number is placed into num.
- * Return -1 on error, 1 if a lock is removed, 0 otherwise.
- * If REMOVEDLOCK is 1, a lock was already removed.
- */
-{
- struct branchhead *bhead, **btrail;
- struct buf branchnum;
- int result;
- int field, numlength;
- static struct branchhead newbranch; /* new branch to be inserted */
-
- numlength = countnumflds(num->string);
-
- if (!branchpoint->branches) {
- /* start first branch */
- branchpoint->branches = &newbranch;
- if (numlength==0) {
- bufscpy(num, branchpoint->num);
- bufscat(num, ".1.1");
- } else if (numlength&1)
- bufscat(num, ".1");
- newbranch.nextbranch = 0;
-
- } else if (numlength==0) {
- /* append new branch to the end */
- bhead=branchpoint->branches;
- while (bhead->nextbranch) bhead=bhead->nextbranch;
- bhead->nextbranch = &newbranch;
- bufautobegin(&branchnum);
- getbranchno(bhead->hsh->num, &branchnum);
- incnum(branchnum.string, num);
- bufautoend(&branchnum);
- bufscat(num, ".1");
- newbranch.nextbranch = 0;
- } else {
- /* place the branch properly */
- field = numlength - ((numlength&1) ^ 1);
- /* field of branch number */
- btrail = &branchpoint->branches;
- while (0 < (result=cmpnumfld(num->string,(*btrail)->hsh->num,field))) {
- btrail = &(*btrail)->nextbranch;
- if (!*btrail) {
- result = -1;
- break;
- }
- }
- if (result < 0) {
- /* insert/append new branchhead */
- newbranch.nextbranch = *btrail;
- *btrail = &newbranch;
- if (numlength&1) bufscat(num, ".1");
- } else {
- /* branch exists; append to end */
- bufautobegin(&branchnum);
- getbranchno(num->string, &branchnum);
- targetdelta = genrevs(
- branchnum.string, (char*)0, (char*)0, (char*)0,
- &gendeltas
- );
- bufautoend(&branchnum);
- if (!targetdelta)
- return -1;
- if (cmpnum(num->string,targetdelta->num) <= 0) {
- rcserror("revision %s too low; must be higher than %s",
- num->string, targetdelta->num
- );
- return -1;
- }
- if (!removedlock
- && 0 <= (removedlock = removelock(targetdelta))
- ) {
- if (numlength&1)
- incnum(targetdelta->num,num);
- targetdelta->next = &newdelta;
- newdelta.next = 0;
- }
- return removedlock;
- /* Don't do anything to newbranch. */
- }
- }
- newbranch.hsh = &newdelta;
- newdelta.next = 0;
- if (branchpoint->lockedby)
- if (strcmp(branchpoint->lockedby, getcaller()) == 0)
- return removelock(branchpoint); /* This returns 1. */
- return removedlock;
-}
-
- static int
-addsyms(num)
- char const *num;
-{
- register struct Symrev *p;
-
- for (p = assoclst; p; p = p->nextsym)
- if (addsymbol(num, p->ssymbol, p->override) < 0)
- return false;
- return true;
-}
-
-
- static void
-incnum(onum,nnum)
- char const *onum;
- struct buf *nnum;
-/* Increment the last field of revision number onum by one and
- * place the result into nnum.
- */
-{
- register char *tp, *np;
- register size_t l;
-
- l = strlen(onum);
- bufalloc(nnum, l+2);
- np = tp = nnum->string;
- VOID strcpy(np, onum);
- for (tp = np + l; np != tp; )
- if (isdigit(*--tp)) {
- if (*tp != '9') {
- ++*tp;
- return;
- }
- *tp = '0';
- } else {
- tp++;
- break;
- }
- /* We changed 999 to 000; now change it to 1000. */
- *tp = '1';
- tp = np + l;
- *tp++ = '0';
- *tp = 0;
-}
-
-
-
- static int
-removelock(delta)
-struct hshentry * delta;
-/* function: Finds the lock held by caller on delta,
- * removes it, and returns nonzero if successful.
- * Print an error message and return -1 if there is no such lock.
- * An exception is if !StrictLocks, and caller is the owner of
- * the RCS file. If caller does not have a lock in this case,
- * return 0; return 1 if a lock is actually removed.
- */
-{
- register struct rcslock *next, **trail;
- char const *num;
-
- num=delta->num;
- for (trail = &Locks; (next = *trail); trail = &next->nextlock)
- if (next->delta == delta)
- if (strcmp(getcaller(), next->login) == 0) {
- /* We found a lock on delta by caller; delete it. */
- *trail = next->nextlock;
- delta->lockedby = 0;
- return 1;
- } else {
- rcserror("revision %s locked by %s", num, next->login);
- return -1;
- }
- if (!StrictLocks && myself(RCSstat.st_uid))
- return 0;
- rcserror("no lock set by %s for revision %s", getcaller(), num);
- return -1;
-}
-
-
-
- static char const *
-getcurdate()
-/* Return a pointer to the current date. */
-{
- static char buffer[datesize]; /* date buffer */
-
- if (!buffer[0])
- time2date(now(), buffer);
- return buffer;
-}
-
- static int
-#if has_prototypes
-fixwork(mode_t newworkmode, time_t mtime)
- /* The `#if has_prototypes' is needed because mode_t might promote to int. */
-#else
- fixwork(newworkmode, mtime)
- mode_t newworkmode;
- time_t mtime;
-#endif
-{
- return
- 1 < workstat.st_nlink
- || (newworkmode&S_IWUSR && !myself(workstat.st_uid))
- || setmtime(workname, mtime) != 0
- ? -1
- : workstat.st_mode == newworkmode ? 0
-#if has_fchmod
- : fchmod(Ifileno(workptr), newworkmode) == 0 ? 0
-#endif
-#if bad_chmod_close
- : -1
-#else
- : chmod(workname, newworkmode)
-#endif
- ;
-}
-
- static int
-xpandfile(unexfile, delta, exname, dolog)
- RILE *unexfile;
- struct hshentry const *delta;
- char const **exname;
- int dolog;
-/*
- * Read unexfile and copy it to a
- * file, performing keyword substitution with data from delta.
- * Return -1 if unsuccessful, 1 if expansion occurred, 0 otherwise.
- * If successful, stores the stream descriptor into *EXFILEP
- * and its name into *EXNAME.
- */
-{
- char const *targetname;
- int e, r;
-
- targetname = makedirtemp(1);
- if (!(exfile = fopenSafer(targetname, FOPEN_W_WORK))) {
- eerror(targetname);
- workerror("can't build working file");
- return -1;
- }
- r = 0;
- if (MIN_UNEXPAND <= Expand)
- fastcopy(unexfile,exfile);
- else {
- for (;;) {
- e = expandline(
- unexfile, exfile, delta, false, (FILE*)0, dolog
- );
- if (e < 0)
- break;
- r |= e;
- if (e <= 1)
- break;
- }
- }
- *exname = targetname;
- return r & 1;
-}
-
-
-
-
-/* --------------------- G E T L O G M S G --------------------------------*/
-
-
- static struct cbuf
-getlogmsg()
-/* Obtain and yield a log message.
- * If a log message is given with -m, yield that message.
- * If this is the initial revision, yield a standard log message.
- * Otherwise, reads a character string from the terminal.
- * Stops after reading EOF or a single '.' on a
- * line. getlogmsg prompts the first time it is called for the
- * log message; during all later calls it asks whether the previous
- * log message can be reused.
- */
-{
- static char const
- emptych[] = EMPTYLOG,
- initialch[] = "Initial revision";
- static struct cbuf const
- emptylog = { emptych, sizeof(emptych)-sizeof(char) },
- initiallog = { initialch, sizeof(initialch)-sizeof(char) };
- static struct buf logbuf;
- static struct cbuf logmsg;
-
- register char *tp;
- register size_t i;
- char const *caller;
-
- if (msg.size) return msg;
-
- if (keepflag) {
- /* generate std. log message */
- caller = getcaller();
- i = sizeof(ciklog)+strlen(caller)+3;
- bufalloc(&logbuf, i + datesize + zonelenmax);
- tp = logbuf.string;
- VOID sprintf(tp, "%s%s at ", ciklog, caller);
- VOID date2str(getcurdate(), tp+i);
- logmsg.string = tp;
- logmsg.size = strlen(tp);
- return logmsg;
- }
-
- if (!targetdelta && (
- cmpnum(newdelnum.string,"1.1")==0 ||
- cmpnum(newdelnum.string,"1.0")==0
- ))
- return initiallog;
-
- if (logmsg.size) {
- /*previous log available*/
- if (yesorno(true, "reuse log message of previous file? [yn](y): "))
- return logmsg;
- }
-
- /* now read string from stdin */
- logmsg = getsstdin("m", "log message", "", &logbuf);
-
- /* now check whether the log message is not empty */
- if (logmsg.size)
- return logmsg;
- return emptylog;
-}
-
-/* Make a linked list of Symbolic names */
-
- static void
-addassoclst(flag, sp)
- int flag;
- char const *sp;
-{
- struct Symrev *pt;
-
- pt = talloc(struct Symrev);
- pt->ssymbol = sp;
- pt->override = flag;
- pt->nextsym = 0;
- *nextassoc = pt;
- nextassoc = &pt->nextsym;
-}
diff --git a/gnu/usr.bin/rcs/co/Makefile b/gnu/usr.bin/rcs/co/Makefile
deleted file mode 100644
index 0c73865..0000000
--- a/gnu/usr.bin/rcs/co/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG= co
-SRCS= co.c
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/co/co.1 b/gnu/usr.bin/rcs/co/co.1
deleted file mode 100644
index 2aea3ad..0000000
--- a/gnu/usr.bin/rcs/co/co.1
+++ /dev/null
@@ -1,736 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds i \&\s-1ISO\s0
-.ds r \&\s-1RCS\s0
-.ds u \&\s-1UTC\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.TH CO 1 \*(Dt GNU
-.SH NAME
-co \- check out RCS revisions
-.SH SYNOPSIS
-.B co
-.RI [ options ] " file " .\|.\|.
-.SH DESCRIPTION
-.B co
-retrieves a revision from each \*r file and stores it into
-the corresponding working file.
-.PP
-Pathnames matching an \*r suffix denote \*r files;
-all others denote working files.
-Names are paired as explained in
-.BR ci (1).
-.PP
-Revisions of an \*r file can be checked out locked or unlocked. Locking a
-revision prevents overlapping updates. A revision checked out for reading or
-processing (e.g., compiling) need not be locked. A revision checked out
-for editing and later checkin must normally be locked. Checkout with locking
-fails if the revision to be checked out is currently locked by another user.
-(A lock can be broken with
-.BR rcs "(1).)\ \&"
-Checkout with locking also requires the caller to be on the access list of
-the \*r file, unless he is the owner of the
-file or the superuser, or the access list is empty.
-Checkout without locking is not subject to accesslist restrictions, and is
-not affected by the presence of locks.
-.PP
-A revision is selected by options for revision or branch number,
-checkin date/time, author, or state.
-When the selection options
-are applied in combination,
-.B co
-retrieves the latest revision
-that satisfies all of them.
-If none of the selection options
-is specified,
-.B co
-retrieves the latest revision
-on the default branch (normally the trunk, see the
-.B \-b
-option of
-.BR rcs (1)).
-A revision or branch number can be attached
-to any of the options
-.BR \-f ,
-.BR \-I ,
-.BR \-l ,
-.BR \-M ,
-.BR \-p ,
-.BR \-q ,
-.BR \-r ,
-or
-.BR \-u .
-The options
-.B \-d
-(date),
-.B \-s
-(state), and
-.B \-w
-(author)
-retrieve from a single branch, the
-.I selected
-branch,
-which is either specified by one of
-.BR \-f ,
-\&.\|.\|.,
-.BR \-u ,
-or the default branch.
-.PP
-A
-.B co
-command applied to an \*r
-file with no revisions creates a zero-length working file.
-.B co
-always performs keyword substitution (see below).
-.SH OPTIONS
-.TP
-.BR \-r [\f2rev\fP]
-retrieves the latest revision whose number is less than or equal to
-.IR rev .
-If
-.I rev
-indicates a branch rather than a revision,
-the latest revision on that branch is retrieved.
-If
-.I rev
-is omitted, the latest revision on the default branch
-(see the
-.B \-b
-option of
-.BR rcs (1))
-is retrieved.
-If
-.I rev
-is
-.BR $ ,
-.B co
-determines the revision number from keyword values in the working file.
-Otherwise, a revision is composed of one or more numeric or symbolic fields
-separated by periods.
-If
-.I rev
-begins with a period,
-then the default branch (normally the trunk) is prepended to it.
-If
-.I rev
-is a branch number followed by a period,
-then the latest revision on that branch is used.
-The numeric equivalent of a symbolic field
-is specified with the
-.B \-n
-option of the commands
-.BR ci (1)
-and
-.BR rcs (1).
-.TP
-.BR \-l [\f2rev\fP]
-same as
-.BR \-r ,
-except that it also locks the retrieved revision for
-the caller.
-.TP
-.BR \-u [\f2rev\fP]
-same as
-.BR \-r ,
-except that it unlocks the retrieved revision if it was
-locked by the caller. If
-.I rev
-is omitted,
-.B \-u
-retrieves the revision locked by the caller, if there is one; otherwise,
-it retrieves the latest revision on the default branch.
-.TP
-.BR \-f [\f2rev\fP]
-forces the overwriting of the working file;
-useful in connection with
-.BR \-q .
-See also
-.SM "FILE MODES"
-below.
-.TP
-.B \-kkv
-Generate keyword strings using the default form, e.g.\&
-.B "$\&Revision: \*(Rv $"
-for the
-.B Revision
-keyword.
-A locker's name is inserted in the value of the
-.BR Header ,
-.BR Id ,
-and
-.B Locker
-keyword strings
-only as a file is being locked,
-i.e. by
-.B "ci\ \-l"
-and
-.BR "co\ \-l".
-This is the default.
-.TP
-.B \-kkvl
-Like
-.BR \-kkv ,
-except that a locker's name is always inserted
-if the given revision is currently locked.
-.TP
-.B \-kk
-Generate only keyword names in keyword strings; omit their values.
-See
-.SM "KEYWORD SUBSTITUTION"
-below.
-For example, for the
-.B Revision
-keyword, generate the string
-.B $\&Revision$
-instead of
-.BR "$\&Revision: \*(Rv $" .
-This option is useful to ignore differences due to keyword substitution
-when comparing different revisions of a file.
-Log messages are inserted after
-.B $\&Log$
-keywords even if
-.B \-kk
-is specified,
-since this tends to be more useful when merging changes.
-.TP
-.B \-ko
-Generate the old keyword string,
-present in the working file just before it was checked in.
-For example, for the
-.B Revision
-keyword, generate the string
-.B "$\&Revision: 1.1 $"
-instead of
-.B "$\&Revision: \*(Rv $"
-if that is how the string appeared when the file was checked in.
-This can be useful for file formats
-that cannot tolerate any changes to substrings
-that happen to take the form of keyword strings.
-.TP
-.B \-kb
-Generate a binary image of the old keyword string.
-This acts like
-.BR \-ko ,
-except it performs all working file input and output in binary mode.
-This makes little difference on Posix and Unix hosts,
-but on DOS-like hosts one should use
-.B "rcs\ \-i\ \-kb"
-to initialize an \*r file intended to be used for binary files.
-Also, on all hosts,
-.BR rcsmerge (1)
-normally refuses to merge files when
-.B \-kb
-is in effect.
-.TP
-.B \-kv
-Generate only keyword values for keyword strings.
-For example, for the
-.B Revision
-keyword, generate the string
-.B \*(Rv
-instead of
-.BR "$\&Revision: \*(Rv $" .
-This can help generate files in programming languages where it is hard to
-strip keyword delimiters like
-.B "$\&Revision:\ $"
-from a string.
-However, further keyword substitution cannot be performed once the
-keyword names are removed, so this option should be used with care.
-Because of this danger of losing keywords,
-this option cannot be combined with
-.BR \-l ,
-and the owner write permission of the working file is turned off;
-to edit the file later, check it out again without
-.BR \-kv .
-.TP
-.BR \-p [\f2rev\fP]
-prints the retrieved revision on the standard output rather than storing it
-in the working file.
-This option is useful when
-.B co
-is part of a pipe.
-.TP
-.BR \-q [\f2rev\fP]
-quiet mode; diagnostics are not printed.
-.TP
-.BR \-I [\f2rev\fP]
-interactive mode;
-the user is prompted and questioned
-even if the standard input is not a terminal.
-.TP
-.BI \-d date
-retrieves the latest revision on the selected branch whose checkin date/time is
-less than or equal to
-.IR date .
-The date and time can be given in free format.
-The time zone
-.B LT
-stands for local time;
-other common time zone names are understood.
-For example, the following
-.IR date s
-are equivalent
-if local time is January 11, 1990, 8pm Pacific Standard Time,
-eight hours west of Coordinated Universal Time (\*u):
-.RS
-.LP
-.RS
-.nf
-.ta \w'\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP 'u
-.ne 10
-\f38:00 pm lt\fP
-\f34:00 AM, Jan. 12, 1990\fP default is \*u
-\f31990-01-12 04:00:00+00\fP \*i 8601 (\*u)
-\f31990-01-11 20:00:00\-08\fP \*i 8601 (local time)
-\f31990/01/12 04:00:00\fP traditional \*r format
-\f3Thu Jan 11 20:00:00 1990 LT\fP output of \f3ctime\fP(3) + \f3LT\fP
-\f3Thu Jan 11 20:00:00 PST 1990\fP output of \f3date\fP(1)
-\f3Fri Jan 12 04:00:00 GMT 1990\fP
-\f3Thu, 11 Jan 1990 20:00:00 \-0800\fP Internet RFC 822
-\f312-January-1990, 04:00 WET\fP
-.ta 4n +4n +4n +4n
-.fi
-.RE
-.LP
-Most fields in the date and time can be defaulted.
-The default time zone is normally \*u, but this can be overridden by the
-.B \-z
-option.
-The other defaults are determined in the order year, month, day,
-hour, minute, and second (most to least significant). At least one of these
-fields must be provided. For omitted fields that are of higher significance
-than the highest provided field, the time zone's current values are assumed.
-For all other omitted fields,
-the lowest possible values are assumed.
-For example, without
-.BR \-z ,
-the date
-.B "20, 10:30"
-defaults to
-10:30:00 \*u of the 20th of the \*u time zone's current month and year.
-The date/time must be quoted if it contains spaces.
-.RE
-.TP
-.BR \-M [\f2rev\fP]
-Set the modification time on the new working file
-to be the date of the retrieved revision.
-Use this option with care; it can confuse
-.BR make (1).
-.TP
-.BI \-s state
-retrieves the latest revision on the selected branch whose state is set to
-.IR state .
-.TP
-.B \-T
-Preserve the modification time on the \*r file
-even if the \*r file changes because a lock is added or removed.
-This option can suppress extensive recompilation caused by a
-.BR make (1)
-dependency of some other copy of the working file on the \*r file.
-Use this option with care; it can suppress recompilation even when it is needed,
-i.e. when the change of lock
-would mean a change to keyword strings in the other working file.
-.TP
-.BR \-w [\f2login\fP]
-retrieves the latest revision on the selected branch which was checked in
-by the user with login name
-.IR login .
-If the argument
-.I login
-is
-omitted, the caller's login is assumed.
-.TP
-.BI \-j joinlist
-generates a new revision which is the join of the revisions on
-.IR joinlist .
-This option is largely obsoleted by
-.BR rcsmerge (1)
-but is retained for backwards compatibility.
-.RS
-.PP
-The
-.I joinlist
-is a comma-separated list of pairs of the form
-.IB rev2 : rev3,
-where
-.I rev2
-and
-.I rev3
-are (symbolic or numeric)
-revision numbers.
-For the initial such pair,
-.I rev1
-denotes the revision selected
-by the above options
-.BR \-f ,
-\&.\|.\|.,
-.BR \-w .
-For all other pairs,
-.I rev1
-denotes the revision generated by the previous pair.
-(Thus, the output
-of one join becomes the input to the next.)
-.PP
-For each pair,
-.B co
-joins revisions
-.I rev1
-and
-.I rev3
-with respect to
-.IR rev2 .
-This means that all changes that transform
-.I rev2
-into
-.I rev1
-are applied to a copy of
-.IR rev3 .
-This is particularly useful if
-.I rev1
-and
-.I rev3
-are the ends of two branches that have
-.I rev2
-as a common ancestor. If
-.IR rev1 < rev2 < rev3
-on the same branch,
-joining generates a new revision which is like
-.I rev3,
-but with all changes that lead from
-.I rev1
-to
-.I rev2
-undone.
-If changes from
-.I rev2
-to
-.I rev1
-overlap with changes from
-.I rev2
-to
-.I rev3,
-.B co
-reports overlaps as described in
-.BR merge (1).
-.PP
-For the initial pair,
-.I rev2
-can be omitted. The default is the common
-ancestor.
-If any of the arguments indicate branches, the latest revisions
-on those branches are assumed.
-The options
-.B \-l
-and
-.B \-u
-lock or unlock
-.IR rev1 .
-.RE
-.TP
-.BI \-V
-Print \*r's version number.
-.TP
-.BI \-V n
-Emulate \*r version
-.I n,
-where
-.I n
-can be
-.BR 3 ,
-.BR 4 ,
-or
-.BR 5 .
-This can be useful when interchanging \*r files with others who are
-running older versions of \*r.
-To see which version of \*r your correspondents are running, have them invoke
-.BR "rcs \-V" ;
-this works with newer versions of \*r.
-If it doesn't work, have them invoke
-.B rlog
-on an \*r file;
-if none of the first few lines of output contain the string
-.B branch:
-it is version 3;
-if the dates' years have just two digits, it is version 4;
-otherwise, it is version 5.
-An \*r file generated while emulating version 3 loses its default branch.
-An \*r revision generated while emulating version 4 or earlier has
-a time stamp that is off by up to 13 hours.
-A revision extracted while emulating version 4 or earlier contains
-abbreviated dates of the form
-.IB yy / mm / dd
-and can also contain different white space and line prefixes
-in the substitution for
-.BR $\&Log$ .
-.TP
-.BI \-x "suffixes"
-Use
-.I suffixes
-to characterize \*r files.
-See
-.BR ci (1)
-for details.
-.TP
-.BI \-z zone
-specifies the date output format in keyword substitution,
-and specifies the default time zone for
-.I date
-in the
-.BI \-d date
-option.
-The
-.I zone
-should be empty, a numeric \*u offset, or the special string
-.B LT
-for local time.
-The default is an empty
-.IR zone ,
-which uses the traditional \*r format of \*u without any time zone indication
-and with slashes separating the parts of the date;
-otherwise, times are output in \*i 8601 format with time zone indication.
-For example, if local time is January 11, 1990, 8pm Pacific Standard Time,
-eight hours west of \*u,
-then the time is output as follows:
-.RS
-.LP
-.RS
-.nf
-.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u
-.ne 4
-\f2option\fP \f2time output\fP
-\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP
-\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP
-\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP
-.ta 4n +4n +4n +4n
-.fi
-.RE
-.LP
-The
-.B \-z
-option does not affect dates stored in \*r files,
-which are always \*u.
-.RE
-.SH "KEYWORD SUBSTITUTION"
-Strings of the form
-.BI $ keyword $
-and
-.BI $ keyword : .\|.\|. $
-embedded in
-the text are replaced
-with strings of the form
-.BI $ keyword : value $
-where
-.I keyword
-and
-.I value
-are pairs listed below.
-Keywords can be embedded in literal strings
-or comments to identify a revision.
-.PP
-Initially, the user enters strings of the form
-.BI $ keyword $ .
-On checkout,
-.B co
-replaces these strings with strings of the form
-.BI $ keyword : value $ .
-If a revision containing strings of the latter form
-is checked back in, the value fields will be replaced during the next
-checkout.
-Thus, the keyword values are automatically updated on checkout.
-This automatic substitution can be modified by the
-.B \-k
-options.
-.PP
-Keywords and their corresponding values:
-.TP
-.B $\&Author$
-The login name of the user who checked in the revision.
-.TP
-.B $\&Date$
-The date and time the revision was checked in.
-With
-.BI \-z zone
-a numeric time zone offset is appended; otherwise, the date is \*u.
-.TP
-.B $\&Header$
-A standard header containing the full pathname of the \*r file, the
-revision number, the date and time, the author, the state,
-and the locker (if locked).
-With
-.BI \-z zone
-a numeric time zone offset is appended to the date; otherwise, the date is \*u.
-.TP
-.B $\&Id$
-Same as
-.BR $\&Header$ ,
-except that the \*r filename is without a path.
-.TP
-.B $\&Locker$
-The login name of the user who locked the revision (empty if not locked).
-.TP
-.B $\&Log$
-The log message supplied during checkin, preceded by a header
-containing the \*r filename, the revision number, the author, and the date
-and time.
-With
-.BI \-z zone
-a numeric time zone offset is appended; otherwise, the date is \*u.
-Existing log messages are
-.I not
-replaced.
-Instead, the new log message is inserted after
-.BR $\&Log: .\|.\|. $ .
-This is useful for
-accumulating a complete change log in a source file.
-.RS
-.LP
-Each inserted line is prefixed by the string that prefixes the
-.B $\&Log$
-line. For example, if the
-.B $\&Log$
-line is
-.RB \*(lq "//\ $\&Log: tan.cc\ $" \*(rq,
-\*r prefixes each line of the log with
-.RB \*(lq "//\ " \*(rq.
-This is useful for languages with comments that go to the end of the line.
-The convention for other languages is to use a
-.RB \*(lq " \(** " \(rq
-prefix inside a multiline comment.
-For example, the initial log comment of a C program
-conventionally is of the following form:
-.RS
-.LP
-.nf
-.ft 3
-.ne 3
-/\(**
-.in +\w'/'u
-\(** $\&Log$
-\(**/
-.in
-.ft
-.fi
-.RE
-.LP
-For backwards compatibility with older versions of \*r, if the log prefix is
-.B /\(**
-or
-.B (\(**
-surrounded by optional white space, inserted log lines contain a space
-instead of
-.B /
-or
-.BR ( ;
-however, this usage is obsolescent and should not be relied on.
-.RE
-.TP
-.B $\&Name$
-The symbolic name used to check out the revision, if any.
-For example,
-.B "co\ \-rJoe"
-generates
-.BR "$\&Name:\ Joe\ $" .
-Plain
-.B co
-generates just
-.BR "$\&Name:\ \ $" .
-.TP
-.B $\&RCSfile$
-The name of the \*r file without a path.
-.TP
-.B $\&Revision$
-The revision number assigned to the revision.
-.TP
-.B $\&Source$
-The full pathname of the \*r file.
-.TP
-.B $\&State$
-The state assigned to the revision with the
-.B \-s
-option of
-.BR rcs (1)
-or
-.BR ci (1).
-.PP
-The following characters in keyword values are represented by escape sequences
-to keep keyword strings well-formed.
-.LP
-.RS
-.nf
-.ne 6
-.ta \w'newline 'u
-\f2char escape sequence\fP
-tab \f3\et\fP
-newline \f3\en\fP
-space \f3\e040
-$ \e044
-\e \e\e\fP
-.fi
-.RE
-.SH "FILE MODES"
-The working file inherits the read and execute permissions from the \*r
-file. In addition, the owner write permission is turned on, unless
-.B \-kv
-is set or the file
-is checked out unlocked and locking is set to strict (see
-.BR rcs (1)).
-.PP
-If a file with the name of the working file exists already and has write
-permission,
-.B co
-aborts the checkout,
-asking beforehand if possible.
-If the existing working file is
-not writable or
-.B \-f
-is given, the working file is deleted without asking.
-.SH FILES
-.B co
-accesses files much as
-.BR ci (1)
-does, except that it does not need to read the working file
-unless a revision number of
-.B $
-is specified.
-.SH ENVIRONMENT
-.TP
-.B \s-1RCSINIT\s0
-options prepended to the argument list, separated by spaces.
-See
-.BR ci (1)
-for details.
-.SH DIAGNOSTICS
-The \*r pathname, the working pathname,
-and the revision number retrieved are
-written to the diagnostic output.
-The exit status is zero if and only if all operations were successful.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
-.SH "SEE ALSO"
-rcsintro(1), ci(1), ctime(3), date(1), ident(1), make(1),
-rcs(1), rcsclean(1), rcsdiff(1), rcsmerge(1), rlog(1),
-rcsfile(5)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.SH LIMITS
-Links to the \*r and working files are not preserved.
-.PP
-There is no way to selectively suppress the expansion of keywords, except
-by writing them differently. In nroff and troff, this is done by embedding the
-null-character
-.B \e&
-into the keyword.
-.br
diff --git a/gnu/usr.bin/rcs/co/co.c b/gnu/usr.bin/rcs/co/co.c
deleted file mode 100644
index 51cb2b2..0000000
--- a/gnu/usr.bin/rcs/co/co.c
+++ /dev/null
@@ -1,826 +0,0 @@
-/* Check out working files from revisions of RCS files. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.18 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.17 1995/06/01 16:23:43 eggert
- * (main, preparejoin): Pass argument instead of using `join' static variable.
- * (main): Add -kb.
- *
- * Revision 5.16 1994/03/17 14:05:48 eggert
- * Move buffer-flushes out of critical sections, since they aren't critical.
- * Use ORCSerror to clean up after a fatal error. Remove lint.
- * Specify subprocess input via file descriptor, not file name.
- *
- * Revision 5.15 1993/11/09 17:40:15 eggert
- * -V now prints version on stdout and exits. Don't print usage twice.
- *
- * Revision 5.14 1993/11/03 17:42:27 eggert
- * Add -z. Generate a value for the Name keyword.
- * Don't arbitrarily limit the number of joins.
- * Improve quality of diagnostics.
- *
- * Revision 5.13 1992/07/28 16:12:44 eggert
- * Add -V. Check that working and RCS files are distinct.
- *
- * Revision 5.12 1992/02/17 23:02:08 eggert
- * Add -T.
- *
- * Revision 5.11 1992/01/24 18:44:19 eggert
- * Add support for bad_creat0. lint -> RCS_lint
- *
- * Revision 5.10 1992/01/06 02:42:34 eggert
- * Update usage string.
- *
- * Revision 5.9 1991/10/07 17:32:46 eggert
- * -k affects just working file, not RCS file.
- *
- * Revision 5.8 1991/08/19 03:13:55 eggert
- * Warn before removing somebody else's file.
- * Add -M. Fix co -j bugs. Tune.
- *
- * Revision 5.7 1991/04/21 11:58:15 eggert
- * Ensure that working file is newer than RCS file after co -[lu].
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.6 1990/12/04 05:18:38 eggert
- * Don't checkaccesslist() unless necessary.
- * Use -I for prompts and -q for diagnostics.
- *
- * Revision 5.5 1990/11/01 05:03:26 eggert
- * Fix -j. Add -I.
- *
- * Revision 5.4 1990/10/04 06:30:11 eggert
- * Accumulate exit status across files.
- *
- * Revision 5.3 1990/09/11 02:41:09 eggert
- * co -kv yields a readonly working file.
- *
- * Revision 5.2 1990/09/04 08:02:13 eggert
- * Standardize yes-or-no procedure.
- *
- * Revision 5.0 1990/08/22 08:10:02 eggert
- * Permit multiple locks by same user. Add setuid support.
- * Remove compile-time limits; use malloc instead.
- * Permit dates past 1999/12/31. Switch to GMT.
- * Make lock and temp files faster and safer.
- * Ansify and Posixate. Add -k, -V. Remove snooping. Tune.
- *
- * Revision 4.7 89/05/01 15:11:41 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.6 88/08/09 19:12:15 eggert
- * Fix "co -d" core dump; rawdate wasn't always initialized.
- * Use execv(), not system(); fix putchar('\0') and diagnose() botches; remove lint
- *
- * Revision 4.5 87/12/18 11:35:40 narten
- * lint cleanups (from Guy Harris)
- *
- * Revision 4.4 87/10/18 10:20:53 narten
- * Updating version numbers changes relative to 1.1, are actually
- * relative to 4.2
- *
- * Revision 1.3 87/09/24 13:58:30 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:21:38 jenkins
- * Port to suns
- *
- * Revision 4.2 83/12/05 13:39:48 wft
- * made rewriteflag external.
- *
- * Revision 4.1 83/05/10 16:52:55 wft
- * Added option -u and -f.
- * Added handling of default branch.
- * Replaced getpwuid() with getcaller().
- * Removed calls to stat(); now done by pairfilenames().
- * Changed and renamed rmoldfile() to rmworkfile().
- * Replaced catchints() calls with restoreints(), unlink()--link() with rename();
- *
- * Revision 3.7 83/02/15 15:27:07 wft
- * Added call to fastcopy() to copy remainder of RCS file.
- *
- * Revision 3.6 83/01/15 14:37:50 wft
- * Added ignoring of interrupts while RCS file is renamed; this avoids
- * deletion of RCS files during the unlink/link window.
- *
- * Revision 3.5 82/12/08 21:40:11 wft
- * changed processing of -d to use DATEFORM; removed actual from
- * call to preparejoin; re-fixed printing of done at the end.
- *
- * Revision 3.4 82/12/04 18:40:00 wft
- * Replaced getdelta() with gettree(), SNOOPDIR with SNOOPFILE.
- * Fixed printing of "done".
- *
- * Revision 3.3 82/11/28 22:23:11 wft
- * Replaced getlogin() with getpwuid(), flcose() with ffclose(),
- * %02d with %.2d, mode generation for working file with WORKMODE.
- * Fixed nil printing. Fixed -j combined with -l and -p, and exit
- * for non-existing revisions in preparejoin().
- *
- * Revision 3.2 82/10/18 20:47:21 wft
- * Mode of working file is now maintained even for co -l, but write permission
- * is removed.
- * The working file inherits its mode from the RCS file, plus write permission
- * for the owner. The write permission is not given if locking is strict and
- * co does not lock.
- * An existing working file without write permission is deleted automatically.
- * Otherwise, co asks (empty answer: abort co).
- * Call to getfullRCSname() added, check for write error added, call
- * for getlogin() fixed.
- *
- * Revision 3.1 82/10/13 16:01:30 wft
- * fixed type of variables receiving from getc() (char -> int).
- * removed unused variables.
- */
-
-
-
-
-#include "rcsbase.h"
-
-static char *addjoin P((char*));
-static char const *getancestor P((char const*,char const*));
-static int buildjoin P((char const*));
-static int preparejoin P((char*));
-static int rmlock P((struct hshentry const*));
-static int rmworkfile P((void));
-static void cleanup P((void));
-
-static char const quietarg[] = "-q";
-
-static char const *expandarg, *suffixarg, *versionarg, *zonearg;
-static char const **joinlist; /* revisions to be joined */
-static int joinlength;
-static FILE *neworkptr;
-static int exitstatus;
-static int forceflag;
-static int lastjoin; /* index of last element in joinlist */
-static int lockflag; /* -1 -> unlock, 0 -> do nothing, 1 -> lock */
-static int mtimeflag;
-static struct hshentries *gendeltas; /* deltas to be generated */
-static struct hshentry *targetdelta; /* final delta to be generated */
-static struct stat workstat;
-
-mainProg(coId, "co", "$FreeBSD$")
-{
- static char const cmdusage[] =
- "\nco usage: co -{fIlMpqru}[rev] -ddate -jjoins -ksubst -sstate -T -w[who] -Vn -xsuff -zzone file ...";
-
- char *a, *joinflag, **newargv;
- char const *author, *date, *rev, *state;
- char const *joinname, *newdate, *neworkname;
- int changelock; /* 1 if a lock has been changed, -1 if error */
- int expmode, r, tostdout, workstatstat;
- int Ttimeflag;
- struct buf numericrev; /* expanded revision number */
- char finaldate[datesize];
-# if OPEN_O_BINARY
- int stdout_mode = 0;
-# endif
-
- setrid();
- author = date = rev = state = 0;
- joinflag = 0;
- bufautobegin(&numericrev);
- expmode = -1;
- suffixes = X_DEFAULT;
- tostdout = false;
- Ttimeflag = false;
-
- argc = getRCSINIT(argc, argv, &newargv);
- argv = newargv;
- while (a = *++argv, 0<--argc && *a++=='-') {
- switch (*a++) {
-
- case 'r':
- revno:
- if (*a) {
- if (rev) warn("redefinition of revision number");
- rev = a;
- }
- break;
-
- case 'f':
- forceflag=true;
- goto revno;
-
- case 'l':
- if (lockflag < 0) {
- warn("-u overridden by -l.");
- }
- lockflag = 1;
- goto revno;
-
- case 'u':
- if (0 < lockflag) {
- warn("-l overridden by -u.");
- }
- lockflag = -1;
- goto revno;
-
- case 'p':
- tostdout = true;
- goto revno;
-
- case 'I':
- interactiveflag = true;
- goto revno;
-
- case 'q':
- quietflag=true;
- goto revno;
-
- case 'd':
- if (date)
- redefined('d');
- str2date(a, finaldate);
- date=finaldate;
- break;
-
- case 'j':
- if (*a) {
- if (joinflag) redefined('j');
- joinflag = a;
- }
- break;
-
- case 'M':
- mtimeflag = true;
- goto revno;
-
- case 's':
- if (*a) {
- if (state) redefined('s');
- state = a;
- }
- break;
-
- case 'T':
- if (*a)
- goto unknown;
- Ttimeflag = true;
- break;
-
- case 'w':
- if (author) redefined('w');
- if (*a)
- author = a;
- else
- author = getcaller();
- break;
-
- case 'x':
- suffixarg = *argv;
- suffixes = a;
- break;
-
- case 'V':
- versionarg = *argv;
- setRCSversion(versionarg);
- break;
-
- case 'z':
- zonearg = *argv;
- zone_set(a);
- break;
-
- case 'k': /* set keyword expand mode */
- expandarg = *argv;
- if (0 <= expmode) redefined('k');
- if (0 <= (expmode = str2expmode(a)))
- break;
- /* fall into */
- default:
- unknown:
- error("unknown option: %s%s", *argv, cmdusage);
-
- };
- } /* end of option processing */
-
- /* Now handle all pathnames. */
- if (nerror) cleanup();
- else if (argc < 1) faterror("no input file%s", cmdusage);
- else for (; 0 < argc; cleanup(), ++argv, --argc) {
- ffree();
-
- if (pairnames(argc, argv, lockflag?rcswriteopen:rcsreadopen, true, false) <= 0)
- continue;
-
- /*
- * RCSname contains the name of the RCS file, and finptr
- * points at it. workname contains the name of the working file.
- * Also, RCSstat has been set.
- */
- diagnose("%s --> %s\n", RCSname, tostdout?"standard output":workname);
-
- workstatstat = -1;
- if (tostdout) {
-# if OPEN_O_BINARY
- int newmode = Expand==BINARY_EXPAND ? OPEN_O_BINARY : 0;
- if (stdout_mode != newmode) {
- stdout_mode = newmode;
- oflush();
- VOID setmode(STDOUT_FILENO, newmode);
- }
-# endif
- neworkname = 0;
- neworkptr = workstdout = stdout;
- } else {
- workstatstat = stat(workname, &workstat);
- if (workstatstat == 0 && same_file(RCSstat, workstat, 0)) {
- rcserror("RCS file is the same as working file %s.",
- workname
- );
- continue;
- }
- neworkname = makedirtemp(1);
- if (!(neworkptr = fopenSafer(neworkname, FOPEN_W_WORK))) {
- if (errno == EACCES)
- workerror("permission denied on parent directory");
- else
- eerror(neworkname);
- continue;
- }
- }
-
- gettree(); /* reads in the delta tree */
-
- if (!Head) {
- /* no revisions; create empty file */
- diagnose("no revisions present; generating empty revision 0.0\n");
- if (lockflag)
- warn(
- "no revisions, so nothing can be %slocked",
- lockflag < 0 ? "un" : ""
- );
- Ozclose(&fcopy);
- if (workstatstat == 0)
- if (!rmworkfile()) continue;
- changelock = 0;
- newdate = 0;
- } else {
- int locks = lockflag ? findlock(false, &targetdelta) : 0;
- if (rev) {
- /* expand symbolic revision number */
- if (!expandsym(rev, &numericrev))
- continue;
- } else {
- switch (locks) {
- default:
- continue;
- case 0:
- bufscpy(&numericrev, Dbranch?Dbranch:"");
- break;
- case 1:
- bufscpy(&numericrev, targetdelta->num);
- break;
- }
- }
- /* get numbers of deltas to be generated */
- if (!(targetdelta=genrevs(numericrev.string,date,author,state,&gendeltas)))
- continue;
- /* check reservations */
- changelock =
- lockflag < 0 ?
- rmlock(targetdelta)
- : lockflag == 0 ?
- 0
- :
- addlock(targetdelta, true);
-
- if (
- changelock < 0
- || (changelock && !checkaccesslist())
- || dorewrite(lockflag, changelock) != 0
- )
- continue;
-
- if (0 <= expmode)
- Expand = expmode;
- if (0 < lockflag && Expand == VAL_EXPAND) {
- rcserror("cannot combine -kv and -l");
- continue;
- }
-
- if (joinflag && !preparejoin(joinflag))
- continue;
-
- diagnose("revision %s%s\n",targetdelta->num,
- 0<lockflag ? " (locked)" :
- lockflag<0 ? " (unlocked)" : "");
-
- /* Prepare to remove old working file if necessary. */
- if (workstatstat == 0)
- if (!rmworkfile()) continue;
-
- /* skip description */
- getdesc(false); /* don't echo*/
-
- locker_expansion = 0 < lockflag;
- targetdelta->name = namedrev(rev, targetdelta);
- joinname = buildrevision(
- gendeltas, targetdelta,
- joinflag&&tostdout ? (FILE*)0 : neworkptr,
- Expand < MIN_UNEXPAND
- );
-# if !large_memory
- if (fcopy == neworkptr)
- fcopy = 0; /* Don't close it twice. */
-# endif
- if_advise_access(changelock && gendeltas->first!=targetdelta,
- finptr, MADV_SEQUENTIAL
- );
-
- if (donerewrite(changelock,
- Ttimeflag ? RCSstat.st_mtime : (time_t)-1
- ) != 0)
- continue;
-
- if (changelock) {
- locks += lockflag;
- if (1 < locks)
- rcswarn("You now have %d locks.", locks);
- }
-
- newdate = targetdelta->date;
- if (joinflag) {
- newdate = 0;
- if (!joinname) {
- aflush(neworkptr);
- joinname = neworkname;
- }
- if (Expand == BINARY_EXPAND)
- workerror("merging binary files");
- if (!buildjoin(joinname))
- continue;
- }
- }
- if (!tostdout) {
- mode_t m = WORKMODE(RCSstat.st_mode,
- ! (Expand==VAL_EXPAND || (lockflag<=0 && StrictLocks))
- );
- time_t t = mtimeflag&&newdate ? date2time(newdate) : (time_t)-1;
- aflush(neworkptr);
- ignoreints();
- r = chnamemod(&neworkptr, neworkname, workname, 1, m, t);
- keepdirtemp(neworkname);
- restoreints();
- if (r != 0) {
- eerror(workname);
- error("see %s", neworkname);
- continue;
- }
- diagnose("done\n");
- }
- }
-
- tempunlink();
- Ofclose(workstdout);
- exitmain(exitstatus);
-
-} /* end of main (co) */
-
- static void
-cleanup()
-{
- if (nerror) exitstatus = EXIT_FAILURE;
- Izclose(&finptr);
- ORCSclose();
-# if !large_memory
- if (fcopy!=workstdout) Ozclose(&fcopy);
-# endif
- if (neworkptr!=workstdout) Ozclose(&neworkptr);
- dirtempunlink();
-}
-
-#if RCS_lint
-# define exiterr coExit
-#endif
- void
-exiterr()
-{
- ORCSerror();
- dirtempunlink();
- tempunlink();
- _exit(EXIT_FAILURE);
-}
-
-
-/*****************************************************************
- * The following routines are auxiliary routines
- *****************************************************************/
-
- static int
-rmworkfile()
-/*
- * Prepare to remove workname, if it exists, and if
- * it is read-only.
- * Otherwise (file writable):
- * if !quietmode asks the user whether to really delete it (default: fail);
- * otherwise failure.
- * Returns true if permission is gotten.
- */
-{
- if (workstat.st_mode&(S_IWUSR|S_IWGRP|S_IWOTH) && !forceflag) {
- /* File is writable */
- if (!yesorno(false, "writable %s exists%s; remove it? [ny](n): ",
- workname,
- myself(workstat.st_uid) ? "" : ", and you do not own it"
- )) {
- error(!quietflag && ttystdin()
- ? "checkout aborted"
- : "writable %s exists; checkout aborted", workname);
- return false;
- }
- }
- /* Actual unlink is done later by caller. */
- return true;
-}
-
-
- static int
-rmlock(delta)
- struct hshentry const *delta;
-/* Function: removes the lock held by caller on delta.
- * Returns -1 if someone else holds the lock,
- * 0 if there is no lock on delta,
- * and 1 if a lock was found and removed.
- */
-{ register struct rcslock * next, * trail;
- char const *num;
- struct rcslock dummy;
- int whomatch, nummatch;
-
- num=delta->num;
- dummy.nextlock=next=Locks;
- trail = &dummy;
- while (next) {
- whomatch = strcmp(getcaller(), next->login);
- nummatch=strcmp(num,next->delta->num);
- if ((whomatch==0) && (nummatch==0)) break;
- /*found a lock on delta by caller*/
- if ((whomatch!=0)&&(nummatch==0)) {
- rcserror("revision %s locked by %s; use co -r or rcs -u",
- num, next->login
- );
- return -1;
- }
- trail=next;
- next=next->nextlock;
- }
- if (next) {
- /*found one; delete it */
- trail->nextlock=next->nextlock;
- Locks=dummy.nextlock;
- next->delta->lockedby = 0;
- return 1; /*success*/
- } else return 0; /*no lock on delta*/
-}
-
-
-
-
-/*****************************************************************
- * The rest of the routines are for handling joins
- *****************************************************************/
-
-
- static char *
-addjoin(joinrev)
- char *joinrev;
-/* Add joinrev's number to joinlist, yielding address of char past joinrev,
- * or 0 if no such revision exists.
- */
-{
- register char *j;
- register struct hshentry *d;
- char terminator;
- struct buf numrev;
- struct hshentries *joindeltas;
-
- j = joinrev;
- for (;;) {
- switch (*j++) {
- default:
- continue;
- case 0:
- case ' ': case '\t': case '\n':
- case ':': case ',': case ';':
- break;
- }
- break;
- }
- terminator = *--j;
- *j = 0;
- bufautobegin(&numrev);
- d = 0;
- if (expandsym(joinrev, &numrev))
- d = genrevs(numrev.string,(char*)0,(char*)0,(char*)0,&joindeltas);
- bufautoend(&numrev);
- *j = terminator;
- if (d) {
- joinlist[++lastjoin] = d->num;
- return j;
- }
- return 0;
-}
-
- static int
-preparejoin(j)
- register char *j;
-/* Parse join list J and place pointers to the
- * revision numbers into joinlist.
- */
-{
- lastjoin= -1;
- for (;;) {
- while ((*j==' ')||(*j=='\t')||(*j==',')) j++;
- if (*j=='\0') break;
- if (lastjoin>=joinlength-2) {
- joinlist =
- (joinlength *= 2) == 0
- ? tnalloc(char const *, joinlength = 16)
- : trealloc(char const *, joinlist, joinlength);
- }
- if (!(j = addjoin(j))) return false;
- while ((*j==' ') || (*j=='\t')) j++;
- if (*j == ':') {
- j++;
- while((*j==' ') || (*j=='\t')) j++;
- if (*j!='\0') {
- if (!(j = addjoin(j))) return false;
- } else {
- rcsfaterror("join pair incomplete");
- }
- } else {
- if (lastjoin==0) { /* first pair */
- /* common ancestor missing */
- joinlist[1]=joinlist[0];
- lastjoin=1;
- /*derive common ancestor*/
- if (!(joinlist[0] = getancestor(targetdelta->num,joinlist[1])))
- return false;
- } else {
- rcsfaterror("join pair incomplete");
- }
- }
- }
- if (lastjoin < 1)
- rcsfaterror("empty join");
- return true;
-}
-
-
-
- static char const *
-getancestor(r1, r2)
- char const *r1, *r2;
-/* Yield the common ancestor of r1 and r2 if successful, 0 otherwise.
- * Work reliably only if r1 and r2 are not branch numbers.
- */
-{
- static struct buf t1, t2;
-
- int l1, l2, l3;
- char const *r;
-
- l1 = countnumflds(r1);
- l2 = countnumflds(r2);
- if ((2<l1 || 2<l2) && cmpnum(r1,r2)!=0) {
- /* not on main trunk or identical */
- l3 = 0;
- while (cmpnumfld(r1, r2, l3+1)==0 && cmpnumfld(r1, r2, l3+2)==0)
- l3 += 2;
- /* This will terminate since r1 and r2 are not the same; see above. */
- if (l3==0) {
- /* no common prefix; common ancestor on main trunk */
- VOID partialno(&t1, r1, l1>2 ? 2 : l1);
- VOID partialno(&t2, r2, l2>2 ? 2 : l2);
- r = cmpnum(t1.string,t2.string)<0 ? t1.string : t2.string;
- if (cmpnum(r,r1)!=0 && cmpnum(r,r2)!=0)
- return r;
- } else if (cmpnumfld(r1, r2, l3+1)!=0)
- return partialno(&t1,r1,l3);
- }
- rcserror("common ancestor of %s and %s undefined", r1, r2);
- return 0;
-}
-
-
-
- static int
-buildjoin(initialfile)
- char const *initialfile;
-/* Function: merge pairs of elements in joinlist into initialfile
- * If workstdout is set, copy result to stdout.
- * All unlinking of initialfile, rev2, and rev3 should be done by tempunlink().
- */
-{
- struct buf commarg;
- struct buf subs;
- char const *rev2, *rev3;
- int i;
- char const *cov[10], *mergev[11];
- char const **p;
-
- bufautobegin(&commarg);
- bufautobegin(&subs);
- rev2 = maketemp(0);
- rev3 = maketemp(3); /* buildrevision() may use 1 and 2 */
-
- cov[1] = CO;
- /* cov[2] setup below */
- p = &cov[3];
- if (expandarg) *p++ = expandarg;
- if (suffixarg) *p++ = suffixarg;
- if (versionarg) *p++ = versionarg;
- if (zonearg) *p++ = zonearg;
- *p++ = quietarg;
- *p++ = RCSname;
- *p = 0;
-
- mergev[1] = MERGE;
- mergev[2] = mergev[4] = "-L";
- /* rest of mergev setup below */
-
- i=0;
- while (i<lastjoin) {
- /*prepare marker for merge*/
- if (i==0)
- bufscpy(&subs, targetdelta->num);
- else {
- bufscat(&subs, ",");
- bufscat(&subs, joinlist[i-2]);
- bufscat(&subs, ":");
- bufscat(&subs, joinlist[i-1]);
- }
- diagnose("revision %s\n",joinlist[i]);
- bufscpy(&commarg, "-p");
- bufscat(&commarg, joinlist[i]);
- cov[2] = commarg.string;
- if (runv(-1, rev2, cov))
- goto badmerge;
- diagnose("revision %s\n",joinlist[i+1]);
- bufscpy(&commarg, "-p");
- bufscat(&commarg, joinlist[i+1]);
- cov[2] = commarg.string;
- if (runv(-1, rev3, cov))
- goto badmerge;
- diagnose("merging...\n");
- mergev[3] = subs.string;
- mergev[5] = joinlist[i+1];
- p = &mergev[6];
- if (quietflag) *p++ = quietarg;
- if (lastjoin<=i+2 && workstdout) *p++ = "-p";
- *p++ = initialfile;
- *p++ = rev2;
- *p++ = rev3;
- *p = 0;
- switch (runv(-1, (char*)0, mergev)) {
- case DIFF_FAILURE: case DIFF_SUCCESS:
- break;
- default:
- goto badmerge;
- }
- i=i+2;
- }
- bufautoend(&commarg);
- bufautoend(&subs);
- return true;
-
- badmerge:
- nerror++;
- bufautoend(&commarg);
- bufautoend(&subs);
- return false;
-}
diff --git a/gnu/usr.bin/rcs/doc/rcs.ms b/gnu/usr.bin/rcs/doc/rcs.ms
deleted file mode 100644
index f6b0db3..0000000
--- a/gnu/usr.bin/rcs/doc/rcs.ms
+++ /dev/null
@@ -1,1518 +0,0 @@
-.\" Format this file with:
-.\" pic file | tbl | troff -ms
-.\"
-.\" \*s stands for $, and avoids problems when this file is checked in.
-.ds s $
-.de D(
-.DS
-.nr VS 12p
-.vs 12p
-.I
-..
-.de D)
-.DE
-.nr VS 18p
-.vs 18p
-.R
-..
-.de Id
-.ND \\$4
-..
-.Id $FreeBSD$
-.RP
-.TL
-RCS\*-A System for Version Control
-.sp
-.AU
-Walter F. Tichy
-.AI
-Department of Computer Sciences
-Purdue University
-West Lafayette, Indiana 47907
-.sp
-.AB
-An important problem in program development and maintenance is version control,
-i.e., the task of keeping a software system consisting of many versions and
-configurations well organized.
-The Revision Control System (RCS)
-is a software tool that assists with that task.
-RCS manages revisions of text documents, in particular source programs,
-documentation, and test data.
-It automates the storing, retrieval, logging and identification of revisions,
-and it provides selection mechanisms for composing configurations.
-This paper introduces basic version control concepts and
-discusses the practice of version control
-using RCS.
-For conserving space, RCS stores deltas, i.e., differences between
-successive revisions. Several delta storage methods are discussed.
-Usage statistics show that RCS's delta storage method is
-space and time efficient.
-The paper concludes with a detailed survey of version control tools.
-.sp
-\fBKeywords\fR: configuration management, history management,
-version control, revisions, deltas.
-.AE
-.FS
-An earlier version of this paper was published in
-.I "Software\*-Practice & Experience"
-.B 15 ,
-7 (July 1985), 637-654.
-.FE
-.nr VS 18p
-.LP
-.NH
-Introduction
-.PP
-Version control is the task of keeping software
-systems consisting of many versions and configurations well organized.
-The Revision Control System (RCS) is a set of UNIX
-commands that assist with that task.
-.PP
-RCS' primary function is to manage \fIrevision groups\fR.
-A revision group is a set of text documents, called \fIrevisions\fR,
-that evolved from each other. A new revision is
-created by manually editing an existing one.
-RCS organizes the revisions into an ancestral tree. The initial revision
-is the root of the tree, and the tree edges indicate
-from which revision a given one evolved.
-Besides managing individual revision groups, RCS provides
-flexible selection functions for composing configurations.
-RCS may be combined with MAKE\u1\d,
-resulting in a powerful package for version control.
-.PP
-RCS also offers facilities for
-merging updates with customer modifications,
-for distributed software development, and
-for automatic identification.
-Identification is the `stamping'
-of revisions and configurations with unique markers.
-These markers are akin to serial numbers,
-telling software maintainers unambiguously which configuration
-is before them.
-.PP
-RCS is designed for both production and experimental
-environments.
-In production environments,
-access controls detect update conflicts and prevent overlapping changes.
-In experimental environments, where strong controls are
-counterproductive, it is possible to loosen the controls.
-.PP
-Although RCS was originally intended for programs, it is useful for any
-text that is revised frequently and whose previous revisions must be
-preserved. RCS has been applied successfully to store the source
-text for drawings, VLSI layouts, documentation, specifications,
-test data, form letters and articles.
-.PP
-This paper discusses the practice of
-version control using RCS.
-It also introduces basic version control concepts,
-useful for clarifying current practice and designing similar systems.
-Revision groups of individual components are treated in the next three sections,
-and the extensions to configurations follow.
-Because of its size, a survey of version control tools
-appears at the end of the paper.
-.NH
-Getting started with RCS
-.PP
-Suppose a text file \fIf.c\fR is to be placed under control of RCS.
-Invoking the check-in command
-.D(
-ci f.c
-.D)
-creates a new revision group with the contents of
-\fIf.c\fR as the initial
-revision (numbered 1.1)
-and stores the group into the file \fIf.c,v\fR.
-Unless told otherwise, the command deletes \fIf.c\fR.
-It also asks for a description of the group.
-The description should state the common purpose of all revisions in the group,
-and becomes part of the group's documentation.
-All later check-in commands will ask for a log entry,
-which should summarize the changes made.
-(The first revision is assigned a default log message,
-which just records the fact that it is the initial revision.)
-.PP
-Files ending in \fI,v\fR
-are called \fIRCS files\fR (\fIv\fR stands for \fIv\fRersions);
-the others are called working files.
-To get back the working file \fIf.c\fR in the previous example,
-execute the check-out command:
-.D(
-co f.c
-.D)
-.R
-This command extracts the latest revision from
-the revision group \fIf.c,v\fR and writes
-it into \fIf.c\fR.
-The file \fIf.c\fR can now be edited and, when finished,
-checked back in with \fIci\fR:
-.D(
-ci f.c
-.D)
-\fICi\fR assigns number 1.2 to
-the new revision.
-If \fIci\fR complains with the message
-.D(
-ci error: no lock set by <login>
-.D)
-then the system administrator has decided to configure RCS for a
-production environment by enabling the `strict locking feature'.
-If this feature is enabled, all RCS files are initialized
-such that check-in operations require a lock on the previous revision
-(the one from which the current one evolved).
-Locking prevents overlapping modifications if several people work on the same file.
-If locking is required, the revision should
-have been locked during the check-out by using
-the option \fI\-l\fR:
-.D(
-co \-l f.c
-.D)
-Of course it is too late now for the check-out with locking, because
-\fIf.c\fR has already been changed; checking out the file again
-would overwrite the modifications.
-(To prevent accidental overwrites, \fIco\fR senses the presence
-of a working file and asks whether the user really intended to overwrite it.
-The overwriting check-out is sometimes useful for
-backing up to the previous revision.)
-To be able to proceed with the check-in in the present case, first execute
-.D(
-rcs \-l f.c
-.D)
-This command retroactively locks the latest revision, unless someone
-else locked it in the meantime. In this case, the two programmers
-involved have to negotiate whose
-modifications should take precedence.
-.PP
-If an RCS file is private, i.e., if only the owner of the file is expected
-to deposit revisions into it, the strict locking feature is unnecessary and
-may be disabled.
-If strict locking is disabled,
-the owner of the RCS file need not have a lock for check-in.
-For safety reasons, all others
-still do. Turning strict locking off and on is done with the commands:
-.D(
-rcs \-U f.c \fRand\fP rcs \-L f.c
-.D)
-These commands enable or disable the strict locking feature for each RCS file
-individually.
-The system administrator only decides whether strict locking is
-enabled initially.
-.PP
-To reduce the clutter in a working directory, all RCS files can be moved
-to a subdirectory with the name \fIRCS\fR.
-RCS commands look first into that directory for RCS files.
-All the commands presented above work
-with the \fIRCS\fR subdirectory without change.\(dg
-.FS \(dg
-Pairs of RCS and working files can actually be specified in 3 ways:
-a) both are given, b) only the working file is given, c) only the
-RCS file is given.
-If a pair is given, both files may have arbitrary path prefixes;
-RCS commands pair them up intelligently.
-.FE
-.PP
-It may be undesirable that \fIci\fR deletes the working file.
-For instance, sometimes one would like to save the current revision,
-but continue editing.
-Invoking
-.D(
-ci \-l f.c
-.D)
-checks in \fIf.c\fR as usual, but performs an additional
-check-out with locking afterwards. Thus, the working file does
-not disappear after the check-in.
-Similarly, the option
-\fI\-u\fR does a check-in followed by a check-out without
-locking. This option is useful if the file is needed for compilation after the check-in.
-Both options update the identification markers in the working file
-(see below).
-.PP
-Besides the operations \fIci\fR and \fIco\fR, RCS provides the following
-commands:
-.sp 0
-.nr VS 12p
-.vs 12p
-.TS
-tab(%);
-li l.
-ident%extract identification markers
-rcs%change RCS file attributes
-rcsclean%remove unchanged working files (optional)
-rcsdiff%compare revisions
-rcsfreeze%record a configuration (optional)
-rcsmerge%merge revisions
-rlog%read log messages and other information in RCS files
-.TE
-A synopsis of these commands appears in the Appendix.
-.NH 2
-Automatic Identification
-.PP
-RCS can stamp source and object code with special identification strings,
-similar to product and serial numbers.
-To obtain such identification, place the marker
-.D(
-\*sId\*s
-.D)
-into the text of a revision, for instance inside a comment.
-The check-out operation will replace this marker with a string of the form
-.D(
-\*sId: filename revisionnumber date time author state locker \*s
-.D)
-This string need never be touched, because \fIco\fR keeps it
-up to date automatically.
-To propagate the marker into object code, simply put
-it into a literal character string. In C, this is done as follows:
-.D(
-static char rcsid[] = \&"\*sId\*s\&";
-.D)
-The command \fIident\fR extracts such markers from any file, in particular from
-object code.
-\fIIdent\fR helps to find out
-which revisions of which modules were used in a given program.
-It returns a complete and unambiguous component list,
-from which a copy of the program can be reconstructed.
-This facility is invaluable for program maintenance.
-.PP
-There are several additional identification markers, one for each component
-of \*sId\*s.
-The marker
-.D(
-\*sLog\*s
-.D)
-has a similar function. It accumulates
-the log messages that are requested during check-in.
-Thus, one can maintain the complete history of a revision directly inside it,
-by enclosing it in a comment.
-Figure 1 is an edited version of a log contained in revision 4.1 of
-the file \fIci.c\fR. The log appears at the beginning of the file,
-and makes it easy to determine what the recent modifications were.
-.sp
-.nr VS 12p
-.vs 12p
-.ne 18
-.nf
-.in +0.5i
-/*
-.in +\w'/'u
-* \*sLog: ci.c,v \*s
-* Revision 4.1 1983/05/10 17:03:06 wft
-* Added option \-d and \-w, and updated assignment of date, etc. to new delta.
-* Added handling of default branches.
-*
-* Revision 3.9 1983/02/15 15:25:44 wft
-* Added call to fastcopy() to copy remainder of RCS file.
-*
-* Revision 3.8 1983/01/14 15:34:05 wft
-* Added ignoring of interrupts while new RCS file is renamed;
-* avoids deletion of RCS files by interrupts.
-*
-* Revision 3.7 1982/12/10 16:09:20 wft
-* Corrected checking of return code from diff.
-* An RCS file now inherits its mode during the first ci from the working file,
-* except that write permission is removed.
-*/
-.in 0
-.ce 1
-Figure 1. Log entries produced by the marker \*sLog\*s.
-.fi
-.nr VS 18p
-.vs 18p
-.sp 0
-.LP
-Since revisions are stored in the form of differences,
-each log message is
-physically stored once,
-independent of the number of revisions present.
-Thus, the \*sLog\*s marker incurs negligible space overhead.
-.NH
-The RCS Revision Tree
-.PP
-RCS arranges revisions in an ancestral tree.
-The \fIci\fR command builds this tree; the auxiliary command \fIrcs\fR
-prunes it.
-The tree has a root revision, normally numbered 1.1, and successive revisions
-are numbered 1.2, 1.3, etc. The first field of a revision number
-is called the \fIrelease number\fR and the second one
-the \fIlevel number\fR. Unless given explicitly,
-the \fIci\fR command assigns a new revision number
-by incrementing the level number of the previous revision.
-The release number must be incremented explicitly, using the
-\fI\-r\fR option of \fIci\fR.
-Assuming there are revisions 1.1, 1.2, and 1.3 in the RCS file f.c,v, the command
-.D(
-ci \-r2.1 f.c \fRor\fP ci \-r2 f.c
-.D)
-assigns the number 2.1 to the new revision.
-Later check-ins without the \fI\-r\fR option will assign the numbers 2.2, 2.3,
-and so on.
-The release number should be incremented only at major transition points
-in the development, for instance when a new release of a software product has
-been completed.
-.NH 2
-When are branches needed?
-.PP
-A young revision tree is slender:
-It consists of only one branch, called the trunk.
-As the tree ages, side branches may form.
-Branches are needed in the following 4 situations.
-.IP "\fITemporary fixes\fR"
-.sp 0
-Suppose a tree has 5 revisions grouped in 2 releases,
-as illustrated in Figure 2.
-Revision 1.3, the last one of release 1, is in operation at customer sites,
-while release 2 is in active development.
-.ne 4
-.PS 4i
-.ps -2
-box "1.1"
-arrow
-box "1.2"
-arrow
-box "1.3"
-arrow
-box "2.1"
-arrow
-box "2.2"
-arrow dashed
-.ps +2
-.PE
-.ce 1
-Figure 2. A slender revision tree.
-.sp 0
-Now imagine a customer requesting a fix of
-a problem in revision 1.3, although actual development has moved on
-to release 2. RCS does not permit an extra
-revision to be spliced in between 1.3 and 2.1, since that would not reflect
-the actual development history. Instead, create a branch
-at revision 1.3, and check in the fix on that branch.
-The first branch starting at 1.3 has number 1.3.1, and
-the revisions on that branch are numbered 1.3.1.1, 1.3.1.2, etc.
-The double numbering is needed to allow for another
-branch at 1.3, say 1.3.2.
-Revisions on the second branch would be numbered
-1.3.2.1, 1.3.2.2, and so on.
-The following steps create
-branch 1.3.1 and add revision 1.3.1.1:
-.sp 0
-.I
-.nr VS 12p
-.vs 12p
-.TS
-tab(%);
-l l l.
- %co \-r1.3 f.c% \*- check out revision 1.3
- %edit f.c% \*- change it
- %ci \-r1.3.1 f.c% \*- check it in on branch 1.3.1
-.TE
-.nr VS 18p
-.vs 18p
-.R
-This sequence of commands transforms the tree of Figure 2 into
-the one in Figure 3.
-Note that it may be necessary to incorporate the differences
-between 1.3 and 1.3.1.1
-into a revision at level 2. The operation \fIrcsmerge\fR automates this
-process (see the Appendix).
-.ne 7
-.PS 4i
-.ps -2
- box "1.1"
- arrow
- box "1.2"
- arrow
-R13: box "1.3"
- arrow
-R21: box "2.1"
- arrow
-R22: box "2.2"
- arrow dashed
- line invis down from R21.s
-RB1: box "1.3.1.1"
- arrow dashed right from RB1.e
- arrow from R13.s to RB1.w
-.ps +2
-.PE
-.ce 1
-Figure 3. A revision tree with one side branch
-.sp
-.IP "\fIDistributed development and customer modifications\fR"
-.sp 0
-Assume a situation as in Figure 2, where revision 1.3 is in operation
-at several customer sites,
-while release 2 is in development.
-Customer sites should use RCS to store the distributed software.
-However, customer modifications should not be placed on the same branch
-as the distributed source; instead, they should be placed on a side branch.
-When the next software distribution arrives,
-it should be appended to the trunk of
-the customer's RCS file, and the customer
-can then merge the local modifications back into the new release.
-In the above example, a
-customer's RCS file would contain the following tree, assuming
-that the customer has received revision 1.3, added his local modifications
-as revision 1.3.1.1, then received revision 2.4, and merged
-2.4 and 1.3.1.1, resulting in 2.4.1.1.
-.ne 7
-.PS 4i
-.ps -2
-R13: box "1.3"
- line invis
-R21: box invis
- line invis
-R22: box invis
- line invis
-R24: box "2.4"
- line invis
-R25: box invis
- line invis
- arrow from R13.e to R24.w
- line invis down from R21.s
-RB1: box "1.3.1.1"
- arrow from R13.s to RB1.w
- right
- line invis down from R25.s
-RB2: box "2.4.1.1"
- arrow from R24.s to RB2.w
-.ps +2
-.PE
-.ce 1
-Figure 4. A customer's revision tree with local modifications.
-.sp 1
-This approach is actually practiced in the CSNET project,
-where several universities and a company cooperate
-in developing a national computer network.
-.IP "\fIParallel development\fR"
-.sp 0
-Sometimes it is desirable to explore an alternate design or
-a different implementation technique in parallel with the
-main line development. Such development
-should be carried out on a side branch.
-The experimental changes may later be moved into the main line, or abandoned.
-.IP "\fIConflicting updates\fR"
-.sp 0
-A common occurrence is that one programmer
-has checked out a revision, but cannot complete the assignment
-for some reason. In the meantime, another person
-must perform another modification
-immediately. In that case, the second person should check-out the same revision,
-modify it, and check it in on a side branch, for later merging.
-.PP
-Every node in a revision tree consists of the following attributes:
-a revision number, a check-in date and time, the author's identification,
-a log entry, a state and the actual text. All these attributes
-are determined at the time the revision is checked in.
-The state attribute indicates the status of a revision.
-It is set automatically to `experimental' during check-in.
-A revision can later be promoted to a higher status, for example
-`stable' or `released'. The set of states is user-defined.
-.NH 2
-Revisions are represented as deltas
-.PP
-For conserving space, RCS stores revisions in the form
-of deltas, i.e., as differences between revisions.
-The user interface completely hides this fact.
-.PP
-A delta is a sequence of edit commands that transforms one string
-into another. The deltas employed by RCS are line-based, which means
-that the only edit commands allowed are insertion and deletion of lines.
-If a single character in a line is changed, the
-edit scripts consider the entire line changed.
-The program \fIdiff\fR\u2\d
-produces a small, line-based delta between pairs of text files.
-A character-based edit script would take much longer to compute,
-and would not be significantly shorter.
-.PP
-Using deltas is a classical space-time tradeoff: deltas reduce the
-space consumed, but increase access time.
-However, a version control tool should impose as little delay
-as possible on programmers.
-Excessive delays discourage the use of version controls,
-or induce programmers to take shortcuts that compromise system integrity.
-To gain reasonably fast access time for both editing and compiling,
-RCS arranges deltas in the following way.
-The most recent revision on the trunk is stored intact.
-All other revisions on the trunk are stored as reverse deltas.
-A reverse delta describes how to go backward in the development history:
-it produces the desired revision if applied to the successor of that revision.
-This implementation has the advantage
-that extraction of the latest revision is a simple and fast copy
-operation.
-Adding a new revision to the trunk is also fast: \fIci\fR simply
-adds the new revision intact, replaces the previous
-revision with a reverse delta, and keeps the rest of the old deltas.
-Thus, \fIci\fR requires the computation
-of only one new delta.
-.PP
-Branches need special treatment. The naive solution would be to
-store complete copies for the tips of all branches.
-Clearly, this approach would cost too much space. Instead,
-RCS uses \fIforward\fR deltas for branches. Regenerating a revision
-on a side branch proceeds as follows. First, extract the latest revision
-on the trunk; secondly, apply reverse deltas until the fork revision for
-the branch is obtained; thirdly, apply forward deltas until the desired
-branch revision is reached. Figure 5 illustrates a tree with
-one side branch. Triangles pointing to the left and right represent
-reverse and forward deltas, respectively.
-.ne 8
-.PS 4i
-.ps -2
-define BD X [line invis $1 right .5;
-line up .3 then left .5 down .3 then right .5 down .3 then up .3] X
-
-define FD X [line invis $1 right .5;
-line left .5 down .3 then up .6 then right .5 down .3;] X
-
-right
-D11: BD(" 1.1")
- arrow right from D11.e
-D12: BD(" 1.2")
- arrow right from D12.e
-D13: BD(" 1.3")
- arrow right from D13.e
-D21: BD(" 2.1")
- arrow right from D21.e
-D22: box "2.2"
- line invis down from D21.s
-F1: FD("1.3.1.1 ")
- arrow from D13.se to F1.w
- arrow from F1.e right
- right
-F2: FD("1.3.1.2 ")
-.ps +2
-.PE
-.ce 1
-Figure 5. A revision tree with reverse and forward deltas.
-.sp 0
-.PP
-Although implementing fast check-out for the latest trunk revision,
-this arrangement has the disadvantage that generation of other revisions
-takes time proportional to the number of deltas applied. For example,
-regenerating the branch tip in Figure 5 requires application of five
-deltas (including the initial one). Since usage statistics show that
-the latest trunk revision is the one that is retrieved in 95 per cent
-of all cases (see the section on usage statistics), biasing check-out time
-in favor of that revision results in significant savings.
-However, careful implementation of the delta application process is
-necessary to provide low retrieval overhead for other revisions, in
-particular for branch tips.
-.PP
-There are several techniques for delta application.
-The naive one is to pass each delta to a general-purpose text editor.
-A prototype of RCS invoked the UNIX editor \fIed\fR both
-for applying deltas and for expanding the identification markers.
-Although easy to implement, performance was poor, owing to the
-high start-up costs and excess generality of \fIed\fR. An intermediate
-version of RCS used a special-purpose, stream-oriented editor.
-This technique reduced the cost of applying a delta to the cost of
-checking out the latest trunk revision. The reason for this behavior
-is that each delta application involves a complete pass over
-the preceding revision.
-.PP
-However, there is a much better algorithm. Note that the deltas are
-line oriented and that most of the work of a stream editor involves
-copying unchanged lines from one revision to the next. A faster
-algorithm avoids unnecessary copying of character strings by using
-a \fIpiece table\fR.
-A piece table is a one-dimensional array, specifying how a given
-revision is `pieced together' from lines in the RCS file.
-Suppose piece table \fIPT\dr\u\fR represents revision \fIr\fR.
-Then \fIPT\dr\u[i]\fR contains the starting position of line \fIi\fR
-of revision \fIr\fR.
-Application of the next delta transforms piece table \fIPT\dr\u\fR
-into \fIPT\dr+1\u\fR. For instance, a delete command removes a
-series of entries from the piece table. An insertion command inserts
-new entries, moving the entries following the insertion point further down the
-array. The inserted entries point to the text lines in the delta.
-Thus, no I/O is involved except for reading the delta itself. When all
-deltas have been applied to the piece table, a sequential pass
-through the table looks up each line in the RCS file and copies it to
-the output file, updating identification markers at the same time.
-Of course, the RCS file must permit random access, since the copied
-lines are scattered throughout that file. Figure 6 illustrates an
-RCS file with two revisions and the corresponding piece tables.
-.ne 13
-.sp 6
-.ce 1
-\fIFigure 6 is not available.\fP
-.sp 5
-.ce 1
-Figure 6. An RCS file and its piece tables
-.sp 0
-.PP
-The piece table approach has the property that the time for applying a single
-delta is roughly determined by the size of the delta, and not by the
-size of the revision. For example, if a delta is
-10 per cent of the size of a revision, then applying it takes only
-10 per cent of the time to generate the latest trunk revision. (The stream
-editor would take 100 per cent.)
-.PP
-There is an important alternative for representing deltas that affects
-performance. SCCS\u3\d,
-a precursor of RCS, uses \fIinterleaved\fR deltas.
-A file containing interleaved deltas is partitioned into blocks of lines.
-Each block has a header that specifies to which revision(s) the block
-belongs. The blocks are sorted out in such a way that a single
-pass over the file can pick up all the lines belonging to a given
-revision. Thus, the regeneration time for all revisions is the same:
-all headers must be inspected, and the associated blocks either copied
-or skipped. As the number of revisions increases, the cost of retrieving
-any revision is much higher than the cost of checking out the
-latest trunk revision with reverse deltas. A detailed comparison
-of SCCS's interleaved deltas and RCS's reverse deltas can be found
-in Reference 4.
-This reference considers the version of RCS with the
-stream editor only. The piece table method improves performance
-further, so that RCS is always faster than SCCS, except if 10
-or more deltas are applied.
-.PP
-Additional speed-up for both delta methods can be obtained by caching
-the most recently generated revision, as has been implemented in DSEE.\u5\d
-With caching, access time to frequently used revisions can approach normal file
-access time, at the cost of some additional space.
-.NH
-Locking: A Controversial Issue
-.PP
-The locking mechanism for RCS was difficult to design.
-The problem and its solution are first presented in their `pure' form,
-followed by a discussion of the complications
-caused by `real-world' considerations.
-.PP
-RCS must prevent two or more persons from depositing competing changes of the
-same revision.
-Suppose two programmers check out revision 2.4 and
-modify it. Programmer A checks in a revision before programmer B\&.
-Unfortunately, programmer B has not seen A's
-changes, so the effect is that A's changes are covered up by B's deposit.
-A's changes are not lost since all revisions
-are saved, but they are confined to a single revision.\(dd
-.FS \(dd
-Note that this problem is entirely different from the atomicity problem.
-Atomicity means that
-concurrent update operations on the same RCS file cannot be permitted,
-because that may result in inconsistent data.
-Atomic updates are essential (and implemented in RCS),
-but do not solve the conflict discussed here.
-.FE
-.PP
-This conflict is prevented in RCS by locking.
-Whenever someone intends to edit a revision (as opposed
-to reading or compiling it), the revision should be checked out
-and locked,
-using the \fI\-l\fR option on \fIco\fR. On subsequent check-in,
-\fIci\fR tests the lock and then removes it.
-At most one programmer at a time may
-lock a particular revision, and only this programmer may check in
-the succeeding revision.
-Thus, while a revision is locked, it is the exclusive responsibility
-of the locker.
-.PP
-An important maxim for software tools like RCS is that they must
-not stand in the way of making progress with a project.
-This consideration leads to several weakenings of the locking mechanism.
-First of all, even if a revision is locked, it can
-still be checked out. This is necessary if other people
-wish to compile or inspect the locked revision
-while the next one is in preparation. The only operations they
-cannot do are to lock the revision or to check in the succeeding one. Secondly,
-check-in operations on other branches in the RCS file are still possible; the
-locking of one revision does not affect any other revision.
-Thirdly, revisions are occasionally locked for a long period of time
-because a programmer is absent or otherwise unable to complete
-the assignment. If another programmer has to make a pressing change,
-there are the following three alternatives for making progress:
-a) find out who is holding the lock and ask that person to release it;
-b) check out the locked revision, modify it, check it
-in on a branch, and merge the changes later;
-c) break the lock. Breaking a lock leaves a highly visible
-trace, namely an electronic mail message that is sent automatically to the
-holder of the lock, recording the breaker and a commentary requested from him.
-Thus, breaking locks is tolerated under certain circumstances,
-but will not go unnoticed.
-Experience has shown that the automatic mail message attaches a high enough
-stigma to lock breaking,
-such that programmers break locks only in real emergencies,
-or when a co-worker resigns and leaves locked revisions behind.
-.PP
-If an RCS file is private, i.e., when a programmer owns an RCS file
-and does not expect anyone else to perform check-in operations,
-locking is an unnecessary nuisance.
-In this case,
-the `strict locking feature' discussed earlier may be disabled,
-provided that file protection
-is set such that only the owner may write the RCS file.
-This has the effect that only the owner can check-in revisions,
-and that no lock is needed for doing so.
-.PP
-As added protection,
-each RCS file contains an access list that specifies the users
-who may execute update operations. If an access list is empty,
-only normal UNIX file protection applies. Thus, the access list is
-useful for restricting the set of people who would otherwise have update
-permission. Just as with locking, the access list
-has no effect on read-only operations such as \fIco\fR. This approach
-is consistent with the UNIX philosophy of openness, which contributes
-to a productive software development environment.
-.NH
-Configuration Management
-.PP
-The preceding sections described how RCS deals with revisions of individual
-components; this section discusses how to handle configurations.
-A configuration is a set of revisions, where each revision comes
-from a different revision group, and the revisions are selected
-according to a certain criterion.
-For example,
-in order to build a functioning compiler, the `right'
-revisions from the scanner, the parser, the optimizer
-and the code generator must be combined.
-RCS, in conjunction with MAKE,
-provides a number of facilities to effect a smooth selection.
-.NH 2
-RCS Selection Functions
-.PP
-.IP "\fIDefault selection\fR"
-.sp 0
-During development, the usual selection criterion is to choose
-the latest revision of all components. The \fIco\fR command
-makes this selection by default. For example, the command
-.D(
-co *,v
-.D)
-retrieves the latest revision on the default branch of each RCS file
-in the current directory.
-The default branch is usually the trunk, but may be
-set to be a side branch.
-Side branches as defaults are needed in distributed software development,
-as discussed in the section on the RCS revision tree.
-.sp
-.IP "\fIRelease based selection\fR"
-.sp 0
-Specifying a release or branch number selects the latest revision in
-that release or branch.
-For instance,
-.D(
-co \-r2 *,v
-.D)
-retrieves the latest revision with release number 2 from each RCS file.
-This selection is convenient if a release has been completed and
-development has moved on to the next release.
-.sp
-.IP "\fIState and author based selection\fR"
-.sp 0
-If the highest level number within a given release number
-is not the desired one,
-the state attribute can help. For example,
-.D(
-co \-r2 \-sReleased *,v
-.D)
-retrieves the latest revision with release number 2 whose state attribute
-is `Released'.
-Of course, the state attribute has to be set appropriately, using the
-\fIci\fR or \fIrcs\fR commands.
-Another alternative is to select a revision by its author,
-using the \fI\-w\fR option.
-.sp
-.IP "\fIDate based selection\fR"
-.sp 0
-Revisions may also be selected by date.
-Suppose a release of an entire system was
-completed and current on March 4, at 1:00 p.m. local time. Then the command
-.D(
-co \-d'March 4, 1:00 pm LT' *,v
-.D)
-checks out all the components of that release, independent of the numbering.
-The \fI\-d\fR option specifies a `cutoff date', i.e.,
-the revision selected has a check-in date that
-is closest to, but not after the date given.
-.IP "\fIName based selection\fR"
-.sp 0
-The most powerful selection function is based on assigning symbolic
-names to revisions and branches.
-In large systems, a single release number or date is not sufficient
-to collect the appropriate revisions from all groups.
-For example, suppose one wishes to combine release 2
-of one subsystem and release 15 of another.
-Most likely, the creation dates of those releases differ also.
-Thus, a single revision number or date passed to the \fIco\fR command
-will not suffice to select the right revisions.
-Symbolic revision numbers solve this problem.
-Each RCS file may contain a set of symbolic names that are mapped
-to numeric revision numbers. For example, assume
-the symbol \fIV3\fR is bound to release number 2 in file \fIs,v\fR, and to
-revision number 15.9 in \fIt,v\fR.
-Then the single command
-.D(
-co \-rV3 s,v t,v
-.D)
-retrieves the latest revision of release 2 from \fIs,v\fR,
-and revision 15.9 from \fIt,v\fR.
-In a large system with many modules, checking out all
-revisions with one command greatly simplifies configuration management.
-.PP
-Judicious use of symbolic revision numbers helps with organizing
-large configurations.
-A special command, \fIrcsfreeze\fR,
-assigns a symbolic revision number to a selected revision
-in every RCS file.
-\fIRcsfreeze\fR effectively freezes a configuration.
-The assigned symbolic revision number selects all components
-of the configuration.
-If necessary, symbolic numbers
-may even be intermixed with numeric ones. Thus, \fIV3.5\fR in the
-above example
-would select revision 2.5 in \fIs,v\fR and branch 15.9.5 in \fIt,v\fR.
-.PP
-The options \fI\-r\fR, \fI\-s\fR, \fI\-w\fR and \fI\-d\fR
-may be combined. If a branch is given, the latest revision
-on that branch satisfying all conditions is retrieved;
-otherwise, the default branch is used.
-.NH 2
-Combining MAKE and RCS
-.PP
-MAKE\u1\d
-is a program that processes configurations.
-It is driven by configuration specifications
-recorded in a special file, called a `Makefile'.
-MAKE avoids redundant processing steps
-by comparing creation dates of source and processed objects.
-For example, when instructed to compile all
-modules of a given system, it only recompiles
-those source modules that were changed
-since they were processed last.
-.PP
-MAKE has been extended with an auto-checkout feature for RCS.*
-.FS *
-This auto-checkout extension is available only in some versions of MAKE,
-e.g. GNU MAKE.
-.FE
-When a certain file to be processed is not present,
-MAKE attempts a check-out operation.
-If successful, MAKE performs the required processing, and then deletes
-the checked out file to conserve space.
-The selection parameters discussed above can be passed to MAKE
-either as parameters, or directly embedded in the Makefile.
-MAKE has also been extended to search the subdirectory named \fIRCS\fR
-for needed files, rather than just the current working directory.
-However, if a working file is present, MAKE totally ignores the corresponding
-RCS file and uses the working file.
-(In newer versions of MAKE distributed by AT&T and others,
-auto-checkout can be
-achieved with the rule DEFAULT, instead of a special extension of MAKE.
-However, a file checked out by the rule DEFAULT
-will not be deleted after processing. \fIRcsclean\fR can be
-used for that purpose.)
-.PP
-With auto-checkout, RCS/MAKE can effect a selection rule
-especially tuned for multi-person software development and maintenance.
-In these situations,
-programmers should obtain configurations that consist of
-the revisions they have personally checked out plus the latest
-checked in revision of all other revision groups.
-This schema can be set up as follows.
-.PP
-Each programmer chooses a working directory
-and places into it a symbolic link, named \fIRCS\fR,
-to the directory containing the relevant RCS files.
-The symbolic link makes sure that \fIco\fR and \fIci\fR
-operations need only specify the working files, and that
-the Makefile need not be changed.
-The programmer then checks out the needed files and modifies them.
-If MAKE is invoked,
-it composes configurations by selecting those
-revisions that are checked out, and the rest from the
-subdirectory \fIRCS\fR.
-The latter selection may be controlled by a symbolic
-revision number or any of the other selection criteria.
-If there are several programmers editing in separate working directories,
-they are insulated from each other's changes until checking in their
-modifications.
-.PP
-Similarly, a maintainer can recreate an older configuration
-by starting to work in an empty working directory.
-During the initial MAKE invocation, all revisions are selected from RCS files.
-As the maintainer checks out files and modifies them,
-a new configuration is gradually built up.
-Every time MAKE is invoked, it substitutes the modified revisions
-into the configuration being manipulated.
-.PP
-A final application of RCS is to use it for storing Makefiles.
-Revision groups of Makefiles represent
-multiple versions of configurations.
-Whenever a configuration is baselined or distributed,
-the best approach is to unambiguously fix
-the configuration with a symbolic revision number by calling
-\fIrcsfreeze\fR,
-to embed that symbol into the Makefile, and to
-check in the Makefile (using the same symbolic revision number).
-With this approach, old configurations
-can be regenerated easily and reliably.
-.NH
-Usage Statistics
-.PP
-The following usage statistics were collected on two DEC VAX-11/780
-computers of the Purdue Computer Science Department. Both machines
-are mainly used for research purposes. Thus, the data
-reflect an environment in which the majority of projects
-involve prototyping and advanced software development,
-but relatively little long-term maintenance.
-.PP
-For the first experiment,
-the \fIci\fR and \fIco\fR operations were instrumented
-to log the number of backward and forward deltas applied.
-The data were collected during a 13 month period
-from Dec. 1982 to Dec. 1983.
-Table I summarizes the results.
-.sp 0
-.nr VS 12p
-.vs 12p
-.TS
-center,box,tab(#);
-c|c|c|c|c s|c s
-c|c|c|c|c s|c s
-l|n|n|n|n n|n n.
-Operation#Total#Total deltas#Mean deltas#Operations#Branch
- #operations #applied#applied#with >1 delta#operations
-_
-co # 7867# 9320#1.18#509#(6%)#203#(3%)
-ci # 3468# 2207#0.64# 85#(2%)# 75#(2%)
-ci & co#11335#11527#1.02#594#(5%)#278#(2%)
-.TE
-.ce 1
-Table I. Statistics for \fIco\fR and \fIci\fR operations.
-.nr VS 18p
-.vs 18p
-.PP
-The first two lines show statistics for check-out and check-in;
-the third line shows the combination.
-Recall that \fIci\fR performs an implicit check-out to obtain
-a revision for computing the delta.
-In all measures presented, the most recent revision (stored intact)
-counts as one delta. The number of deltas applied represents
-the number of passes necessary, where the first `pass' is a copying step.
-.PP
-Note that the check-out operation is executed more than
-twice as frequently as the check-in operation.
-The fourth column gives the mean number of deltas
-applied in all three cases.
-For \fIci\fR, the mean number of deltas applied is less
-than one.
-The reasons are that the initial check-in requires no delta at all, and that
-the only time \fIci\fR requires more than one delta is for branches.
-Column 5 shows the actual number of operations that applied more than one
-delta.
-The last column indicates that branches were not used often.
-.PP
-The last three columns demonstrate that the most recent trunk revision
-is by far the most frequently accessed.
-For RCS, check-out of
-this revision is a simple copy operation, which is the absolute minimum
-given the copy-semantics of \fIco\fR.
-Access to older revisions and branches
-is more common in non-academic environments,
-yet even if access to older deltas were an order
-of magnitude more frequent,
-the combined average number of deltas applied would still be below 1.2.
-Since RCS is faster than SCCS until up to 10 delta applications,
-reverse deltas are clearly the method of choice.
-.PP
-The second experiment, conducted in March of 1984,
-involved surveying the existing RCS files
-on our two machines. The goal was to determine the mean number of
-revisions per RCS file, as well as the space consumed by them.
-Table II shows the results. (Tables I and II were produced at different
-times and are unrelated.)
-.sp 0
-.nr VS 12p
-.vs 12p
-.TS
-center,box,tab(#);
-c | c | c | c | c | c | c
-c | c | c | c | c | c | c
-l | n | n | n | n | n | n.
- #Total RCS#Total#Mean#Mean size of#Mean size of#Overhead
- #files#revisions#revisions#RCS files#revisions
-_
-All files #8033#11133#1.39#6156#5585#1.10
-Files with#1477# 4578#3.10#8074#6041#1.34
-\(>= 2 deltas
-.TE
-.ce 1
-Table II. Statistics for RCS files.
-.nr VS 18p
-.vs 18p
-.PP
-The mean number of revisions per RCS file is 1.39.
-Columns 5 and 6 show the mean sizes (in bytes) of an RCS file
-and of the latest revision of each RCS file, respectively.
-The `overhead' column contains the ratio of the mean sizes.
-Assuming that all revisions in an RCS file are approximately the same size,
-this ratio gives a measure of the space consumed by the extra revisions.
-.PP
-In our sample, over 80 per cent of the RCS files contained only a single revision.
-The reason is that our
-systems programmers routinely check in all source files
-on the distribution tapes, even though they may never touch them again.
-To get a better indication of how much space savings are possible
-with deltas, all measures with those files
-that contained 2 or more revisions were recomputed. Only for those files
-is RCS necessary.
-As shown in the second line, the average number of revisions for those files is
-3.10, with an overhead of 1.34. This means that the extra 2.10 deltas
-require 34 per cent extra space, or
-16 per cent per extra revision.
-Rochkind\u3\d
-measured the space consumed by SCCS, and
-reported an average of 5 revisions per group
-and an overhead of 1.37 (or about 9 per cent per extra revision).
-In a later paper, Glasser\u6\d
-observed an average of 7 revisions per group in a single, large project,
-but provided no overhead figure.
-In his paper on DSEE\u5\d,
-Leblang reported that delta storage combined with blank compression
-results in an overhead of a mere 1\-2 per cent per revision.
-Since leading blanks accounted for about 20 per cent of the surveyed Pascal
-programs, a revision group with 5\-10 members was smaller
-than a single cleartext copy.
-.PP
-The above observations demonstrate clearly that the space needed
-for extra revisions is small. With delta storage, the luxury of
-keeping multiple revisions online is certainly affordable.
-In fact, introducing a system with delta storage may reduce
-storage requirements, because programmers often save back-up copies
-anyway. Since back-up copies are stored much more efficiently with deltas,
-introducing a system such as RCS may
-actually free a considerable amount of space.
-.NH
-Survey of Version Control Tools
-.PP
-The need to keep back-up copies of software arose when
-programs and data were no longer stored on paper media, but were entered
-from terminals and stored on disk.
-Back-up copies are desirable for reliability, and many modern editors
-automatically save a back-up copy for every file touched.
-This strategy
-is valuable for short-term back-ups, but not suitable for long-term
-version control, since an existing back-up copy is overwritten whenever the
-corresponding file is edited.
-.PP
-Tape archives are suitable for long-term, offline storage.
-If all changed files are dumped on a back-up tape once per day, old revisions
-remain accessible. However, tape archives are unsatisfactory
-for version control in several ways. First, backing up the file
-system every 24 hours does not capture intermediate revisions.
-Secondly, the old revisions are not online,
-and accessing them is tedious and time-consuming.
-In particular, it is impractical to
-compare several old revisions of a group,
-because that may require mounting and searching several tapes.
-Tape archives are important fail-safe tools in the
-event of catastrophic disk failures or accidental deletions,
-but they are ill-suited for version control.
-Conversely, version control tools do not obviate the
-need for tape archives.
-.PP
-A natural technique for keeping several old revisions online is
-to never delete a file.
-Editing a file
-simply creates a new file with the same
-name, but with a different sequence number.
-This technique, available as an option in DEC's VMS operating system,
-turns out to be inadequate for version control.
-First, it is prohibitively expensive in terms of storage costs,
-especially since no data compression techniques are employed.
-Secondly, indiscriminately storing every change produces too many
-revisions, and programmers have difficulties distinguishing them.
-The proliferation of revisions forces programmers to spend much time on
-finding and deleting useless files.
-Thirdly, most of the support functions like locking, logging,
-revision selection,
-and identification described in this paper are not available.
-.PP
-An alternative approach is to separate editing from revision control.
-The user may repeatedly edit a given revision,
-until freezing it with an explicit command.
-Once a revision is frozen, it is stored permanently and can no longer be modified.
-(In RCS, freezing a revisions is done with \fIci\fR.)
-Editing a frozen revision implicitly creates a new one, which
-can again be changed repeatedly until it is frozen itself.
-This approach saves exactly those revisions that the user
-considers important, and keeps the number of revisions manageable.
-IBM's CLEAR/CASTER\u7\d,
-AT&T's SCCS\u3\d,
-CMU's SDC\u8\d
-and DEC's CMS\u9\d,
-are examples of version control systems using this approach.
-CLEAR/CASTER maintains a data base of programs, specifications,
-documentation and messages, using deltas.
-Its goal is to provide control over the development process from a
-management viewpoint.
-SCCS stores multiple revisions of source text in an ancestral tree,
-records a log entry for each revision,
-provides access control, and has facilities
-for uniquely identifying each revision.
-An efficient delta technique
-reduces the space consumed by each revision group.
-SDC is much simpler than SCCS because it stores not more than
-two revisions. However, it maintains a complete log for all old
-revisions, some of which may be on back-up tape.
-CMS, like SCCS, manages tree-structured revision groups,
-but offers no identification mechanism.
-.PP
-Tools for dealing with configurations are still in a state of flux.
-SCCS, SDC and CMS can be combined with MAKE or MAKE-like programs.
-Since flexible selection rules are missing from all these tools,
-it is sometimes difficult
-to specify precisely which revision of each group
-should be passed to MAKE for building a desired configuration.
-The Xerox Cedar system\u10\d
-provides a `System Modeller' that can rebuild
-a configuration from an arbitrary set of module revisions.
-The revisions of a module are only distinguished by creation time,
-and there is no tool for managing groups.
-Since the selection rules are primitive,
-the System Modeller appears to be somewhat tedious to use.
-Apollo's DSEE\u5\d
-is a sophisticated software engineering environment.
-It manages revision groups in a way similar to SCCS and CMS. Configurations
-are built using `configuration threads'.
-A configuration thread states which revision of each group
-named in a configuration should be chosen.
-A configuration thread may contain dynamic specifiers
-(e.g., `choose the revisions I am currently working on,
-and the most recent revisions otherwise'), which are bound
-automatically at build time.
-It also provides a notification mechanism for alerting
-maintainers about the need to rebuild a system after a change.
-.PP
-RCS is based on a general model for describing
-multi-version/multi-configuration systems\u11\d.
-The model describes systems using AND/OR graphs, where AND nodes represent
-configurations, and OR nodes represent version groups.
-The model gives rise to a suit of selection rules for
-composing configurations, almost all of which are implemented in RCS.
-The revisions selected by RCS are passed to MAKE for configuration building.
-Revision group management is modelled after SCCS.
-RCS retains SCCS's best features,
-but offers a significantly simpler user interface,
-flexible selection rules, adequate integration with MAKE
-and improved identification.
-A detailed comparison of RCS and SCCS appears in Reference 4.
-.PP
-An important component of all revision control systems
-is a program for computing deltas.
-SCCS and RCS use the program \fIdiff\fR\u2\d,
-which first computes the longest common substring of two
-revisions, and then produces the delta from that substring.
-The delta is simply an edit script consisting of deletion and
-insertion commands that generate one revision from the other.
-.PP
-A delta based on a longest common substring is not necessarily minimal,
-because it does not take advantage of crossing block moves.
-Crossing block moves arise if two or more blocks of lines
-(e.g., procedures)
-appear in a different order in two revisions.
-An edit script derived from a longest common substring
-first deletes the shorter of the two blocks, and then reinserts it.
-Heckel\u12\d
-proposed an algorithm for detecting block moves, but
-since the algorithm is based on heuristics,
-there are conditions
-under which the generated delta is far from minimal.
-DSEE uses this algorithm combined with blank compression,
-apparently with satisfactory overall results.
-A new algorithm that is guaranteed to produce a minimal delta based on
-block moves appears in Reference 13.
-A future release of RCS will use this algorithm.
-.PP
-\fIAcknowledgements\fR:
-Many people have helped make RCS a success by contributed criticisms, suggestions,
-corrections, and even whole new commands (including manual pages).
-The list of people is too long to be
-reproduced here, but my sincere thanks for their help and
-goodwill goes to all of them.
-.sp
-.nr VS 12p
-.vs 12p
-.SH
-Appendix: Synopsis of RCS Operations
-.LP
-.IP "\fIci\fP \fB\- check in revisions\fP"
-.sp 0
-\fICi\fR stores the contents of a working file into the
-corresponding RCS file as a new revision.
-If the RCS file doesn't exist, \fIci\fR creates it.
-\fICi\fR removes the working file, unless one of the options
-\fI\-u\fR or \fI\-l\fR is present.
-For each check-in, \fIci\fR asks for a commentary
-describing the changes relative to the previous revision.
-.sp 1
-\fICi\fR assigns the revision number given by the \fI\-r\fR option;
-if that option is missing, it derives the number from the
-lock held by the user; if there is no lock and locking is not strict,
-\fIci\fR increments the number of the latest revision on the trunk.
-A side branch can only be started by explicitly specifying its
-number with the \fI\-r\fR option during check-in.
-.sp 1
-\fICi\fR also determines
-whether the revision to be checked in is different from the
-previous one, and asks whether to proceed if not.
-This facility simplifies check-in operations for large systems,
-because one need not remember which files were changed.
-.sp 1
-The option \fI\-k\fR searches the checked in file for identification
-markers containing
-the attributes
-revision number, check-in date, author and state, and assigns these
-to the new revision rather than computing them. This option is
-useful for software distribution: Recipients of distributed software
-using RCS should check in updates with the \fI\-k\fR option.
-This convention guarantees that revision numbers, check-in dates,
-etc., are the same at all sites.
-.IP "\fIco\fP \fB\- check out revisions\fP"
-.sp 0
-\fICo\fR retrieves revisions according to revision number,
-date, author and state attributes. It either places the revision
-into the working file, or prints it on the standard output.
-\fICo\fR always expands the identification markers.
-.IP "\fIident\fP \fB\- extract identification markers\fP"
-.sp 0
-\fIIdent\fR extracts the identification markers expanded by \fIco\fR
-from any file and prints them.
-.IP "\fIrcs\fP \fB\- change RCS file attributes\fP"
-.sp 0
-\fIRcs\fR is an administrative operation that changes access lists,
-locks, unlocks, breaks locks, toggles the strict-locking feature,
-sets state attributes and symbolic revision numbers, changes the
-description, and deletes revisions. A revision can
-only be deleted if it is not the fork of a side branch.
-.br
-.ne 10
-.IP "\fIrcsclean\fP \fB\- clean working directory\fP"
-.sp 0
-\fIRcsclean\fR removes working files that were checked out but never changed.*
-.FS *
-The \fIrcsclean\fP and \fIrcsfreeze\fP commands
-are optional and are not always installed.
-.FE
-.IP "\fIrcsdiff\fP \fB\- compare revisions\fP"
-.sp 0
-\fIRcsdiff\fR compares two revisions and prints their
-difference, using the UNIX tool \fIdiff\fR.
-One of the revisions compared may be checked out.
-This command is useful for finding out about changes.
-.IP "\fIrcsfreeze\fP \fB\- freeze a configuration\fP"
-.sp 0
-\fIRcsfreeze\fR assigns the same symbolic revision number
-to a given revision in all RCS files.
-This command is useful for accurately recording a configuration.*
-.IP "\fIrcsmerge\fP \fB\- merge revisions\fP"
-.sp 0
-\fIRcsmerge\fR merges two revisions, \fIrev1\fR and \fIrev2\fR,
-with respect to a common ancestor.
-A 3-way file comparison determines the segments of lines that
-are (a) the same in all three revisions, or (b) the same in 2 revisions,
-or (c) different in all three. For all segments of type (b) where
-\fIrev1\fR is the differing revision,
-the segment in \fIrev1\fR replaces the corresponding segment of \fIrev2\fR.
-Type (c) indicates an overlapping change, is flagged as an error, and requires user
-intervention to select the correct alternative.
-.IP "\fIrlog\fP \fB\- read log messages\fP"
-.sp 0
-\fIRlog\fR prints the log messages and other information in an RCS file.
-.bp
-.LP
-.nr VS 12p
-.vs 12p
-.]<
-.ds [F 1
-.]-
-.ds [K FELD02
-.ds [K MakeArticle
-.ds [A Feldman, Stuart I.
-.ds [D March 1979
-.ds [T Make\*-A Program for Maintaining Computer Programs
-.ds [J Software\*-Practice & Experience
-.ds [V 9
-.ds [N 3
-.ds [P 255-265
-.nr [P 1
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 1 journal-article
-.ds [F 2
-.]-
-.ds [K HUNT01
-.ds [T An Algorithm for Differential File Comparison
-.ds [A Hunt, James W.
-.as [A " and McIlroy, M. D.
-.ds [I Computing Science Technical Report, Bell Laboratories
-.ds [R 41
-.ds [D June 1976
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 4 tech-report
-.ds [F 3
-.]-
-.ds [K SCCS
-.ds [A Rochkind, Marc J.
-.ds [D Dec. 1975
-.ds [T The Source Code Control System
-.ds [J IEEE Transactions on Software Engineering
-.ds [V SE-1
-.ds [N 4
-.ds [P 364-370
-.nr [P 1
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 1 journal-article
-.ds [F 4
-.]-
-.ds [K TICH08
-.ds [T Design, Implementation, and Evaluation of a Revision Control System
-.ds [A Tichy, Walter F.
-.ds [B Proceedings of the 6th International Conference on Software Engineering
-.ds [I ACM, IEEE, IPS, NBS
-.ds [D September 1982
-.ds [P 58-67
-.nr [P 1
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 3 article-in-book
-.ds [F 5
-.]-
-.ds [K LEBL01
-.ds [A Leblang, David B.
-.as [A " and Chase, Robert P.
-.ds [T Computer-Aided Software Engineering in a Distributed Workstation Environment
-.ds [O Proceedings of the ACM SIGSOFT/SIGPLAN Software Engineering Symposium
-.as [O " on Practical Software Development Environments.
-.ds [J SIGPLAN Notices
-.ds [V 19
-.ds [N 5
-.ds [D May 1984
-.ds [P 104-112
-.nr [P 1
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 1 journal-article
-.ds [F 1
-.ds [F 3
-.ds [F 6
-.]-
-.ds [K SCCSEval
-.ds [A Glasser, Alan L.
-.ds [D Nov. 1978
-.ds [T The Evolution of a Source Code Control System
-.ds [J Software Engineering Notes
-.ds [V 3
-.ds [N 5
-.ds [P 122-125
-.nr [P 1
-.ds [O Proceedings of the Software Quality and Assurance Workshop.
-.nr [T 0
-.nr [A 1
-.nr [O 1
-.][ 1 journal-article
-.ds [F 5
-.ds [F 7
-.]-
-.ds [K IBMClearCaster
-.ds [A Brown, H.B.
-.ds [D 1970
-.ds [T The Clear/Caster System
-.ds [J Nato Conference on Software Engineering, Rome
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 1 journal-article
-.ds [F 3
-.ds [F 8
-.]-
-.ds [K HabermannSDC
-.ds [A Habermann, A. Nico
-.ds [D Jan. 1979
-.ds [T A Software Development Control System
-.ds [I Technical Report, Carnegie-Mellon University, Department of Computer Science
-.nr [T 0
-.nr [A 0
-.nr [O 0
-.][ 2 book
-.ds [F 9
-.]-
-.ds [K CMS
-.ds [A DEC
-.ds [T Code Management System
-.ds [I Digital Equipment Corporation
-.ds [O Document No.\ EA-23134-82
-.ds [D 1982
-.nr [T 0
-.nr [A 0
-.nr [O 0
-.][ 2 book
-.ds [F 10
-.]-
-.ds [K LAMP01
-.ds [A Lampson, Butler W.
-.as [A " and Schmidt, Eric E.
-.ds [T Practical Use of a Polymorphic Applicative Language
-.ds [B Proceedings of the 10th Symposium on Principles of Programming Languages
-.ds [I ACM
-.ds [P 237-255
-.nr [P 1
-.ds [D January 1983
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 3 article-in-book
-.ds [F 5
-.ds [F 11
-.]-
-.ds [K TICH07
-.ds [T A Data Model for Programming Support Environments and its Application
-.ds [A Tichy, Walter F.
-.ds [B Automated Tools for Information System Design and Development
-.ds [E Hans-Jochen Schneider and Anthony I. Wasserman
-.ds [C Amsterdam
-.ds [I North-Holland Publishing Company
-.ds [D 1982
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 3 article-in-book
-.ds [F 4
-.ds [F 2
-.ds [F 12
-.]-
-.ds [K HECK01
-.ds [T A Technique for Isolating Differences Between Files
-.ds [A Heckel, Paul
-.ds [J Communications of the ACM
-.ds [D April 1978
-.ds [V 21
-.ds [N 4
-.ds [P 264-268
-.nr [P 1
-.nr [T 0
-.nr [A 0
-.nr [O 0
-.][ 1 journal-article
-.ds [F 13
-.]-
-.ds [K TICH11
-.ds [T The String-to-String Correction Problem with Block Moves
-.ds [A Tichy, Walter F.
-.ds [D Nov. 1984
-.ds [J ACM Transactions on Computer Systems
-.ds [V 2
-.ds [N 4
-.ds [P 309-321
-.nr [P 1
-.nr [T 0
-.nr [A 1
-.nr [O 0
-.][ 1 journal-article
-.]>
diff --git a/gnu/usr.bin/rcs/doc/rcs_func.ms b/gnu/usr.bin/rcs/doc/rcs_func.ms
deleted file mode 100644
index 9818086..0000000
--- a/gnu/usr.bin/rcs/doc/rcs_func.ms
+++ /dev/null
@@ -1,95 +0,0 @@
-.SH
-Functions of RCS (Revision Control System)
-.PP
-RCS manages software libraries. It greatly increases programmer productivity
-by providing the following functions.
-.IP 1.
-RCS stores and retrieves multiple revisions of program and other text.
-Thus, one can maintain one or more releases while developing the next
-release, with a minimum of space overhead. Changes no longer destroy the
-original -- previous revisions remain accessible.
-.RS
-.IP a.
-Maintains each module as a tree of revisions.
-.IP b.
-Project libraries can
-be organized centrally, decentralized, or any way you like.
-.IP c.
-RCS works for any type of text: programs, documentation, memos, papers,
-graphics, VLSI layouts, form letters, etc.
-.RE
-.IP 2.
-RCS maintains a complete history of changes.
-Thus, one can find out what happened to a module easily
-and quickly, without having to compare source listings or
-having to track down colleagues.
-.RS
-.IP a.
-RCS performs automatic record keeping.
-.IP b.
-RCS logs all changes automatically.
-.IP c.
-RCS guarantees project continuity.
-.RE
-.IP 3.
-RCS manages multiple lines of development.
-.IP 4.
-RCS can merge multiple lines of development.
-Thus, when several parallel lines of development must be consolidated
-into one line, the merging of changes is automatic.
-.IP 5.
-RCS flags coding conflicts.
-If two or more lines of development modify the same section of code,
-RCS can alert programmers about overlapping changes.
-.IP 6.
-RCS resolves access conflicts.
-When two or more programmers wish to modify the same revision,
-RCS alerts the programmers and makes sure that one modification won't wipe
-out the other one.
-.IP 7.
-RCS provides high-level retrieval functions.
-Revisions can be retrieved according to ranges of revision numbers,
-symbolic names, dates, authors, and states.
-.IP 8.
-RCS provides release and configuration control.
-Revisions can be marked as released, stable, experimental, etc.
-Configurations of modules can be described simply and directly.
-.IP 9.
-RCS performs automatic identification of modules with name, revision
-number, creation time, author, etc.
-Thus, it is always possible to determine which revisions of which
-modules make up a given configuration.
-.IP 10.
-Provides high-level management visibility.
-Thus, it is easy to track the status of a software project.
-.RS
-.IP a.
-RCS provides a complete change history.
-.IP b.
-RCS records who did what when to which revision of which module.
-.RE
-.IP 11.
-RCS is fully compatible with existing software development tools.
-RCS is unobtrusive -- its interface to the file system is such that
-all your existing software tools can be used as before.
-.IP 12.
-RCS' basic user interface is extremely simple. The novice need to learn
-only two commands. Its more sophisticated features have been
-tuned towards advanced software development environments and the
-experienced software professional.
-.IP 13.
-RCS simplifies software distribution if customers
-maintain sources with RCS also. This technique assures proper
-identification of versions and configurations, and tracking of customer
-modifications. Customer modifications can be merged into distributed
-versions locally or by the development group.
-.IP 14.
-RCS needs little extra space for the revisions (only the differences).
-If intermediate revisions are deleted, the corresponding
-differences are compressed into the shortest possible form.
-.IP 15.
-RCS is implemented with reverse deltas. This means that
-the latest revision, which is the one that is accessed most often,
-is stored intact. All others are regenerated from the latest one
-by applying reverse deltas (backward differences). This
-results in fast access time for the revision needed most often.
diff --git a/gnu/usr.bin/rcs/ident/Makefile b/gnu/usr.bin/rcs/ident/Makefile
deleted file mode 100644
index f28f8d3..0000000
--- a/gnu/usr.bin/rcs/ident/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG= ident
-SRCS= ident.c
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/ident/ident.1 b/gnu/usr.bin/rcs/ident/ident.1
deleted file mode 100644
index 253a2ce..0000000
--- a/gnu/usr.bin/rcs/ident/ident.1
+++ /dev/null
@@ -1,182 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-.ds iD \\$3 \\$4 \\$5 \\$6 \\$7
-..
-.Id $FreeBSD$
-.ds r \&\s-1RCS\s0
-.ds u \&\s-1UTC\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.TH IDENT 1 \*(Dt GNU
-.SH NAME
-ident \- identify RCS keyword strings in files
-.SH SYNOPSIS
-.B ident
-[
-.B \-q
-] [
-.B \-V
-] [
-.I file
-\&.\|.\|. ]
-.SH DESCRIPTION
-.B ident
-searches for all instances of the pattern
-.BI $ keyword : "\ text\ " $
-in the named files or, if no files are named, the standard input.
-.PP
-These patterns are normally inserted automatically by the \*r command
-.BR co (1),
-but can also be inserted manually.
-The option
-.B \-q
-suppresses
-the warning given if there are no patterns in a file.
-The option
-.B \-V
-prints
-.BR ident 's
-version number.
-.PP
-.B ident
-works on text files as well as object files and dumps.
-For example, if the C program in
-.B f.c
-contains
-.IP
-.ft 3
-#include <stdio.h>
-.br
-static char const rcsid[] =
-.br
- \&"$\&Id: f.c,v \*(iD $\&";
-.br
-int main() { return printf(\&"%s\en\&", rcsid) == EOF; }
-.ft P
-.LP
-and
-.B f.c
-is compiled into
-.BR f.o ,
-then the command
-.IP
-.B "ident f.c f.o"
-.LP
-will output
-.nf
-.IP
-.ft 3
-f.c:
- $\&Id: f.c,v \*(iD $
-f.o:
- $\&Id: f.c,v \*(iD $
-.ft
-.fi
-.PP
-If a C program defines a string like
-.B rcsid
-above but does not use it,
-.BR lint (1)
-may complain, and some C compilers will optimize away the string.
-The most reliable solution is to have the program use the
-.B rcsid
-string, as shown in the example above.
-.PP
-.B ident
-finds all instances of the
-.BI $ keyword : "\ text\ " $
-pattern, even if
-.I keyword
-is not actually an \*r-supported keyword.
-This gives you information about nonstandard keywords like
-.BR $\&XConsortium$ .
-.SH KEYWORDS
-Here is the list of keywords currently maintained by
-.BR co (1).
-All times are given in Coordinated Universal Time (\*u,
-sometimes called \&\s-1GMT\s0) by default, but if the files
-were checked out with
-.BR co 's
-.BI \-z zone
-option, times are given with a numeric time zone indication appended.
-.TP
-.B $\&Author$
-The login name of the user who checked in the revision.
-.TP
-.B $\&Date$
-The date and time the revision was checked in.
-.TP
-.B $\&Header$
-A standard header containing the full pathname of the \*r file, the
-revision number, the date and time, the author, the state,
-and the locker (if locked).
-.TP
-.B $\&Id$
-Same as
-.BR $\&Header$ ,
-except that the \*r filename is without a path.
-.TP
-.B $\&Locker$
-The login name of the user who locked the revision (empty if not locked).
-.TP
-.B $\&Log$
-The log message supplied during checkin.
-For
-.BR ident 's
-purposes, this is equivalent to
-.BR $\&RCSfile$ .
-.TP
-.B $\&Name$
-The symbolic name used to check out the revision, if any.
-.TP
-.B $\&RCSfile$
-The name of the \*r file without a path.
-.TP
-.B $\&Revision$
-The revision number assigned to the revision.
-.TP
-.B $\&Source$
-The full pathname of the \*r file.
-.TP
-.B $\&State$
-The state assigned to the revision with the
-.B \-s
-option of
-.BR rcs (1)
-or
-.BR ci (1).
-.PP
-.BR co (1)
-represents the following characters in keyword values by escape sequences
-to keep keyword strings well-formed.
-.LP
-.RS
-.nf
-.ne 6
-.ta \w'newline 'u
-\f2char escape sequence\fP
-tab \f3\et\fP
-newline \f3\en\fP
-space \f3\e040
-$ \e044
-\e \e\e\fP
-.fi
-.RE
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1992, 1993 Paul Eggert.
-.SH "SEE ALSO"
-ci(1), co(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1),
-rcsfile(5)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
diff --git a/gnu/usr.bin/rcs/ident/ident.c b/gnu/usr.bin/rcs/ident/ident.c
deleted file mode 100644
index 9b8bf57..0000000
--- a/gnu/usr.bin/rcs/ident/ident.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* Identify RCS keyword strings in files. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.9 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.8 1995/06/01 16:23:43 eggert
- * (exiterr, reportError): New functions, needed for DOS and OS/2 ports.
- * (scanfile): Use them.
- *
- * Revision 5.7 1994/03/20 04:52:58 eggert
- * Remove `exiting' from identExit.
- *
- * Revision 5.6 1993/11/09 17:40:15 eggert
- * Add -V.
- *
- * Revision 5.5 1993/11/03 17:42:27 eggert
- * Test for char == EOF, not char < 0.
- *
- * Revision 5.4 1992/01/24 18:44:19 eggert
- * lint -> RCS_lint
- *
- * Revision 5.3 1991/09/10 22:15:46 eggert
- * Open files with FOPEN_R, not FOPEN_R_WORK,
- * because they might be executables, not working files.
- *
- * Revision 5.2 1991/08/19 03:13:55 eggert
- * Report read errors immediately.
- *
- * Revision 5.1 1991/02/25 07:12:37 eggert
- * Don't report empty keywords. Check for I/O errors.
- *
- * Revision 5.0 1990/08/22 08:12:37 eggert
- * Don't limit output to known keywords.
- * Remove arbitrary limits and lint. Ansify and Posixate.
- *
- * Revision 4.5 89/05/01 15:11:54 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.4 87/10/23 17:09:57 narten
- * added exit(0) so exit return code would be non random
- *
- * Revision 4.3 87/10/18 10:23:55 narten
- * Updating version numbers. Changes relative to 1.1 are actually relative
- * to 4.1
- *
- * Revision 1.3 87/07/09 09:20:52 trinkle
- * Added check to make sure there is at least one arg before comparing argv[1]
- * with "-q". This necessary on machines that don't allow dereferncing null
- * pointers (i.e. Suns).
- *
- * Revision 1.2 87/03/27 14:21:47 jenkins
- * Port to suns
- *
- * Revision 4.1 83/05/10 16:31:02 wft
- * Added option -q and input from reading stdin.
- * Marker matching is now done with trymatch() (independent of keywords).
- *
- * Revision 3.4 83/02/18 17:37:49 wft
- * removed printing of new line after last file.
- *
- * Revision 3.3 82/12/04 12:48:55 wft
- * Added LOCKER.
- *
- * Revision 3.2 82/11/28 18:24:17 wft
- * removed Suffix; added ungetc to avoid skipping over trailing KDELIM.
- *
- * Revision 3.1 82/10/13 15:58:51 wft
- * fixed type of variables receiving from getc() (char-->int).
-*/
-
-#include "rcsbase.h"
-
-static int match P((FILE*));
-static int scanfile P((FILE*,char const*,int));
-static void reportError P((char const*));
-
-mainProg(identId, "ident", "$FreeBSD$")
-/* Ident searches the named files for all occurrences
- * of the pattern $@: text $ where @ is a keyword.
- */
-
-{
- FILE *fp;
- int quiet = 0;
- int status = EXIT_SUCCESS;
- char const *a;
-
- while ((a = *++argv) && *a=='-')
- while (*++a)
- switch (*a) {
- case 'q':
- quiet = 1;
- break;
-
- case 'V':
- VOID printf("RCS version %s\n", RCS_version_string);
- quiet = -1;
- break;
-
- default:
- VOID fprintf(stderr,
- "ident: usage: ident -{qV} [file...]\n"
- );
- exitmain(EXIT_FAILURE);
- break;
- }
-
- if (0 <= quiet)
- if (!a)
- VOID scanfile(stdin, (char*)0, quiet);
- else
- do {
- if (!(fp = fopen(a, FOPEN_RB))) {
- reportError(a);
- status = EXIT_FAILURE;
- } else if (
- scanfile(fp, a, quiet) != 0
- || (argv[1] && putchar('\n') == EOF)
- )
- break;
- } while ((a = *++argv));
-
- if (ferror(stdout) || fclose(stdout)!=0) {
- reportError("standard output");
- status = EXIT_FAILURE;
- }
- exitmain(status);
-}
-
-#if RCS_lint
-# define exiterr identExit
-#endif
- void
-exiterr()
-{
- _exit(EXIT_FAILURE);
-}
-
- static void
-reportError(s)
- char const *s;
-{
- int e = errno;
- VOID fprintf(stderr, "%s error: ", cmdid);
- errno = e;
- perror(s);
-}
-
-
- static int
-scanfile(file, name, quiet)
- register FILE *file;
- char const *name;
- int quiet;
-/* Function: scan an open file with descriptor file for keywords.
- * Return -1 if there's a write error; exit immediately on a read error.
- */
-{
- register int c;
-
- if (name) {
- VOID printf("%s:\n", name);
- if (ferror(stdout))
- return -1;
- } else
- name = "standard input";
- c = 0;
- while (c != EOF || ! (feof(file)|ferror(file))) {
- if (c == KDELIM) {
- if ((c = match(file)))
- continue;
- if (ferror(stdout))
- return -1;
- quiet = true;
- }
- c = getc(file);
- }
- if (ferror(file) || fclose(file) != 0) {
- reportError(name);
- /*
- * The following is equivalent to exit(EXIT_FAILURE), but we invoke
- * exiterr to keep lint happy. The DOS and OS/2 ports need exiterr.
- */
- VOID fflush(stderr);
- VOID fflush(stdout);
- exiterr();
- }
- if (!quiet)
- VOID fprintf(stderr, "%s warning: no id keywords in %s\n", cmdid, name);
- return 0;
-}
-
-
-
- static int
-match(fp) /* group substring between two KDELIM's; then do pattern match */
- register FILE *fp;
-{
- char line[BUFSIZ];
- register int c;
- register char * tp;
-
- tp = line;
- while ((c = getc(fp)) != VDELIM) {
- if (c == EOF && feof(fp) | ferror(fp))
- return c;
- switch (ctab[c]) {
- case LETTER: case Letter: case DIGIT:
- *tp++ = c;
- if (tp < line+sizeof(line)-4)
- break;
- /* fall into */
- default:
- return c ? c : '\n'/* anything but 0 or KDELIM or EOF */;
- }
- }
- if (tp == line)
- return c;
- *tp++ = c;
- if ((c = getc(fp)) != ' ')
- return c ? c : '\n';
- *tp++ = c;
- while( (c = getc(fp)) != KDELIM ) {
- if (c == EOF && feof(fp) | ferror(fp))
- return c;
- switch (ctab[c]) {
- default:
- *tp++ = c;
- if (tp < line+sizeof(line)-2)
- break;
- /* fall into */
- case NEWLN: case UNKN:
- return c ? c : '\n';
- }
- }
- if (tp[-1] != ' ')
- return c;
- *tp++ = c; /*append trailing KDELIM*/
- *tp = '\0';
- VOID printf(" %c%s\n", KDELIM, line);
- return 0;
-}
diff --git a/gnu/usr.bin/rcs/lib/Makefile b/gnu/usr.bin/rcs/lib/Makefile
deleted file mode 100644
index f21fda1..0000000
--- a/gnu/usr.bin/rcs/lib/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-# $FreeBSD$
-
-# Define FSYNC_ALL to get slower but safer writes in case of crashes in
-# the middle of CVS/RCS changes
-#CFLAGS += -DFSYNC_ALL
-
-LIB = rcs
-SRCS = maketime.c partime.c rcsedit.c rcsfcmp.c rcsfnms.c rcsgen.c \
- rcskeep.c rcskeys.c rcslex.c rcsmap.c rcsrev.c rcssyn.c rcstime.c \
- rcsutil.c merger.c version.c
-
-INTERNALLIB=
-
-.include <bsd.lib.mk>
diff --git a/gnu/usr.bin/rcs/lib/conf.h b/gnu/usr.bin/rcs/lib/conf.h
deleted file mode 100644
index 96ec07d..0000000
--- a/gnu/usr.bin/rcs/lib/conf.h
+++ /dev/null
@@ -1,400 +0,0 @@
-/* RCS compile-time configuration */
-
- /* $FreeBSD$ */
-
-/*
- * This file is generated automatically.
- * If you edit it by hand your changes may be lost.
- * Instead, please try to fix conf.sh,
- * and send your fixes to rcs-bugs@cs.purdue.edu.
- */
-
-#define exitmain(n) return n /* how to exit from main() */
-/* #define _POSIX_C_SOURCE 2147483647L */ /* if strict C + Posix 1003.1b-1993 or later */
-/* #define _POSIX_SOURCE */ /* if strict C + Posix 1003.1-1990 */
-
-#include <errno.h>
-#include <stdio.h>
-#include <time.h>
-
-/* Comment out #include lines below that do not work. */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <limits.h>
-/* #include <mach/mach.h> */
-/* #include <net/errno.h> */
-#include <pwd.h>
-/* #include <siginfo.h> */
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-/* #include <ucontext.h> */
-#include <unistd.h>
-#include <utime.h>
-/* #include <vfork.h> */
-
-/* Define boolean symbols to be 0 (false, the default), or 1 (true). */
-#define has_sys_param_h 1 /* Does #include <sys/param.h> work? */
-/* extern int errno; */ /* Uncomment if <errno.h> doesn't declare errno. */
-#define has_readlink 1 /* Does readlink() work? */
-#define readlink_isreg_errno EINVAL /* errno after readlink on regular file */
-
-#if has_readlink && !defined(MAXSYMLINKS)
-# if has_sys_param_h
-# include <sys/param.h>
-# endif
-# ifndef MAXSYMLINKS
-# define MAXSYMLINKS 20 /* BSD; not standard yet */
-# endif
-#endif
-
-/* Comment out the typedefs below if the types are already declared. */
-/* Fix any uncommented typedefs that are wrong. */
-/* typedef int mode_t; */
-/* typedef long off_t; */
-/* typedef int pid_t; */
-/* typedef int sig_atomic_t; */
-/* typedef unsigned size_t; */
-/* typedef int ssize_t; */
-/* typedef long time_t; */
-/* typedef int uid_t; */
-
-/* Comment out the keyword definitions below if the keywords work. */
-/* #define const */
-/* #define volatile */
-
-/* Define boolean symbols to be 0 (false, the default), or 1 (true). */
-#define has_prototypes 1 /* Do function prototypes work? */
-#define has_stdarg 1 /* Does <stdarg.h> work? */
-/* #define has_varargs ? */ /* Does <varargs.h> work? */
-#define va_start_args 2 /* How many args does va_start() take? */
-
-#if O_BINARY
- /* Text and binary i/o behave differently. */
- /* This is incompatible with Posix and Unix. */
-# define FOPEN_RB "rb"
-# define FOPEN_R_WORK (Expand==BINARY_EXPAND ? "r" : "rb")
-# define FOPEN_WB "wb"
-# define FOPEN_W_WORK (Expand==BINARY_EXPAND ? "w" : "wb")
-# define FOPEN_WPLUS_WORK (Expand==BINARY_EXPAND ? "w+" : "w+b")
-# define OPEN_O_BINARY O_BINARY
-#else
- /*
- * Text and binary i/o behave the same.
- * Omit "b", since some nonstandard hosts reject it.
- */
-# define FOPEN_RB "r"
-# define FOPEN_R_WORK "r"
-# define FOPEN_WB "w"
-# define FOPEN_W_WORK "w"
-# define FOPEN_WPLUS_WORK "w+"
-# define OPEN_O_BINARY 0
-#endif
-
-/* This may need changing on non-Unix systems (notably DOS). */
-#define OPEN_CREAT_READONLY (S_IRUSR|S_IRGRP|S_IROTH) /* lock file mode */
-#define OPEN_O_LOCK 0 /* extra open flags for creating lock file */
-#define OPEN_O_WRONLY O_WRONLY /* main open flag for creating a lock file */
-
-/* Define or comment out the following symbols as needed. */
-#if has_prototypes
-# define P(params) params
-#else
-# define P(params) ()
-#endif
-#if has_stdarg
-# include <stdarg.h>
-#else
-# if has_varargs
-# include <varargs.h>
-# else
- typedef char *va_list;
-# define va_dcl int va_alist;
-# define va_start(ap) ((ap) = (va_list)&va_alist)
-# define va_arg(ap,t) (((t*) ((ap)+=sizeof(t))) [-1])
-# define va_end(ap)
-# endif
-#endif
-#if va_start_args == 2
-# define vararg_start va_start
-#else
-# define vararg_start(ap,p) va_start(ap)
-#endif
-#define bad_chmod_close 0 /* Can chmod() close file descriptors? */
-#define bad_creat0 0 /* Do writes fail after creat(f,0)? */
-#define bad_fopen_wplus 0 /* Does fopen(f,"w+") fail to truncate f? */
-#define getlogin_is_secure 0 /* Is getlogin() secure? Usually it's not. */
-#define has_attribute_noreturn 1 /* Does __attribute__((noreturn)) work? */
-#if has_attribute_noreturn
-# define exiting __attribute__((noreturn))
-#else
-# define exiting
-#endif
-#define has_dirent 1 /* Do opendir(), readdir(), closedir() work? */
-#define void_closedir 0 /* Does closedir() yield void? */
-#define has_fchmod 1 /* Does fchmod() work? */
-#define has_fflush_input 0 /* Does fflush() work on input files? */
-#define has_fputs 1 /* Does fputs() work? */
-#define has_ftruncate 1 /* Does ftruncate() work? */
-#define has_getuid 1 /* Does getuid() work? */
-#define has_getpwuid 1 /* Does getpwuid() work? */
-#define has_memcmp 1 /* Does memcmp() work? */
-#define has_memcpy 1 /* Does memcpy() work? */
-#define has_memmove 1 /* Does memmove() work? */
-#define has_map_fd 0 /* Does map_fd() work? */
-#define has_mmap 1 /* Does mmap() work on regular files? */
-#define has_madvise 0 /* Does madvise() work? */
-#define mmap_signal SIGBUS /* signal received if you reference nonexistent part of mmapped file */
-#define has_rename 1 /* Does rename() work? */
-#define bad_a_rename 0 /* Does rename(A,B) fail if A is unwritable? */
-#define bad_b_rename 0 /* Does rename(A,B) fail if B is unwritable? */
-#define bad_NFS_rename 0 /* Can rename(A,B) falsely report success? */
-/* typedef int void; */ /* Some ancient compilers need this. */
-#define VOID (void) /* 'VOID e;' discards the value of an expression 'e'. */
-#define has_seteuid 1 /* Does seteuid() work? See ../INSTALL.RCS. */
-#define has_setreuid 0 /* Does setreuid() work? See ../INSTALL.RCS. */
-#define has_setuid 1 /* Does setuid() exist? */
-#define has_sigaction 1 /* Does struct sigaction work? */
-#define has_sa_sigaction 1 /* Does struct sigaction have sa_sigaction? */
-#define has_signal 1 /* Does signal() work? */
-#define signal_type void /* type returned by signal handlers */
-#define sig_zaps_handler 0 /* Must a signal handler reinvoke signal()? */
-/* #define has_sigblock ? */ /* Does sigblock() work? */
-/* #define sigmask(s) (1 << ((s)-1)) */ /* Yield mask for signal number. */
-typedef size_t fread_type; /* type returned by fread() and fwrite() */
-typedef size_t freadarg_type; /* type of their size arguments */
-typedef void *malloc_type; /* type returned by malloc() */
-#define has_getcwd 1 /* Does getcwd() work? */
-/* #define has_getwd ? */ /* Does getwd() work? */
-#define needs_getabsname 0 /* Must we define getabsname? */
-#define has_mktemp 1 /* Does mktemp() work? */
-#define has_mkstemp 1 /* Does mkstemp() work? */
-#define has_NFS 1 /* Might NFS be used? */
-#define has_psiginfo 0 /* Does psiginfo() work? */
-#define has_psignal 1 /* Does psignal() work? */
-/* #define has_si_errno ? */ /* Does siginfo_t have si_errno? */
-/* #define has_sys_siglist ? */ /* Does sys_siglist[] work? */
-/* #define strchr index */ /* Use old-fashioned name for strchr()? */
-/* #define strrchr rindex */ /* Use old-fashioned name for strrchr()? */
-#define bad_unlink 0 /* Does unlink() fail on unwritable files? */
-#define has_vfork 1 /* Does vfork() work? */
-#define has_fork 1 /* Does fork() work? */
-#define has_spawn 0 /* Does spawn*() work? */
-#define has_waitpid 1 /* Does waitpid() work? */
-#define bad_wait_if_SIGCHLD_ignored 0 /* Does ignoring SIGCHLD break wait()? */
-#define RCS_SHELL "/bin/sh" /* shell to run RCS subprograms */
-#define has_printf_dot 1 /* Does "%.2d" print leading 0? */
-#define has_vfprintf 1 /* Does vfprintf() work? */
-#define has_attribute_format_printf 1 /* Does __attribute__((format(printf,N,N+1))) work? */
-#if has_attribute_format_printf
-# define printf_string(m, n) __attribute__((format(printf, m, n)))
-#else
-# define printf_string(m, n)
-#endif
-#if has_attribute_format_printf && has_attribute_noreturn
- /* Work around a bug in GCC 2.5.x. */
-# define printf_string_exiting(m, n) __attribute__((format(printf, m, n), noreturn))
-#else
-# define printf_string_exiting(m, n) printf_string(m, n) exiting
-#endif
-/* #define has__doprintf ? */ /* Does _doprintf() work? */
-/* #define has__doprnt ? */ /* Does _doprnt() work? */
-/* #undef EXIT_FAILURE */ /* Uncomment this if EXIT_FAILURE is broken. */
-#define large_memory 1 /* Can main memory hold entire RCS files? */
-#ifndef LONG_MAX
-#define LONG_MAX 2147483647L /* long maximum */
-#endif
-/* Do struct stat s and t describe the same file? Answer d if unknown. */
-#define same_file(s,t,d) ((s).st_ino==(t).st_ino && (s).st_dev==(t).st_dev)
-#define has_utimbuf 1 /* Does struct utimbuf work? */
-#define CO "/usr/bin/co" /* name of 'co' program */
-#define COMPAT2 0 /* Are version 2 files supported? */
-#define DIFF "/usr/bin/diff" /* name of 'diff' program */
-#define DIFF3 "/usr/bin/diff3" /* name of 'diff3' program */
-#define DIFF3_BIN 1 /* Is diff3 user-visible (not the /usr/lib auxiliary)? */
-#define DIFFFLAGS "-an" /* Make diff output suitable for RCS. */
-#define DIFF_L 1 /* Does diff -L work? */
-#define DIFF_SUCCESS 0 /* DIFF status if no differences are found */
-#define DIFF_FAILURE 1 /* DIFF status if differences are found */
-#define DIFF_TROUBLE 2 /* DIFF status if trouble */
-#define ED "/bin/ed" /* name of 'ed' program (used only if !DIFF3_BIN) */
-#define MERGE "/usr/bin/merge" /* name of 'merge' program */
-#define TMPDIR "/tmp" /* default directory for temporary files */
-#define SLASH '/' /* principal filename separator */
-#define SLASHes '/' /* `case SLASHes:' labels all filename separators */
-#define isSLASH(c) ((c) == SLASH) /* Is arg a filename separator? */
-#define ROOTPATH(p) isSLASH((p)[0]) /* Is p an absolute pathname? */
-#define X_DEFAULT ",v/" /* default value for -x option */
-#define SLASHSLASH_is_SLASH 1 /* Are // and / the same directory? */
-#define ALL_ABSOLUTE 1 /* Do all subprograms satisfy ROOTPATH? */
-#define DIFF_ABSOLUTE 1 /* Is ROOTPATH(DIFF) true? */
-#define SENDMAIL "/usr/sbin/sendmail" /* how to send mail */
-#define TZ_must_be_set 0 /* Must TZ be set for gmtime() to work? */
-
-
-
-/* Adjust the following declarations as needed. */
-
-
-/* The rest is for the benefit of non-standard, traditional hosts. */
-/* Don't bother to declare functions that in traditional hosts do not appear, */
-/* or are declared in .h files, or return int or void. */
-
-
-/* traditional BSD */
-
-#if has_sys_siglist && !defined(sys_siglist)
- extern char const * const sys_siglist[];
-#endif
-
-
-/* Posix (ISO/IEC 9945-1: 1990 / IEEE Std 1003.1-1990) */
-
-/* <fcntl.h> */
-#ifdef O_CREAT
-# define open_can_creat 1
-#else
-# define open_can_creat 0
-# define O_RDONLY 0
-# define O_WRONLY 1
-# define O_RDWR 2
-# define O_CREAT 01000
-# define O_TRUNC 02000
-#endif
-#ifndef O_EXCL
-#define O_EXCL 0
-#endif
-
-/* <sys/stat.h> */
-#ifndef S_IRUSR
-# ifdef S_IREAD
-# define S_IRUSR S_IREAD
-# else
-# define S_IRUSR 0400
-# endif
-# ifdef S_IWRITE
-# define S_IWUSR S_IWRITE
-# else
-# define S_IWUSR (S_IRUSR/2)
-# endif
-#endif
-#ifndef S_IRGRP
-# if has_getuid
-# define S_IRGRP (S_IRUSR / 0010)
-# define S_IWGRP (S_IWUSR / 0010)
-# define S_IROTH (S_IRUSR / 0100)
-# define S_IWOTH (S_IWUSR / 0100)
-# else
- /* single user OS -- not Posix or Unix */
-# define S_IRGRP 0
-# define S_IWGRP 0
-# define S_IROTH 0
-# define S_IWOTH 0
-# endif
-#endif
-#ifndef S_ISREG
-#define S_ISREG(n) (((n) & S_IFMT) == S_IFREG)
-#endif
-
-/* <sys/wait.h> */
-#ifndef WEXITSTATUS
-#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
-#undef WIFEXITED /* Avoid 4.3BSD incompatibility with Posix. */
-#endif
-#ifndef WIFEXITED
-#define WIFEXITED(stat_val) (((stat_val) & 0377) == 0)
-#endif
-#ifndef WTERMSIG
-#define WTERMSIG(stat_val) ((stat_val) & 0177)
-#undef WIFSIGNALED /* Avoid 4.3BSD incompatibility with Posix. */
-#endif
-#ifndef WIFSIGNALED
-#define WIFSIGNALED(stat_val) ((unsigned)(stat_val) - 1 < 0377)
-#endif
-
-/* <unistd.h> */
-char *getlogin P((void));
-#ifndef STDIN_FILENO
-# define STDIN_FILENO 0
-# define STDOUT_FILENO 1
-# define STDERR_FILENO 2
-#endif
-#if has_fork && !has_vfork
-# undef vfork
-# define vfork fork
-#endif
-#if has_getcwd || !has_getwd
- char *getcwd P((char*,size_t));
-#else
- char *getwd P((char*));
-#endif
-#if has_setuid && !has_seteuid
-# undef seteuid
-# define seteuid setuid
-#endif
-#if has_spawn
-# if ALL_ABSOLUTE
-# define spawn_RCS spawnv
-# else
-# define spawn_RCS spawnvp
-# endif
-#else
-# if ALL_ABSOLUTE
-# define exec_RCS execv
-# else
-# define exec_RCS execvp
-# endif
-#endif
-
-/* utime.h */
-#if !has_utimbuf
- struct utimbuf { time_t actime, modtime; };
-#endif
-
-
-/* Standard C library */
-
-/* <stdio.h> */
-#ifndef L_tmpnam
-#define L_tmpnam 32 /* power of 2 > sizeof("/usr/tmp/xxxxxxxxxxxxxxx") */
-#endif
-#ifndef SEEK_SET
-#define SEEK_SET 0
-#endif
-#ifndef SEEK_CUR
-#define SEEK_CUR 1
-#endif
-#if has_mktemp
- char *mktemp P((char*)); /* traditional */
-#else
- char *tmpnam P((char*));
-#endif
-
-/* <stdlib.h> */
-char *getenv P((char const*));
-void _exit P((int)) exiting;
-void exit P((int)) exiting;
-malloc_type malloc P((size_t));
-malloc_type realloc P((malloc_type,size_t));
-#ifndef EXIT_FAILURE
-#define EXIT_FAILURE 1
-#endif
-#ifndef EXIT_SUCCESS
-#define EXIT_SUCCESS 0
-#endif
-
-/* <string.h> */
-char *strcpy P((char*,char const*));
-char *strchr P((char const*,int));
-char *strrchr P((char const*,int));
-void *memcpy P((void*,void const*,size_t));
-#if has_memmove
- void *memmove P((void*,void const*,size_t));
-#endif
-
-/* <time.h> */
-time_t time P((time_t*));
diff --git a/gnu/usr.bin/rcs/lib/maketime.c b/gnu/usr.bin/rcs/lib/maketime.c
deleted file mode 100644
index 0f83bf5..0000000
--- a/gnu/usr.bin/rcs/lib/maketime.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* Convert struct partime into time_t. */
-
-/* Copyright 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#if has_conf_h
-# include "conf.h"
-#else
-# ifdef __STDC__
-# define P(x) x
-# else
-# define const
-# define P(x) ()
-# endif
-# include <stdlib.h>
-# include <time.h>
-#endif
-
-#include "partime.h"
-#include "maketime.h"
-
-char const maketId[]
- = "$FreeBSD$";
-
-static int isleap P((int));
-static int month_days P((struct tm const*));
-static time_t maketime P((struct partime const*,time_t));
-
-/*
-* For maximum portability, use only localtime and gmtime.
-* Make no assumptions about the time_t epoch or the range of time_t values.
-* Avoid mktime because it's not universal and because there's no easy,
-* portable way for mktime to yield the inverse of gmtime.
-*/
-
-#define TM_YEAR_ORIGIN 1900
-
- static int
-isleap(y)
- int y;
-{
- return (y&3) == 0 && (y%100 != 0 || y%400 == 0);
-}
-
-static int const month_yday[] = {
- /* days in year before start of months 0-12 */
- 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
-};
-
-/* Yield the number of days in TM's month. */
- static int
-month_days(tm)
- struct tm const *tm;
-{
- int m = tm->tm_mon;
- return month_yday[m+1] - month_yday[m]
- + (m==1 && isleap(tm->tm_year + TM_YEAR_ORIGIN));
-}
-
-/*
-* Convert UNIXTIME to struct tm form.
-* Use gmtime if available and if !LOCALZONE, localtime otherwise.
-*/
- struct tm *
-time2tm(unixtime, localzone)
- time_t unixtime;
- int localzone;
-{
- struct tm *tm;
-# if TZ_must_be_set
- static char const *TZ;
- if (!TZ && !(TZ = getenv("TZ")))
- faterror("The TZ environment variable is not set; please set it to your timezone");
-# endif
- if (localzone || !(tm = gmtime(&unixtime)))
- tm = localtime(&unixtime);
- return tm;
-}
-
-/* Yield A - B, measured in seconds. */
- time_t
-difftm(a, b)
- struct tm const *a, *b;
-{
- int ay = a->tm_year + (TM_YEAR_ORIGIN - 1);
- int by = b->tm_year + (TM_YEAR_ORIGIN - 1);
- int difference_in_day_of_year = a->tm_yday - b->tm_yday;
- int intervening_leap_days = (
- ((ay >> 2) - (by >> 2))
- - (ay/100 - by/100)
- + ((ay/100 >> 2) - (by/100 >> 2))
- );
- time_t difference_in_years = ay - by;
- time_t difference_in_days = (
- difference_in_years*365
- + (intervening_leap_days + difference_in_day_of_year)
- );
- return
- (
- (
- 24*difference_in_days
- + (a->tm_hour - b->tm_hour)
- )*60 + (a->tm_min - b->tm_min)
- )*60 + (a->tm_sec - b->tm_sec);
-}
-
-/*
-* Adjust time T by adding SECONDS. SECONDS must be at most 24 hours' worth.
-* Adjust only T's year, mon, mday, hour, min and sec members;
-* plus adjust wday if it is defined.
-*/
- void
-adjzone(t, seconds)
- register struct tm *t;
- long seconds;
-{
- /*
- * This code can be off by a second if SECONDS is not a multiple of 60,
- * if T is local time, and if a leap second happens during this minute.
- * But this bug has never occurred, and most likely will not ever occur.
- * Liberia, the last country for which SECONDS % 60 was nonzero,
- * switched to UTC in May 1972; the first leap second was in June 1972.
- */
- int leap_second = t->tm_sec == 60;
- long sec = seconds + (t->tm_sec - leap_second);
- if (sec < 0) {
- if ((t->tm_min -= (59-sec)/60) < 0) {
- if ((t->tm_hour -= (59-t->tm_min)/60) < 0) {
- t->tm_hour += 24;
- if (TM_DEFINED(t->tm_wday) && --t->tm_wday < 0)
- t->tm_wday = 6;
- if (--t->tm_mday <= 0) {
- if (--t->tm_mon < 0) {
- --t->tm_year;
- t->tm_mon = 11;
- }
- t->tm_mday = month_days(t);
- }
- }
- t->tm_min += 24 * 60;
- }
- sec += 24L * 60 * 60;
- } else
- if (60 <= (t->tm_min += sec/60))
- if (24 <= (t->tm_hour += t->tm_min/60)) {
- t->tm_hour -= 24;
- if (TM_DEFINED(t->tm_wday) && ++t->tm_wday == 7)
- t->tm_wday = 0;
- if (month_days(t) < ++t->tm_mday) {
- if (11 < ++t->tm_mon) {
- ++t->tm_year;
- t->tm_mon = 0;
- }
- t->tm_mday = 1;
- }
- }
- t->tm_min %= 60;
- t->tm_sec = (int) (sec%60) + leap_second;
-}
-
-/*
-* Convert TM to time_t, using localtime if LOCALZONE and gmtime otherwise.
-* Use only TM's year, mon, mday, hour, min, and sec members.
-* Ignore TM's old tm_yday and tm_wday, but fill in their correct values.
-* Yield -1 on failure (e.g. a member out of range).
-* Posix 1003.1-1990 doesn't allow leap seconds, but some implementations
-* have them anyway, so allow them if localtime/gmtime does.
-*/
- time_t
-tm2time(tm, localzone)
- struct tm *tm;
- int localzone;
-{
- /* Cache the most recent t,tm pairs; 1 for gmtime, 1 for localtime. */
- static time_t t_cache[2];
- static struct tm tm_cache[2];
-
- time_t d, gt;
- struct tm const *gtm;
- /*
- * The maximum number of iterations should be enough to handle any
- * combinations of leap seconds, time zone rule changes, and solar time.
- * 4 is probably enough; we use a bigger number just to be safe.
- */
- int remaining_tries = 8;
-
- /* Avoid subscript errors. */
- if (12 <= (unsigned)tm->tm_mon)
- return -1;
-
- tm->tm_yday = month_yday[tm->tm_mon] + tm->tm_mday
- - (tm->tm_mon<2 || ! isleap(tm->tm_year + TM_YEAR_ORIGIN));
-
- /* Make a first guess. */
- gt = t_cache[localzone];
- gtm = gt ? &tm_cache[localzone] : time2tm(gt,localzone);
-
- /* Repeatedly use the error from the guess to improve the guess. */
- while ((d = difftm(tm, gtm)) != 0) {
- if (--remaining_tries == 0)
- return -1;
- gt += d;
- gtm = time2tm(gt,localzone);
- }
- t_cache[localzone] = gt;
- tm_cache[localzone] = *gtm;
-
- /*
- * Check that the guess actually matches;
- * overflow can cause difftm to yield 0 even on differing times,
- * or tm may have members out of range (e.g. bad leap seconds).
- */
- if ( (tm->tm_year ^ gtm->tm_year)
- | (tm->tm_mon ^ gtm->tm_mon)
- | (tm->tm_mday ^ gtm->tm_mday)
- | (tm->tm_hour ^ gtm->tm_hour)
- | (tm->tm_min ^ gtm->tm_min)
- | (tm->tm_sec ^ gtm->tm_sec))
- return -1;
-
- tm->tm_wday = gtm->tm_wday;
- return gt;
-}
-
-/*
-* Check *PT and convert it to time_t.
-* If it is incompletely specified, use DEFAULT_TIME to fill it out.
-* Use localtime if PT->zone is the special value TM_LOCAL_ZONE.
-* Yield -1 on failure.
-* ISO 8601 day-of-year and week numbers are not yet supported.
-*/
- static time_t
-maketime(pt, default_time)
- struct partime const *pt;
- time_t default_time;
-{
- int localzone, wday;
- struct tm tm;
- struct tm *tm0 = 0;
- time_t r;
-
- tm0 = 0; /* Keep gcc -Wall happy. */
- localzone = pt->zone==TM_LOCAL_ZONE;
-
- tm = pt->tm;
-
- if (TM_DEFINED(pt->ymodulus) || !TM_DEFINED(tm.tm_year)) {
- /* Get tm corresponding to current time. */
- tm0 = time2tm(default_time, localzone);
- if (!localzone)
- adjzone(tm0, pt->zone);
- }
-
- if (TM_DEFINED(pt->ymodulus))
- tm.tm_year +=
- (tm0->tm_year + TM_YEAR_ORIGIN)/pt->ymodulus * pt->ymodulus;
- else if (!TM_DEFINED(tm.tm_year)) {
- /* Set default year, month, day from current time. */
- tm.tm_year = tm0->tm_year + TM_YEAR_ORIGIN;
- if (!TM_DEFINED(tm.tm_mon)) {
- tm.tm_mon = tm0->tm_mon;
- if (!TM_DEFINED(tm.tm_mday))
- tm.tm_mday = tm0->tm_mday;
- }
- }
-
- /* Convert from partime year (Gregorian) to Posix year. */
- tm.tm_year -= TM_YEAR_ORIGIN;
-
- /* Set remaining default fields to be their minimum values. */
- if (!TM_DEFINED(tm.tm_mon)) tm.tm_mon = 0;
- if (!TM_DEFINED(tm.tm_mday)) tm.tm_mday = 1;
- if (!TM_DEFINED(tm.tm_hour)) tm.tm_hour = 0;
- if (!TM_DEFINED(tm.tm_min)) tm.tm_min = 0;
- if (!TM_DEFINED(tm.tm_sec)) tm.tm_sec = 0;
-
- if (!localzone)
- adjzone(&tm, -pt->zone);
- wday = tm.tm_wday;
-
- /* Convert and fill in the rest of the tm. */
- r = tm2time(&tm, localzone);
-
- /* Check weekday. */
- if (r != -1 && TM_DEFINED(wday) && wday != tm.tm_wday)
- return -1;
-
- return r;
-}
-
-/* Parse a free-format date in SOURCE, yielding a Unix format time. */
- time_t
-str2time(source, default_time, default_zone)
- char const *source;
- time_t default_time;
- long default_zone;
-{
- struct partime pt;
-
- if (*partime(source, &pt))
- return -1;
- if (pt.zone == TM_UNDEFINED_ZONE)
- pt.zone = default_zone;
- return maketime(&pt, default_time);
-}
-
-#if TEST
-#include <stdio.h>
- int
-main(argc, argv) int argc; char **argv;
-{
- time_t default_time = time((time_t *)0);
- long default_zone = argv[1] ? atol(argv[1]) : 0;
- char buf[1000];
- while (fgets(buf, 1000, stdin)) {
- time_t t = str2time(buf, default_time, default_zone);
- printf("%s", asctime(gmtime(&t)));
- }
- return 0;
-}
-#endif
diff --git a/gnu/usr.bin/rcs/lib/maketime.h b/gnu/usr.bin/rcs/lib/maketime.h
deleted file mode 100644
index fbe1256..0000000
--- a/gnu/usr.bin/rcs/lib/maketime.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Yield time_t from struct partime yielded by partime. */
-
-/* Copyright 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#if defined(__STDC__) || has_prototypes
-# define __MAKETIME_P(x) x
-#else
-# define __MAKETIME_P(x) ()
-#endif
-
-struct tm *time2tm __MAKETIME_P((time_t,int));
-time_t difftm __MAKETIME_P((struct tm const *, struct tm const *));
-time_t str2time __MAKETIME_P((char const *, time_t, long));
-time_t tm2time __MAKETIME_P((struct tm *, int));
-void adjzone __MAKETIME_P((struct tm *, long));
diff --git a/gnu/usr.bin/rcs/lib/merger.c b/gnu/usr.bin/rcs/lib/merger.c
deleted file mode 100644
index 8f1d610..0000000
--- a/gnu/usr.bin/rcs/lib/merger.c
+++ /dev/null
@@ -1,148 +0,0 @@
-/* three-way file merge internals */
-
-/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#include "rcsbase.h"
-
-libId(mergerId, "$FreeBSD$")
-
- static char const *normalize_arg P((char const*,char**));
- static char const *
-normalize_arg(s, b)
- char const *s;
- char **b;
-/*
- * If S looks like an option, prepend ./ to it. Yield the result.
- * Set *B to the address of any storage that was allocated.
- */
-{
- char *t;
- if (*s == '-') {
- *b = t = testalloc(strlen(s) + 3);
- VOID sprintf(t, ".%c%s", SLASH, s);
- return t;
- } else {
- *b = 0;
- return s;
- }
-}
-
- int
-merge(tostdout, edarg, label, argv)
- int tostdout;
- char const *edarg;
- char const *const label[3];
- char const *const argv[3];
-/*
- * Do `merge [-p] EDARG -L l0 -L l1 -L l2 a0 a1 a2',
- * where TOSTDOUT specifies whether -p is present,
- * EDARG gives the editing type (e.g. "-A", or null for the default),
- * LABEL gives l0, l1 and l2, and ARGV gives a0, a1 and a2.
- * Yield DIFF_SUCCESS or DIFF_FAILURE.
- */
-{
- register int i;
- FILE *f;
- RILE *rt;
- char const *a[3], *t;
- char *b[3];
- int s;
-#if !DIFF3_BIN
- char const *d[2];
-#endif
-
- for (i=3; 0<=--i; )
- a[i] = normalize_arg(argv[i], &b[i]);
-
- if (!edarg)
- edarg = "-E";
-
-#if DIFF3_BIN
- t = 0;
- if (!tostdout)
- t = maketemp(0);
- s = run(
- -1, t,
- DIFF3, edarg, "-am",
- "-L", label[0],
- "-L", label[1],
- "-L", label[2],
- a[0], a[1], a[2], (char*)0
- );
- switch (s) {
- case DIFF_SUCCESS:
- break;
- case DIFF_FAILURE:
- warn("conflicts during merge");
- break;
- default:
- exiterr();
- }
- if (t) {
- if (!(f = fopenSafer(argv[0], "w")))
- efaterror(argv[0]);
- if (!(rt = Iopen(t, "r", (struct stat*)0)))
- efaterror(t);
- fastcopy(rt, f);
- Ifclose(rt);
- Ofclose(f);
- }
-#else
- for (i=0; i<2; i++)
- switch (run(
- -1, d[i]=maketemp(i),
- DIFF, a[i], a[2], (char*)0
- )) {
- case DIFF_FAILURE: case DIFF_SUCCESS: break;
- default: faterror("diff failed");
- }
- t = maketemp(2);
- s = run(
- -1, t,
- DIFF3, edarg, d[0], d[1], a[0], a[1], a[2],
- label[0], label[2], (char*)0
- );
- if (s != DIFF_SUCCESS) {
- s = DIFF_FAILURE;
- warn("overlaps or other problems during merge");
- }
- if (!(f = fopenSafer(t, "a+")))
- efaterror(t);
- aputs(tostdout ? "1,$p\n" : "w\n", f);
- Orewind(f);
- aflush(f);
- if (run(fileno(f), (char*)0, ED, "-", a[0], (char*)0))
- exiterr();
- Ofclose(f);
-#endif
-
- tempunlink();
- for (i=3; 0<=--i; )
- if (b[i])
- tfree(b[i]);
- return s;
-}
diff --git a/gnu/usr.bin/rcs/lib/partime.c b/gnu/usr.bin/rcs/lib/partime.c
deleted file mode 100644
index 05b0108..0000000
--- a/gnu/usr.bin/rcs/lib/partime.c
+++ /dev/null
@@ -1,701 +0,0 @@
-/* Parse a string, yielding a struct partime that describes it. */
-
-/* Copyright 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#if has_conf_h
-# include "conf.h"
-#else
-# ifdef __STDC__
-# define P(x) x
-# else
-# define const
-# define P(x) ()
-# endif
-# include <limits.h>
-# include <time.h>
-#endif
-
-#include <ctype.h>
-#undef isdigit
-#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than stock */
-
-#include "partime.h"
-
-char const partimeId[]
- = "$FreeBSD$";
-
-
-/* Lookup tables for names of months, weekdays, time zones. */
-
-#define NAME_LENGTH_MAXIMUM 4
-
-struct name_val {
- char name[NAME_LENGTH_MAXIMUM];
- int val;
-};
-
-
-static char const *parse_decimal P((char const*,int,int,int,int,int*,int*));
-static char const *parse_fixed P((char const*,int,int*));
-static char const *parse_pattern_letter P((char const*,int,struct partime*));
-static char const *parse_prefix P((char const*,struct partime*,int*));
-static char const *parse_ranged P((char const*,int,int,int,int*));
-static int lookup P((char const*,struct name_val const[]));
-static int merge_partime P((struct partime*, struct partime const*));
-static void undefine P((struct partime*));
-
-
-static struct name_val const month_names[] = {
- {"jan",0}, {"feb",1}, {"mar",2}, {"apr",3}, {"may",4}, {"jun",5},
- {"jul",6}, {"aug",7}, {"sep",8}, {"oct",9}, {"nov",10}, {"dec",11},
- {"", TM_UNDEFINED}
-};
-
-static struct name_val const weekday_names[] = {
- {"sun",0}, {"mon",1}, {"tue",2}, {"wed",3}, {"thu",4}, {"fri",5}, {"sat",6},
- {"", TM_UNDEFINED}
-};
-
-#define hr60nonnegative(t) ((t)/100 * 60 + (t)%100)
-#define hr60(t) ((t)<0 ? -hr60nonnegative(-(t)) : hr60nonnegative(t))
-#define zs(t,s) {s, hr60(t)}
-#define zd(t,s,d) zs(t, s), zs((t)+100, d)
-
-static struct name_val const zone_names[] = {
- zs(-1000, "hst"), /* Hawaii */
- zd(-1000,"hast","hadt"),/* Hawaii-Aleutian */
- zd(- 900,"akst","akdt"),/* Alaska */
- zd(- 800, "pst", "pdt"),/* Pacific */
- zd(- 700, "mst", "mdt"),/* Mountain */
- zd(- 600, "cst", "cdt"),/* Central */
- zd(- 500, "est", "edt"),/* Eastern */
- zd(- 400, "ast", "adt"),/* Atlantic */
- zd(- 330, "nst", "ndt"),/* Newfoundland */
- zs( 000, "utc"), /* Coordinated Universal */
- zs( 000, "cut"), /* " */
- zs( 000, "ut"), /* Universal */
- zs( 000, "z"), /* Zulu (required by ISO 8601) */
- zd( 000, "gmt", "bst"),/* Greenwich Mean, British Summer */
- zs( 000, "wet"), /* Western Europe */
- zs( 100, "met"), /* Middle Europe */
- zs( 100, "cet"), /* Central Europe */
- zs( 200, "eet"), /* Eastern Europe */
- zs( 530, "ist"), /* India */
- zd( 900, "jst", "jdt"),/* Japan */
- zd( 900, "kst", "kdt"),/* Korea */
- zd( 1200,"nzst","nzdt"),/* New Zealand */
- { "lt", 1 },
-#if 0
- /* The following names are duplicates or are not well attested. */
- zs(-1100, "sst"), /* Samoa */
- zs(-1000, "tht"), /* Tahiti */
- zs(- 930, "mqt"), /* Marquesas */
- zs(- 900, "gbt"), /* Gambier */
- zd(- 900, "yst", "ydt"),/* Yukon - name is no longer used */
- zs(- 830, "pit"), /* Pitcairn */
- zd(- 500, "cst", "cdt"),/* Cuba */
- zd(- 500, "ast", "adt"),/* Acre */
- zd(- 400, "wst", "wdt"),/* Western Brazil */
- zd(- 400, "ast", "adt"),/* Andes */
- zd(- 400, "cst", "cdt"),/* Chile */
- zs(- 300, "wgt"), /* Western Greenland */
- zd(- 300, "est", "edt"),/* Eastern South America */
- zs(- 300, "mgt"), /* Middle Greenland */
- zd(- 200, "fst", "fdt"),/* Fernando de Noronha */
- zs(- 100, "egt"), /* Eastern Greenland */
- zs(- 100, "aat"), /* Atlantic Africa */
- zs(- 100, "act"), /* Azores and Canaries */
- zs( 000, "wat"), /* West Africa */
- zs( 100, "cat"), /* Central Africa */
- zd( 100, "mez","mesz"),/* Mittel-Europaeische Zeit */
- zs( 200, "sat"), /* South Africa */
- zd( 200, "ist", "idt"),/* Israel */
- zs( 300, "eat"), /* East Africa */
- zd( 300, "ast", "adt"),/* Arabia */
- zd( 300, "msk", "msd"),/* Moscow */
- zd( 330, "ist", "idt"),/* Iran */
- zs( 400, "gst"), /* Gulf */
- zs( 400, "smt"), /* Seychelles & Mascarene */
- zd( 400, "esk", "esd"),/* Yekaterinburg */
- zd( 400, "bsk", "bsd"),/* Baku */
- zs( 430, "aft"), /* Afghanistan */
- zd( 500, "osk", "osd"),/* Omsk */
- zs( 500, "pkt"), /* Pakistan */
- zd( 500, "tsk", "tsd"),/* Tashkent */
- zs( 545, "npt"), /* Nepal */
- zs( 600, "bgt"), /* Bangladesh */
- zd( 600, "nsk", "nsd"),/* Novosibirsk */
- zs( 630, "bmt"), /* Burma */
- zs( 630, "cct"), /* Cocos */
- zs( 700, "ict"), /* Indochina */
- zs( 700, "jvt"), /* Java */
- zd( 700, "isk", "isd"),/* Irkutsk */
- zs( 800, "hkt"), /* Hong Kong */
- zs( 800, "pst"), /* Philippines */
- zs( 800, "sgt"), /* Singapore */
- zd( 800, "cst", "cdt"),/* China */
- zd( 800, "ust", "udt"),/* Ulan Bator */
- zd( 800, "wst", "wst"),/* Western Australia */
- zd( 800, "ysk", "ysd"),/* Yakutsk */
- zs( 900, "blt"), /* Belau */
- zs( 900, "mlt"), /* Moluccas */
- zd( 900, "vsk", "vsd"),/* Vladivostok */
- zd( 930, "cst", "cst"),/* Central Australia */
- zs( 1000, "gst"), /* Guam */
- zd( 1000, "gsk", "gsd"),/* Magadan */
- zd( 1000, "est", "est"),/* Eastern Australia */
- zd( 1100,"lhst","lhst"),/* Lord Howe */
- zd( 1100, "psk", "psd"),/* Petropavlovsk-Kamchatski */
- zs( 1100,"ncst"), /* New Caledonia */
- zs( 1130,"nrft"), /* Norfolk */
- zd( 1200, "ask", "asd"),/* Anadyr */
- zs( 1245,"nz-chat"), /* Chatham */
- zs( 1300, "tgt"), /* Tongatapu */
-#endif
- {"", -1}
-};
-
- static int
-lookup (s, table)
- char const *s;
- struct name_val const table[];
-/* Look for a prefix of S in TABLE, returning val for first matching entry. */
-{
- int j;
- char buf[NAME_LENGTH_MAXIMUM];
-
- for (j = 0; j < NAME_LENGTH_MAXIMUM; j++) {
- unsigned char c = *s++;
- buf[j] = isupper (c) ? tolower (c) : c;
- if (!isalpha (c))
- break;
- }
- for (; table[0].name[0]; table++)
- for (j = 0; buf[j] == table[0].name[j]; )
- if (++j == NAME_LENGTH_MAXIMUM || !table[0].name[j])
- goto done;
- done:
- return table[0].val;
-}
-
-
- static void
-undefine (t) struct partime *t;
-/* Set *T to ``undefined'' values. */
-{
- t->tm.tm_sec = t->tm.tm_min = t->tm.tm_hour = t->tm.tm_mday = t->tm.tm_mon
- = t->tm.tm_year = t->tm.tm_wday = t->tm.tm_yday
- = t->ymodulus = t->yweek
- = TM_UNDEFINED;
- t->zone = TM_UNDEFINED_ZONE;
-}
-
-/*
-* Array of patterns to look for in a date string.
-* Order is important: we look for the first matching pattern
-* whose values do not contradict values that we already know about.
-* See `parse_pattern_letter' below for the meaning of the pattern codes.
-*/
-static char const * const patterns[] = {
- /*
- * These traditional patterns must come first,
- * to prevent an ISO 8601 format from misinterpreting their prefixes.
- */
- "E_n_y", "x", /* RFC 822 */
- "E_n", "n_E", "n", "t:m:s_A", "t:m_A", "t_A", /* traditional */
- "y/N/D$", /* traditional RCS */
-
- /* ISO 8601:1988 formats, generalized a bit. */
- "y-N-D$", "4ND$", "Y-N$",
- "RND$", "-R=N$", "-R$", "--N=D$", "N=DT",
- "--N$", "---D$", "DT",
- "Y-d$", "4d$", "R=d$", "-d$", "dT",
- "y-W-X", "yWX", "y=W",
- "-r-W-X", "r-W-XT", "-rWX", "rWXT", "-W=X", "W=XT", "-W",
- "-w-X", "w-XT", "---X$", "XT", "4$",
- "T",
- "h:m:s$", "hms$", "h:m$", "hm$", "h$", "-m:s$", "-ms$", "-m$", "--s$",
- "Y", "Z",
-
- 0
-};
-
- static char const *
-parse_prefix (str, t, pi) char const *str; struct partime *t; int *pi;
-/*
-* Parse an initial prefix of STR, setting *T accordingly.
-* Return the first character after the prefix, or 0 if it couldn't be parsed.
-* Start with pattern *PI; if success, set *PI to the next pattern to try.
-* Set *PI to -1 if we know there are no more patterns to try;
-* if *PI is initially negative, give up immediately.
-*/
-{
- int i = *pi;
- char const *pat;
- unsigned char c;
-
- if (i < 0)
- return 0;
-
- /* Remove initial noise. */
- while (!isalnum (c = *str) && c != '-' && c != '+') {
- if (!c) {
- undefine (t);
- *pi = -1;
- return str;
- }
- str++;
- }
-
- /* Try a pattern until one succeeds. */
- while ((pat = patterns[i++]) != 0) {
- char const *s = str;
- undefine (t);
- do {
- if (!(c = *pat++)) {
- *pi = i;
- return s;
- }
- } while ((s = parse_pattern_letter (s, c, t)) != 0);
- }
-
- return 0;
-}
-
- static char const *
-parse_fixed (s, digits, res) char const *s; int digits, *res;
-/*
-* Parse an initial prefix of S of length DIGITS; it must be a number.
-* Store the parsed number into *RES.
-* Return the first character after the prefix, or 0 if it couldn't be parsed.
-*/
-{
- int n = 0;
- char const *lim = s + digits;
- while (s < lim) {
- unsigned d = *s++ - '0';
- if (9 < d)
- return 0;
- n = 10*n + d;
- }
- *res = n;
- return s;
-}
-
- static char const *
-parse_ranged (s, digits, lo, hi, res) char const *s; int digits, lo, hi, *res;
-/*
-* Parse an initial prefix of S of length DIGITS;
-* it must be a number in the range LO through HI.
-* Store the parsed number into *RES.
-* Return the first character after the prefix, or 0 if it couldn't be parsed.
-*/
-{
- s = parse_fixed (s, digits, res);
- return s && lo<=*res && *res<=hi ? s : 0;
-}
-
- static char const *
-parse_decimal (s, digits, lo, hi, resolution, res, fres)
- char const *s;
- int digits, lo, hi, resolution, *res, *fres;
-/*
-* Parse an initial prefix of S of length DIGITS;
-* it must be a number in the range LO through HI
-* and it may be followed by a fraction that is to be computed using RESOLUTION.
-* Store the parsed number into *RES; store the fraction times RESOLUTION,
-* rounded to the nearest integer, into *FRES.
-* Return the first character after the prefix, or 0 if it couldn't be parsed.
-*/
-{
- s = parse_fixed (s, digits, res);
- if (s && lo<=*res && *res<=hi) {
- int f = 0;
- if ((s[0]==',' || s[0]=='.') && isdigit ((unsigned char) s[1])) {
- char const *s1 = ++s;
- int num10 = 0, denom10 = 10, product;
- while (isdigit ((unsigned char) *++s))
- denom10 *= 10;
- s = parse_fixed (s1, s - s1, &num10);
- product = num10*resolution;
- f = (product + (denom10>>1)) / denom10;
- f -= f & (product%denom10 == denom10>>1); /* round to even */
- if (f < 0 || product/resolution != num10)
- return 0; /* overflow */
- }
- *fres = f;
- return s;
- }
- return 0;
-}
-
- char *
-parzone (s, zone) char const *s; long *zone;
-/*
-* Parse an initial prefix of S; it must denote a time zone.
-* Set *ZONE to the number of seconds east of GMT,
-* or to TM_LOCAL_ZONE if it is the local time zone.
-* Return the first character after the prefix, or 0 if it couldn't be parsed.
-*/
-{
- char sign;
- int hh, mm, ss;
- int minutesEastOfUTC;
- long offset, z;
-
- /*
- * The formats are LT, n, n DST, nDST, no, o
- * where n is a time zone name
- * and o is a time zone offset of the form [-+]hh[:mm[:ss]].
- */
- switch (*s) {
- case '-': case '+':
- z = 0;
- break;
-
- default:
- minutesEastOfUTC = lookup (s, zone_names);
- if (minutesEastOfUTC == -1)
- return 0;
-
- /* Don't bother to check rest of spelling. */
- while (isalpha ((unsigned char) *s))
- s++;
-
- /* Don't modify LT. */
- if (minutesEastOfUTC == 1) {
- *zone = TM_LOCAL_ZONE;
- return (char *) s;
- }
-
- z = minutesEastOfUTC * 60L;
-
- /* Look for trailing " DST". */
- if (
- (s[-1]=='T' || s[-1]=='t') &&
- (s[-2]=='S' || s[-2]=='s') &&
- (s[-3]=='D' || s[-3]=='t')
- )
- goto trailing_dst;
- while (isspace ((unsigned char) *s))
- s++;
- if (
- (s[0]=='D' || s[0]=='d') &&
- (s[1]=='S' || s[1]=='s') &&
- (s[2]=='T' || s[2]=='t')
- ) {
- s += 3;
- trailing_dst:
- *zone = z + 60*60;
- return (char *) s;
- }
-
- switch (*s) {
- case '-': case '+': break;
- default: return (char *) s;
- }
- }
- sign = *s++;
-
- if (!(s = parse_ranged (s, 2, 0, 23, &hh)))
- return 0;
- mm = ss = 0;
- if (*s == ':')
- s++;
- if (isdigit ((unsigned char) *s)) {
- if (!(s = parse_ranged (s, 2, 0, 59, &mm)))
- return 0;
- if (*s==':' && s[-3]==':' && isdigit ((unsigned char) s[1])) {
- if (!(s = parse_ranged (s + 1, 2, 0, 59, &ss)))
- return 0;
- }
- }
- if (isdigit ((unsigned char) *s))
- return 0;
- offset = (hh*60 + mm)*60L + ss;
- *zone = z + (sign=='-' ? -offset : offset);
- /*
- * ?? Are fractions allowed here?
- * If so, they're not implemented.
- */
- return (char *) s;
-}
-
- static char const *
-parse_pattern_letter (s, c, t) char const *s; int c; struct partime *t;
-/*
-* Parse an initial prefix of S, matching the pattern whose code is C.
-* Set *T accordingly.
-* Return the first character after the prefix, or 0 if it couldn't be parsed.
-*/
-{
- switch (c) {
- case '$': /* The next character must be a non-digit. */
- if (isdigit ((unsigned char) *s))
- return 0;
- break;
-
- case '-': case '/': case ':':
- /* These characters stand for themselves. */
- if (*s++ != c)
- return 0;
- break;
-
- case '4': /* 4-digit year */
- s = parse_fixed (s, 4, &t->tm.tm_year);
- break;
-
- case '=': /* optional '-' */
- s += *s == '-';
- break;
-
- case 'A': /* AM or PM */
- /*
- * This matches the regular expression [AaPp][Mm]?.
- * It must not be followed by a letter or digit;
- * otherwise it would match prefixes of strings like "PST".
- */
- switch (*s++) {
- case 'A': case 'a':
- if (t->tm.tm_hour == 12)
- t->tm.tm_hour = 0;
- break;
-
- case 'P': case 'p':
- if (t->tm.tm_hour != 12)
- t->tm.tm_hour += 12;
- break;
-
- default: return 0;
- }
- switch (*s) {
- case 'M': case 'm': s++; break;
- }
- if (isalnum (*s))
- return 0;
- break;
-
- case 'D': /* day of month [01-31] */
- s = parse_ranged (s, 2, 1, 31, &t->tm.tm_mday);
- break;
-
- case 'd': /* day of year [001-366] */
- s = parse_ranged (s, 3, 1, 366, &t->tm.tm_yday);
- t->tm.tm_yday--;
- break;
-
- case 'E': /* extended day of month [1-9, 01-31] */
- s = parse_ranged (s, (
- isdigit ((unsigned char) s[0]) &&
- isdigit ((unsigned char) s[1])
- ) + 1, 1, 31, &t->tm.tm_mday);
- break;
-
- case 'h': /* hour [00-23 followed by optional fraction] */
- {
- int frac;
- s = parse_decimal (s, 2, 0, 23, 60*60, &t->tm.tm_hour, &frac);
- t->tm.tm_min = frac / 60;
- t->tm.tm_sec = frac % 60;
- }
- break;
-
- case 'm': /* minute [00-59 followed by optional fraction] */
- s = parse_decimal (s, 2, 0, 59, 60, &t->tm.tm_min, &t->tm.tm_sec);
- break;
-
- case 'n': /* month name [e.g. "Jan"] */
- if (!TM_DEFINED (t->tm.tm_mon = lookup (s, month_names)))
- return 0;
- /* Don't bother to check rest of spelling. */
- while (isalpha ((unsigned char) *s))
- s++;
- break;
-
- case 'N': /* month [01-12] */
- s = parse_ranged (s, 2, 1, 12, &t->tm.tm_mon);
- t->tm.tm_mon--;
- break;
-
- case 'r': /* year % 10 (remainder in origin-0 decade) [0-9] */
- s = parse_fixed (s, 1, &t->tm.tm_year);
- t->ymodulus = 10;
- break;
-
- case_R:
- case 'R': /* year % 100 (remainder in origin-0 century) [00-99] */
- s = parse_fixed (s, 2, &t->tm.tm_year);
- t->ymodulus = 100;
- break;
-
- case 's': /* second [00-60 followed by optional fraction] */
- {
- int frac;
- s = parse_decimal (s, 2, 0, 60, 1, &t->tm.tm_sec, &frac);
- t->tm.tm_sec += frac;
- }
- break;
-
- case 'T': /* 'T' or 't' */
- switch (*s++) {
- case 'T': case 't': break;
- default: return 0;
- }
- break;
-
- case 't': /* traditional hour [1-9 or 01-12] */
- s = parse_ranged (s, (
- isdigit ((unsigned char) s[0]) && isdigit ((unsigned char) s[1])
- ) + 1, 1, 12, &t->tm.tm_hour);
- break;
-
- case 'w': /* 'W' or 'w' only (stands for current week) */
- switch (*s++) {
- case 'W': case 'w': break;
- default: return 0;
- }
- break;
-
- case 'W': /* 'W' or 'w', followed by a week of year [00-53] */
- switch (*s++) {
- case 'W': case 'w': break;
- default: return 0;
- }
- s = parse_ranged (s, 2, 0, 53, &t->yweek);
- break;
-
- case 'X': /* weekday (1=Mon ... 7=Sun) [1-7] */
- s = parse_ranged (s, 1, 1, 7, &t->tm.tm_wday);
- t->tm.tm_wday--;
- break;
-
- case 'x': /* weekday name [e.g. "Sun"] */
- if (!TM_DEFINED (t->tm.tm_wday = lookup (s, weekday_names)))
- return 0;
- /* Don't bother to check rest of spelling. */
- while (isalpha ((unsigned char) *s))
- s++;
- break;
-
- case 'y': /* either R or Y */
- if (
- isdigit ((unsigned char) s[0]) &&
- isdigit ((unsigned char) s[1]) &&
- !isdigit ((unsigned char) s[2])
- )
- goto case_R;
- /* fall into */
- case 'Y': /* year in full [4 or more digits] */
- {
- int len = 0;
- while (isdigit ((unsigned char) s[len]))
- len++;
- if (len < 4)
- return 0;
- s = parse_fixed (s, len, &t->tm.tm_year);
- }
- break;
-
- case 'Z': /* time zone */
- s = parzone (s, &t->zone);
- break;
-
- case '_': /* possibly empty sequence of non-alphanumerics */
- while (!isalnum (*s) && *s)
- s++;
- break;
-
- default: /* bad pattern */
- return 0;
- }
- return s;
-}
-
- static int
-merge_partime (t, u) struct partime *t; struct partime const *u;
-/*
-* If there is no conflict, merge into *T the additional information in *U
-* and return 0. Otherwise do nothing and return -1.
-*/
-{
-# define conflict(a,b) ((a) != (b) && TM_DEFINED (a) && TM_DEFINED (b))
- if (
- conflict (t->tm.tm_sec, u->tm.tm_sec) ||
- conflict (t->tm.tm_min, u->tm.tm_min) ||
- conflict (t->tm.tm_hour, u->tm.tm_hour) ||
- conflict (t->tm.tm_mday, u->tm.tm_mday) ||
- conflict (t->tm.tm_mon, u->tm.tm_mon) ||
- conflict (t->tm.tm_year, u->tm.tm_year) ||
- conflict (t->tm.tm_wday, u->tm.tm_yday) ||
- conflict (t->ymodulus, u->ymodulus) ||
- conflict (t->yweek, u->yweek) ||
- (
- t->zone != u->zone &&
- t->zone != TM_UNDEFINED_ZONE &&
- u->zone != TM_UNDEFINED_ZONE
- )
- )
- return -1;
-# undef conflict
-# define merge_(a,b) if (TM_DEFINED (b)) (a) = (b);
- merge_ (t->tm.tm_sec, u->tm.tm_sec)
- merge_ (t->tm.tm_min, u->tm.tm_min)
- merge_ (t->tm.tm_hour, u->tm.tm_hour)
- merge_ (t->tm.tm_mday, u->tm.tm_mday)
- merge_ (t->tm.tm_mon, u->tm.tm_mon)
- merge_ (t->tm.tm_year, u->tm.tm_year)
- merge_ (t->tm.tm_wday, u->tm.tm_yday)
- merge_ (t->ymodulus, u->ymodulus)
- merge_ (t->yweek, u->yweek)
-# undef merge_
- if (u->zone != TM_UNDEFINED_ZONE) t->zone = u->zone;
- return 0;
-}
-
- char *
-partime (s, t) char const *s; struct partime *t;
-/*
-* Parse a date/time prefix of S, putting the parsed result into *T.
-* Return the first character after the prefix.
-* The prefix may contain no useful information;
-* in that case, *T will contain only undefined values.
-*/
-{
- struct partime p;
-
- undefine (t);
- while (*s) {
- int i = 0;
- char const *s1;
- do {
- if (!(s1 = parse_prefix (s, &p, &i)))
- return (char *) s;
- } while (merge_partime (t, &p) != 0);
- s = s1;
- }
- return (char *) s;
-}
diff --git a/gnu/usr.bin/rcs/lib/partime.h b/gnu/usr.bin/rcs/lib/partime.h
deleted file mode 100644
index 5d3983f..0000000
--- a/gnu/usr.bin/rcs/lib/partime.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* Parse a string, yielding a struct partime that describes it. */
-
-/* Copyright 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#define TM_UNDEFINED (-1)
-#define TM_DEFINED(x) (0 <= (x))
-
-#define TM_UNDEFINED_ZONE ((long) -24 * 60 * 60)
-#define TM_LOCAL_ZONE (TM_UNDEFINED_ZONE - 1)
-
-struct partime {
- /*
- * This structure describes the parsed time.
- * Only the following tm_* values in it are used:
- * sec, min, hour, mday, mon, year, wday, yday.
- * If TM_UNDEFINED(value), the parser never found the value.
- * The tm_year field is the actual year, not the year - 1900;
- * but see ymodulus below.
- */
- struct tm tm;
-
- /*
- * If !TM_UNDEFINED(ymodulus),
- * then tm.tm_year is actually modulo ymodulus.
- */
- int ymodulus;
-
- /*
- * Week of year, ISO 8601 style.
- * If TM_UNDEFINED(yweek), the parser never found yweek.
- * Weeks start on Mondays.
- * Week 1 includes Jan 4.
- */
- int yweek;
-
- /* Seconds east of UTC; or TM_LOCAL_ZONE or TM_UNDEFINED_ZONE. */
- long zone;
-};
-
-#if defined(__STDC__) || has_prototypes
-# define __PARTIME_P(x) x
-#else
-# define __PARTIME_P(x) ()
-#endif
-
-char *partime __PARTIME_P((char const *, struct partime *));
-char *parzone __PARTIME_P((char const *, long *));
diff --git a/gnu/usr.bin/rcs/lib/rcsbase.h b/gnu/usr.bin/rcs/lib/rcsbase.h
deleted file mode 100644
index 9f2f68c..0000000
--- a/gnu/usr.bin/rcs/lib/rcsbase.h
+++ /dev/null
@@ -1,762 +0,0 @@
-/* RCS common definitions and data structures */
-
-#define RCSBASE "$FreeBSD$"
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.20 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.19 1995/06/01 16:23:43 eggert
- * (SIZEABLE_PATH): Don't depend on PATH_MAX: it's not worth configuring.
- * (Ioffset_type,BINARY_EXPAND,MIN_UNEXPAND,MIN_UNCHANGED_EXPAND): New macros.
- * (maps_memory): New macro; replaces many instances of `has_mmap'.
- * (cacheptr): Renamed from cachetell.
- * (struct RILE): New alternate name for RILE; the type is now recursive.
- * (deallocate): New member for RILE, used for generic buffer deallocation.
- * (cacheunget_): No longer take a failure arg; just call Ierror on failure.
- * (struct rcslock): Renamed from struct lock, to avoid collisions with
- * system headers on some hosts. All users changed.
- * (basefilename): Renamed from basename, likewise.
- * (dirtpname): Remove; no longer external.
- * (dirlen, dateform): Remove; no longer used.
- * (cmpdate, fopenSafer, fdSafer, readAccessFilenameBuffer): New functions.
- * (zonelenmax): Increase to 9 for full ISO 8601 format.
- * (catchmmapints): Depend on has_NFS.
- *
- * Revision 5.18 1994/03/17 14:05:48 eggert
- * Add primitives for reading backwards from a RILE;
- * this is needed to go back and find the $Log prefix.
- * Specify subprocess input via file descriptor, not file name. Remove lint.
- *
- * Revision 5.17 1993/11/09 17:40:15 eggert
- * Move RCS-specific time handling into rcstime.c.
- * printf_string now takes two arguments, alas.
- *
- * Revision 5.16 1993/11/03 17:42:27 eggert
- * Don't arbitrarily limit the number of joins. Remove `nil'.
- * Add Name keyword. Don't discard ignored phrases.
- * Add support for merge -A vs -E, and allow up to three labels.
- * Improve quality of diagnostics and prototypes.
- *
- * Revision 5.15 1992/07/28 16:12:44 eggert
- * Statement macro names now end in _.
- *
- * Revision 5.14 1992/02/17 23:02:22 eggert
- * Add -T support. Work around NFS mmap SIGBUS problem.
- *
- * Revision 5.13 1992/01/24 18:44:19 eggert
- * Add support for bad_creat0. lint -> RCS_lint
- *
- * Revision 5.12 1992/01/06 02:42:34 eggert
- * while (E) ; -> while (E) continue;
- *
- * Revision 5.11 1991/10/07 17:32:46 eggert
- * Support piece tables even if !has_mmap.
- *
- * Revision 5.10 1991/09/24 00:28:39 eggert
- * Remove unexported functions.
- *
- * Revision 5.9 1991/08/19 03:13:55 eggert
- * Add piece tables and other tuneups, and NFS workarounds.
- *
- * Revision 5.8 1991/04/21 11:58:20 eggert
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.7 1991/02/28 19:18:50 eggert
- * Try setuid() if seteuid() doesn't work.
- *
- * Revision 5.6 1991/02/26 17:48:37 eggert
- * Support new link behavior. Move ANSI C / Posix declarations into conf.sh.
- *
- * Revision 5.5 1990/12/04 05:18:43 eggert
- * Use -I for prompts and -q for diagnostics.
- *
- * Revision 5.4 1990/11/01 05:03:35 eggert
- * Don't assume that builtins are functions; they may be macros.
- * Permit arbitrary data in logs.
- *
- * Revision 5.3 1990/09/26 23:36:58 eggert
- * Port wait() to non-Posix ANSI C hosts.
- *
- * Revision 5.2 1990/09/04 08:02:20 eggert
- * Don't redefine NAME_MAX, PATH_MAX.
- * Improve incomplete line handling. Standardize yes-or-no procedure.
- *
- * Revision 5.1 1990/08/29 07:13:53 eggert
- * Add -kkvl. Fix type typos exposed by porting. Clean old log messages too.
- *
- * Revision 5.0 1990/08/22 08:12:44 eggert
- * Adjust ANSI C / Posix support. Add -k, -V, setuid. Don't call access().
- * Remove compile-time limits; use malloc instead.
- * Ansify and Posixate. Add support for ISO 8859.
- * Remove snoop and v2 support.
- *
- * Revision 4.9 89/05/01 15:17:14 narten
- * botched previous USG fix
- *
- * Revision 4.8 89/05/01 14:53:05 narten
- * changed #include <strings.h> -> string.h for USG systems.
- *
- * Revision 4.7 88/11/08 15:58:45 narten
- * removed defs for functions loaded from libraries
- *
- * Revision 4.6 88/08/09 19:12:36 eggert
- * Shrink stdio code size; remove lint; permit -Dhshsize=nn.
- *
- * Revision 4.5 87/12/18 17:06:41 narten
- * made removed BSD ifdef, now uses V4_2BSD
- *
- * Revision 4.4 87/10/18 10:29:49 narten
- * Updating version numbers
- * Changes relative to 1.1 are actually relative to 4.2
- *
- * Revision 1.3 87/09/24 14:02:25 narten
- * changes for lint
- *
- * Revision 1.2 87/03/27 14:22:02 jenkins
- * Port to suns
- *
- * Revision 4.2 83/12/20 16:04:20 wft
- * merged 3.6.1.1 and 4.1 (SMALLOG, logsize).
- * moved setting of STRICT_LOCKING to Makefile.
- * changed DOLLAR to UNKN (conflict with KDELIM).
- *
- * Revision 4.1 83/05/04 09:12:41 wft
- * Added markers Id and RCSfile.
- * Added Dbranch for default branches.
- *
- * Revision 3.6.1.1 83/12/02 21:56:22 wft
- * Increased logsize, added macro SMALLOG.
- *
- * Revision 3.6 83/01/15 16:43:28 wft
- * 4.2 prerelease
- *
- * Revision 3.6 83/01/15 16:43:28 wft
- * Replaced dbm.h with BYTESIZ, fixed definition of rindex().
- * Added variants of NCPFN and NCPPN for bsd 4.2, selected by defining V4_2BSD.
- * Added macro DELNUMFORM to have uniform format for printing delta text nodes.
- * Added macro DELETE to mark deleted deltas.
- *
- * Revision 3.5 82/12/10 12:16:56 wft
- * Added two forms of DATEFORM, one using %02d, the other %.2d.
- *
- * Revision 3.4 82/12/04 20:01:25 wft
- * added LOCKER, Locker, and USG (redefinition of rindex).
- *
- * Revision 3.3 82/12/03 12:22:04 wft
- * Added dbm.h, stdio.h, RCSBASE, RCSSEP, RCSSUF, WORKMODE, TMPFILE3,
- * PRINTDATE, PRINTTIME, map, and ctab; removed Suffix. Redefined keyvallength
- * using NCPPN. Changed putc() to abort on write error.
- *
- * Revision 3.2 82/10/18 15:03:52 wft
- * added macro STRICT_LOCKING, removed RCSUMASK.
- * renamed JOINFILE[1,2] to JOINFIL[1,2].
- *
- * Revision 3.1 82/10/11 19:41:17 wft
- * removed NBPW, NBPC, NCPW.
- * added typdef int void to aid compiling
- */
-
-
-#include "conf.h"
-
-
-#define EXIT_TROUBLE DIFF_TROUBLE
-
-#ifdef _POSIX_PATH_MAX
-# define SIZEABLE_PATH _POSIX_PATH_MAX
-#else
-# define SIZEABLE_PATH 255 /* size of a large path; not a hard limit */
-#endif
-
-/* for traditional C hosts with unusual size arguments */
-#define Fread(p,s,n,f) fread(p, (freadarg_type)(s), (freadarg_type)(n), f)
-#define Fwrite(p,s,n,f) fwrite(p, (freadarg_type)(s), (freadarg_type)(n), f)
-
-
-/*
- * Parameters
- */
-
-/* backwards compatibility with old versions of RCS */
-#define VERSION_min 3 /* old output RCS format supported */
-#define VERSION_max 5 /* newest output RCS format supported */
-#ifndef VERSION_DEFAULT /* default RCS output format */
-# define VERSION_DEFAULT VERSION_max
-#endif
-#define VERSION(n) ((n) - VERSION_DEFAULT) /* internally, 0 is the default */
-
-#ifndef STRICT_LOCKING
-#define STRICT_LOCKING 1
-#endif
- /* 0 sets the default locking to non-strict; */
- /* used in experimental environments. */
- /* 1 sets the default locking to strict; */
- /* used in production environments. */
-
-#define yearlength 16 /* (good through AD 9,999,999,999,999,999) */
-#define datesize (yearlength+16) /* size of output of time2date */
-#define RCSTMPPREFIX '_' /* prefix for temp files in working dir */
-#define KDELIM '$' /* delimiter for keywords */
-#define VDELIM ':' /* separates keywords from values */
-#define DEFAULTSTATE "Exp" /* default state of revisions */
-
-
-
-#define true 1
-#define false 0
-
-
-/*
- * RILE - readonly file
- * declarecache; - declares local cache for RILE variable(s)
- * setupcache - sets up the local RILE cache, but does not initialize it
- * cache, uncache - caches and uncaches the local RILE;
- * (uncache,cache) is needed around functions that advance the RILE pointer
- * Igeteof_(f,c,s) - get a char c from f, executing statement s at EOF
- * cachegeteof_(c,s) - Igeteof_ applied to the local RILE
- * Iget_(f,c) - like Igeteof_, except EOF is an error
- * cacheget_(c) - Iget_ applied to the local RILE
- * cacheunget_(f,c,s) - read c backwards from cached f, executing s at BOF
- * Ifileno, Ioffset_type, Irewind, Itell - analogs to stdio routines
- *
- * By conventions, macros whose names end in _ are statements, not expressions.
- * Following such macros with `; else' results in a syntax error.
- */
-
-#define maps_memory (has_map_fd || has_mmap)
-
-#if large_memory
- typedef unsigned char const *Iptr_type;
- typedef struct RILE {
- Iptr_type ptr, lim;
- unsigned char *base; /* not Iptr_type for lint's sake */
- unsigned char *readlim;
- int fd;
-# if maps_memory
- void (*deallocate) P((struct RILE *));
-# else
- FILE *stream;
-# endif
- } RILE;
-# if maps_memory
-# define declarecache register Iptr_type ptr, lim
-# define setupcache(f) (lim = (f)->lim)
-# define Igeteof_(f,c,s) if ((f)->ptr==(f)->lim) s else (c)= *(f)->ptr++;
-# define cachegeteof_(c,s) if (ptr==lim) s else (c)= *ptr++;
-# else
- int Igetmore P((RILE*));
-# define declarecache register Iptr_type ptr; register RILE *rRILE
-# define setupcache(f) (rRILE = (f))
-# define Igeteof_(f,c,s) if ((f)->ptr==(f)->readlim && !Igetmore(f)) s else (c)= *(f)->ptr++;
-# define cachegeteof_(c,s) if (ptr==rRILE->readlim && !Igetmore(rRILE)) s else (c)= *ptr++;
-# endif
-# define uncache(f) ((f)->ptr = ptr)
-# define cache(f) (ptr = (f)->ptr)
-# define Iget_(f,c) Igeteof_(f,c,Ieof();)
-# define cacheget_(c) cachegeteof_(c,Ieof();)
-# define cacheunget_(f,c) (c)=(--ptr)[-1];
-# define Ioffset_type size_t
-# define Itell(f) ((f)->ptr - (f)->base)
-# define Irewind(f) ((f)->ptr = (f)->base)
-# define cacheptr() ptr
-# define Ifileno(f) ((f)->fd)
-#else
-# define RILE FILE
-# define declarecache register FILE *ptr
-# define setupcache(f) (ptr = (f))
-# define uncache(f)
-# define cache(f)
-# define Igeteof_(f,c,s) {if(((c)=getc(f))==EOF){testIerror(f);if(feof(f))s}}
-# define cachegeteof_(c,s) Igeteof_(ptr,c,s)
-# define Iget_(f,c) { if (((c)=getc(f))==EOF) testIeof(f); }
-# define cacheget_(c) Iget_(ptr,c)
-# define cacheunget_(f,c) if(fseek(ptr,-2L,SEEK_CUR))Ierror();else cacheget_(c)
-# define Ioffset_type long
-# define Itell(f) ftell(f)
-# define Ifileno(f) fileno(f)
-#endif
-
-/* Print a char, but abort on write error. */
-#define aputc_(c,o) { if (putc(c,o)==EOF) testOerror(o); }
-
-/* Get a character from an RCS file, perhaps copying to a new RCS file. */
-#define GETCeof_(o,c,s) { cachegeteof_(c,s) if (o) aputc_(c,o) }
-#define GETC_(o,c) { cacheget_(c) if (o) aputc_(c,o) }
-
-
-#define WORKMODE(RCSmode, writable) (((RCSmode)&(mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH)) | ((writable)?S_IWUSR:0))
-/* computes mode of working file: same as RCSmode, but write permission */
-/* determined by writable */
-
-
-/* character classes and token codes */
-enum tokens {
-/* classes */ DELIM, DIGIT, IDCHAR, NEWLN, LETTER, Letter,
- PERIOD, SBEGIN, SPACE, UNKN,
-/* tokens */ COLON, ID, NUM, SEMI, STRING
-};
-
-#define SDELIM '@' /* the actual character is needed for string handling*/
-/* SDELIM must be consistent with ctab[], so that ctab[SDELIM]==SBEGIN.
- * there should be no overlap among SDELIM, KDELIM, and VDELIM
- */
-
-#define isdigit(c) (((unsigned)(c)-'0') <= 9) /* faster than ctab[c]==DIGIT */
-
-
-
-
-
-/***************************************
- * Data structures for the symbol table
- ***************************************/
-
-/* Buffer of arbitrary data */
-struct buf {
- char *string;
- size_t size;
-};
-struct cbuf {
- char const *string;
- size_t size;
-};
-
-/* Hash table entry */
-struct hshentry {
- char const * num; /* pointer to revision number (ASCIZ) */
- char const * date; /* pointer to date of checkin */
- char const * author; /* login of person checking in */
- char const * lockedby; /* who locks the revision */
- char const * state; /* state of revision (Exp by default) */
- char const * name; /* name (if any) by which retrieved */
- struct cbuf log; /* log message requested at checkin */
- struct branchhead * branches; /* list of first revisions on branches*/
- struct cbuf ig; /* ignored phrases in admin part */
- struct cbuf igtext; /* ignored phrases in deltatext part */
- struct hshentry * next; /* next revision on same branch */
- struct hshentry * nexthsh; /* next revision with same hash value */
- long insertlns;/* lines inserted (computed by rlog) */
- long deletelns;/* lines deleted (computed by rlog) */
- char selector; /* true if selected, false if deleted */
-};
-
-/* list of hash entries */
-struct hshentries {
- struct hshentries *rest;
- struct hshentry *first;
-};
-
-/* list element for branch lists */
-struct branchhead {
- struct hshentry * hsh;
- struct branchhead * nextbranch;
-};
-
-/* accesslist element */
-struct access {
- char const * login;
- struct access * nextaccess;
-};
-
-/* list element for locks */
-struct rcslock {
- char const * login;
- struct hshentry * delta;
- struct rcslock * nextlock;
-};
-
-/* list element for symbolic names */
-struct assoc {
- char const * symbol;
- char const * num;
- struct assoc * nextassoc;
-};
-
-
-#define mainArgs (argc,argv) int argc; char **argv;
-
-#if RCS_lint
-# define libId(name,rcsid)
-# define mainProg(name,cmd,rcsid) int name mainArgs
-#else
-# define libId(name,rcsid) char const name[] = rcsid;
-# define mainProg(n,c,i) char const Copyright[] = "Copyright 1982,1988,1989 Walter F. Tichy, Purdue CS\nCopyright 1990,1991,1992,1993,1994,1995 Paul Eggert", baseid[] = RCSBASE, cmdid[] = c; libId(n,i) int main P((int,char**)); int main mainArgs
-#endif
-
-/*
- * Markers for keyword expansion (used in co and ident)
- * Every byte must have class LETTER or Letter.
- */
-#define AUTHOR "Author"
-#define DATE "Date"
-#define HEADER "Header"
-#define IDH "Id"
-#define LOCKER "Locker"
-#define LOG "Log"
-#define NAME "Name"
-#define RCSFILE "RCSfile"
-#define REVISION "Revision"
-#define SOURCE "Source"
-#define STATE "State"
-#define CVSHEADER "CVSHeader"
-#define keylength 9 /* max length of any of the above keywords */
-
-enum markers { Nomatch, Author, Date, Header, Id,
- Locker, Log, Name, RCSfile, Revision, Source, State, CVSHeader,
- LocalId };
- /* This must be in the same order as rcskeys.c's Keyword[] array. */
-
-#define DELNUMFORM "\n\n%s\n%s\n"
-/* used by putdtext and scanlogtext */
-
-#define EMPTYLOG "*** empty log message ***" /* used by ci and rlog */
-
-/* main program */
-extern char const cmdid[];
-void exiterr P((void)) exiting;
-
-/* merge */
-int merge P((int,char const*,char const*const[3],char const*const[3]));
-
-/* rcsedit */
-#define ciklogsize 23 /* sizeof("checked in with -k by ") */
-extern FILE *fcopy;
-extern char const *resultname;
-extern char const ciklog[ciklogsize];
-extern int locker_expansion;
-RILE *rcswriteopen P((struct buf*,struct stat*,int));
-char const *makedirtemp P((int));
-char const *getcaller P((void));
-int addlock P((struct hshentry*,int));
-int addsymbol P((char const*,char const*,int));
-int checkaccesslist P((void));
-int chnamemod P((FILE**,char const*,char const*,int,mode_t,time_t));
-int donerewrite P((int,time_t));
-int dorewrite P((int,int));
-int expandline P((RILE*,FILE*,struct hshentry const*,int,FILE*,int));
-int findlock P((int,struct hshentry**));
-int setmtime P((char const*,time_t));
-void ORCSclose P((void));
-void ORCSerror P((void));
-void copystring P((void));
-void dirtempunlink P((void));
-void enterstring P((void));
-void finishedit P((struct hshentry const*,FILE*,int));
-void keepdirtemp P((char const*));
-void openfcopy P((FILE*));
-void snapshotedit P((FILE*));
-void xpandstring P((struct hshentry const*));
-#if has_NFS || bad_unlink
- int un_link P((char const*));
-#else
-# define un_link(s) unlink(s)
-#endif
-#if large_memory
- void edit_string P((void));
-# define editstring(delta) edit_string()
-#else
- void editstring P((struct hshentry const*));
-#endif
-
-/* rcsfcmp */
-int rcsfcmp P((RILE*,struct stat const*,char const*,struct hshentry const*));
-
-/* rcsfnms */
-#define bufautobegin(b) clear_buf(b)
-#define clear_buf(b) (VOID ((b)->string = 0, (b)->size = 0))
-extern FILE *workstdout;
-extern char *workname;
-extern char const *RCSname;
-extern char const *suffixes;
-extern int fdlock;
-extern struct stat RCSstat;
-RILE *rcsreadopen P((struct buf*,struct stat*,int));
-char *bufenlarge P((struct buf*,char const**));
-char const *basefilename P((char const*));
-char const *getfullRCSname P((void));
-char const *getfullCVSname P((void));
-char const *maketemp P((int));
-char const *rcssuffix P((char const*));
-int pairnames P((int,char**,RILE*(*)P((struct buf*,struct stat*,int)),int,int));
-struct cbuf bufremember P((struct buf*,size_t));
-void bufalloc P((struct buf*,size_t));
-void bufautoend P((struct buf*));
-void bufrealloc P((struct buf*,size_t));
-void bufscat P((struct buf*,char const*));
-void bufscpy P((struct buf*,char const*));
-void tempunlink P((void));
-
-/* rcsgen */
-extern int interactiveflag;
-extern struct buf curlogbuf;
-char const *buildrevision P((struct hshentries const*,struct hshentry*,FILE*,int));
-int getcstdin P((void));
-int putdtext P((struct hshentry const*,char const*,FILE*,int));
-int ttystdin P((void));
-int yesorno P((int,char const*,...)) printf_string(2,3);
-struct cbuf cleanlogmsg P((char*,size_t));
-struct cbuf getsstdin P((char const*,char const*,char const*,struct buf*));
-void putdesc P((int,char*));
-void putdftext P((struct hshentry const*,RILE*,FILE*,int));
-
-/* rcskeep */
-extern int prevkeys;
-extern struct buf prevauthor, prevdate, prevname, prevrev, prevstate;
-int getoldkeys P((RILE*));
-
-/* rcskeys */
-extern char const *Keyword[];
-extern enum markers LocalIdMode;
-enum markers trymatch P((char const*));
-void setRCSLocalId(char const *);
-void setIncExc(char const *);
-
-/* rcslex */
-extern FILE *foutptr;
-extern FILE *frewrite;
-extern RILE *finptr;
-extern char const *NextString;
-extern enum tokens nexttok;
-extern int hshenter;
-extern int nerror;
-extern int nextc;
-extern int quietflag;
-extern long rcsline;
-char const *getid P((void));
-void efaterror P((char const*)) exiting;
-void enfaterror P((int,char const*)) exiting;
-void fatcleanup P((int)) exiting;
-void faterror P((char const*,...)) printf_string_exiting(1,2);
-void fatserror P((char const*,...)) printf_string_exiting(1,2);
-void rcsfaterror P((char const*,...)) printf_string_exiting(1,2);
-void Ieof P((void)) exiting;
-void Ierror P((void)) exiting;
-void Oerror P((void)) exiting;
-char *checkid P((char*,int));
-char *checksym P((char*,int));
-int eoflex P((void));
-int getkeyopt P((char const*));
-int getlex P((enum tokens));
-struct cbuf getphrases P((char const*));
-struct cbuf savestring P((struct buf*));
-struct hshentry *getnum P((void));
-void Ifclose P((RILE*));
-void Izclose P((RILE**));
-void Lexinit P((void));
-void Ofclose P((FILE*));
-void Orewind P((FILE*));
-void Ozclose P((FILE**));
-void aflush P((FILE*));
-void afputc P((int,FILE*));
-void aprintf P((FILE*,char const*,...)) printf_string(2,3);
-void aputs P((char const*,FILE*));
-void checksid P((char*));
-void checkssym P((char*));
-void diagnose P((char const*,...)) printf_string(1,2);
-void eerror P((char const*));
-void eflush P((void));
-void enerror P((int,char const*));
-void error P((char const*,...)) printf_string(1,2);
-void fvfprintf P((FILE*,char const*,va_list));
-void getkey P((char const*));
-void getkeystring P((char const*));
-void nextlex P((void));
-void oflush P((void));
-void printstring P((void));
-void readstring P((void));
-void redefined P((int));
-void rcserror P((char const*,...)) printf_string(1,2);
-void rcswarn P((char const*,...)) printf_string(1,2);
-void testIerror P((FILE*));
-void testOerror P((FILE*));
-void warn P((char const*,...)) printf_string(1,2);
-void warnignore P((void));
-void workerror P((char const*,...)) printf_string(1,2);
-void workwarn P((char const*,...)) printf_string(1,2);
-#if has_madvise && has_mmap && large_memory
- void advise_access P((RILE*,int));
-# define if_advise_access(p,f,advice) if (p) advise_access(f,advice)
-#else
-# define advise_access(f,advice)
-# define if_advise_access(p,f,advice)
-#endif
-#if large_memory && maps_memory
- RILE *I_open P((char const*,struct stat*));
-# define Iopen(f,m,s) I_open(f,s)
-#else
- RILE *Iopen P((char const*,char const*,struct stat*));
-#endif
-#if !large_memory
- void testIeof P((FILE*));
- void Irewind P((RILE*));
-#endif
-
-/* rcsmap */
-extern enum tokens const ctab[];
-
-/* rcsrev */
-char *partialno P((struct buf*,char const*,int));
-char const *namedrev P((char const*,struct hshentry*));
-char const *tiprev P((void));
-int cmpdate P((char const*,char const*));
-int cmpnum P((char const*,char const*));
-int cmpnumfld P((char const*,char const*,int));
-int compartial P((char const*,char const*,int));
-int expandsym P((char const*,struct buf*));
-int fexpandsym P((char const*,struct buf*,RILE*));
-struct hshentry *genrevs P((char const*,char const*,char const*,char const*,struct hshentries**));
-int countnumflds P((char const*));
-void getbranchno P((char const*,struct buf*));
-
-/* rcssyn */
-/* These expand modes must agree with Expand_names[] in rcssyn.c. */
-#define KEYVAL_EXPAND 0 /* -kkv `$Keyword: value $' */
-#define KEYVALLOCK_EXPAND 1 /* -kkvl `$Keyword: value locker $' */
-#define KEY_EXPAND 2 /* -kk `$Keyword$' */
-#define VAL_EXPAND 3 /* -kv `value' */
-#define OLD_EXPAND 4 /* -ko use old string, omitting expansion */
-#define BINARY_EXPAND 5 /* -kb like -ko, but use binary mode I/O */
-#define MIN_UNEXPAND OLD_EXPAND /* min value for no logical expansion */
-#define MIN_UNCHANGED_EXPAND (OPEN_O_BINARY ? BINARY_EXPAND : OLD_EXPAND)
- /* min value guaranteed to yield an identical file */
-struct diffcmd {
- long
- line1, /* number of first line */
- nlines, /* number of lines affected */
- adprev, /* previous 'a' line1+1 or 'd' line1 */
- dafter; /* sum of previous 'd' line1 and previous 'd' nlines */
-};
-extern char const * Dbranch;
-extern struct access * AccessList;
-extern struct assoc * Symbols;
-extern struct cbuf Comment;
-extern struct cbuf Ignored;
-extern struct rcslock *Locks;
-extern struct hshentry * Head;
-extern int Expand;
-extern int StrictLocks;
-extern int TotalDeltas;
-extern char const *const expand_names[];
-extern char const
- Kaccess[], Kauthor[], Kbranch[], Kcomment[],
- Kdate[], Kdesc[], Kexpand[], Khead[], Klocks[], Klog[],
- Knext[], Kstate[], Kstrict[], Ksymbols[], Ktext[];
-void unexpected_EOF P((void)) exiting;
-int getdiffcmd P((RILE*,int,FILE*,struct diffcmd*));
-int str2expmode P((char const*));
-void getadmin P((void));
-void getdesc P((int));
-void gettree P((void));
-void ignorephrases P((char const*));
-void initdiffcmd P((struct diffcmd*));
-void putadmin P((void));
-void putstring P((FILE*,int,struct cbuf,int));
-void puttree P((struct hshentry const*,FILE*));
-
-/* rcstime */
-#define zonelenmax 9 /* maxiumum length of time zone string, e.g. "+12:34:56" */
-char const *date2str P((char const[datesize],char[datesize + zonelenmax]));
-time_t date2time P((char const[datesize]));
-void str2date P((char const*,char[datesize]));
-void time2date P((time_t,char[datesize]));
-void zone_set P((char const*));
-
-/* rcsutil */
-extern int RCSversion;
-FILE *fopenSafer P((char const*,char const*));
-char *cgetenv P((char const*));
-char *fstr_save P((char const*));
-char *str_save P((char const*));
-char const *getusername P((int));
-int fdSafer P((int));
-int getRCSINIT P((int,char**,char***));
-int run P((int,char const*,...));
-int runv P((int,char const*,char const**));
-malloc_type fremember P((malloc_type));
-malloc_type ftestalloc P((size_t));
-malloc_type testalloc P((size_t));
-malloc_type testrealloc P((malloc_type,size_t));
-#define ftalloc(T) ftnalloc(T,1)
-#define talloc(T) tnalloc(T,1)
-#if RCS_lint
- extern malloc_type lintalloc;
-# define ftnalloc(T,n) (lintalloc = ftestalloc(sizeof(T)*(n)), (T*)0)
-# define tnalloc(T,n) (lintalloc = testalloc(sizeof(T)*(n)), (T*)0)
-# define trealloc(T,p,n) (lintalloc = testrealloc((malloc_type)0, sizeof(T)*(n)), p)
-# define tfree(p)
-#else
-# define ftnalloc(T,n) ((T*) ftestalloc(sizeof(T)*(n)))
-# define tnalloc(T,n) ((T*) testalloc(sizeof(T)*(n)))
-# define trealloc(T,p,n) ((T*) testrealloc((malloc_type)(p), sizeof(T)*(n)))
-# define tfree(p) free((malloc_type)(p))
-#endif
-time_t now P((void));
-void awrite P((char const*,size_t,FILE*));
-void fastcopy P((RILE*,FILE*));
-void ffree P((void));
-void ffree1 P((char const*));
-void setRCSversion P((char const*));
-#if has_signal
- void catchints P((void));
- void ignoreints P((void));
- void restoreints P((void));
-#else
-# define catchints()
-# define ignoreints()
-# define restoreints()
-#endif
-#if has_mmap && large_memory
-# if has_NFS && mmap_signal
- void catchmmapints P((void));
- void readAccessFilenameBuffer P((char const*,unsigned char const*));
-# else
-# define catchmmapints()
-# endif
-#endif
-#if has_getuid
- uid_t ruid P((void));
-# define myself(u) ((u) == ruid())
-#else
-# define myself(u) true
-#endif
-#if has_setuid
- uid_t euid P((void));
- void nosetid P((void));
- void seteid P((void));
- void setrid P((void));
-#else
-# define nosetid()
-# define seteid()
-# define setrid()
-#endif
-
-/* version */
-extern char const RCS_version_string[];
diff --git a/gnu/usr.bin/rcs/lib/rcsedit.c b/gnu/usr.bin/rcs/lib/rcsedit.c
deleted file mode 100644
index dc9dd30..0000000
--- a/gnu/usr.bin/rcs/lib/rcsedit.c
+++ /dev/null
@@ -1,1958 +0,0 @@
-/* RCS stream editor */
-
-/******************************************************************************
- * edits the input file according to a
- * script from stdin, generated by diff -n
- * performs keyword expansion
- ******************************************************************************
- */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.19 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.18 1995/06/01 16:23:43 eggert
- * (dirtpname): No longer external.
- * (do_link): Simplify logic.
- * (finisheditline, finishedit): Replace Iseek/Itell with what they stand for.
- * (fopen_update_truncate): Replace `#if' with `if'.
- * (keyreplace, makedirtemp): dirlen(x) -> basefilename(x)-x.
- *
- * (edit_string): Fix bug: if !large_memory, a bogus trailing `@' was output
- * at the end of incomplete lines.
- *
- * (keyreplace): Do not assume that seeking backwards
- * at the start of a file will fail; on some systems it succeeds.
- * Convert C- and Pascal-style comment starts to ` *' in comment leader.
- *
- * (rcswriteopen): Use fdSafer to get safer file descriptor.
- * Open RCS file with FOPEN_RB.
- *
- * (chnamemod): Work around bad_NFS_rename bug; don't ignore un_link result.
- * Fall back on chmod if fchmod fails, since it might be ENOSYS.
- *
- * (aflush): Move to rcslex.c.
- *
- * Revision 5.17 1994/03/20 04:52:58 eggert
- * Normally calculate the $Log prefix from context, not from RCS file.
- * Move setmtime here from rcsutil.c. Add ORCSerror. Remove lint.
- *
- * Revision 5.16 1993/11/03 17:42:27 eggert
- * Add -z. Add Name keyword. If bad_unlink, ignore errno when unlink fails.
- * Escape white space, $, and \ in keyword string file names.
- * Don't output 2 spaces between date and time after Log.
- *
- * Revision 5.15 1992/07/28 16:12:44 eggert
- * Some hosts have readlink but not ELOOP. Avoid `unsigned'.
- * Preserve dates more systematically. Statement macro names now end in _.
- *
- * Revision 5.14 1992/02/17 23:02:24 eggert
- * Add -T support.
- *
- * Revision 5.13 1992/01/24 18:44:19 eggert
- * Add support for bad_chmod_close, bad_creat0.
- *
- * Revision 5.12 1992/01/06 02:42:34 eggert
- * Add setmode parameter to chnamemod. addsymbol now reports changes.
- * while (E) ; -> while (E) continue;
- *
- * Revision 5.11 1991/11/03 01:11:44 eggert
- * Move the warning about link breaking to where they're actually being broken.
- *
- * Revision 5.10 1991/10/07 17:32:46 eggert
- * Support piece tables even if !has_mmap. Fix rare NFS bugs.
- *
- * Revision 5.9 1991/09/17 19:07:40 eggert
- * SGI readlink() yields ENXIO, not EINVAL, for nonlinks.
- *
- * Revision 5.8 1991/08/19 03:13:55 eggert
- * Add piece tables, NFS bug workarounds. Catch odd filenames. Tune.
- *
- * Revision 5.7 1991/04/21 11:58:21 eggert
- * Fix errno bugs. Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.6 1991/02/25 07:12:40 eggert
- * Fix setuid bug. Support new link behavior. Work around broken "w+" fopen.
- *
- * Revision 5.5 1990/12/30 05:07:35 eggert
- * Fix report of busy RCS files when !defined(O_CREAT) | !defined(O_EXCL).
- *
- * Revision 5.4 1990/11/01 05:03:40 eggert
- * Permit arbitrary data in comment leaders.
- *
- * Revision 5.3 1990/09/11 02:41:13 eggert
- * Tune expandline().
- *
- * Revision 5.2 1990/09/04 08:02:21 eggert
- * Count RCS lines better. Improve incomplete line handling.
- *
- * Revision 5.1 1990/08/29 07:13:56 eggert
- * Add -kkvl.
- * Fix bug when getting revisions to files ending in incomplete lines.
- * Fix bug in comment leader expansion.
- *
- * Revision 5.0 1990/08/22 08:12:47 eggert
- * Don't require final newline.
- * Don't append "checked in with -k by " to logs,
- * so that checking in a program with -k doesn't change it.
- * Don't generate trailing white space for empty comment leader.
- * Remove compile-time limits; use malloc instead. Add -k, -V.
- * Permit dates past 1999/12/31. Make lock and temp files faster and safer.
- * Ansify and Posixate. Check diff's output.
- *
- * Revision 4.8 89/05/01 15:12:35 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.7 88/11/08 13:54:14 narten
- * misplaced semicolon caused infinite loop
- *
- * Revision 4.6 88/08/09 19:12:45 eggert
- * Shrink stdio code size; allow cc -R.
- *
- * Revision 4.5 87/12/18 11:38:46 narten
- * Changes from the 43. version. Don't know the significance of the
- * first change involving "rewind". Also, additional "lint" cleanup.
- * (Guy Harris)
- *
- * Revision 4.4 87/10/18 10:32:21 narten
- * Updating version numbers. Changes relative to version 1.1 actually
- * relative to 4.1
- *
- * Revision 1.4 87/09/24 13:59:29 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.3 87/09/15 16:39:39 shepler
- * added an initializatin of the variables editline and linecorr
- * this will be done each time a file is processed.
- * (there was an obscure bug where if co was used to retrieve multiple files
- * it would dump)
- * fix attributed to Roy Morris @FileNet Corp ...!felix!roy
- *
- * Revision 1.2 87/03/27 14:22:17 jenkins
- * Port to suns
- *
- * Revision 4.1 83/05/12 13:10:30 wft
- * Added new markers Id and RCSfile; added locker to Header and Id.
- * Overhauled expandline completely() (problem with $01234567890123456789@).
- * Moved trymatch() and marker table to rcskeys.c.
- *
- * Revision 3.7 83/05/12 13:04:39 wft
- * Added retry to expandline to resume after failed match which ended in $.
- * Fixed truncation problem for $19chars followed by@@.
- * Log no longer expands full path of RCS file.
- *
- * Revision 3.6 83/05/11 16:06:30 wft
- * added retry to expandline to resume after failed match which ended in $.
- * Fixed truncation problem for $19chars followed by@@.
- *
- * Revision 3.5 82/12/04 13:20:56 wft
- * Added expansion of keyword Locker.
- *
- * Revision 3.4 82/12/03 12:26:54 wft
- * Added line number correction in case editing does not start at the
- * beginning of the file.
- * Changed keyword expansion to always print a space before closing KDELIM;
- * Expansion for Header shortened.
- *
- * Revision 3.3 82/11/14 14:49:30 wft
- * removed Suffix from keyword expansion. Replaced fclose with ffclose.
- * keyreplace() gets log message from delta, not from curlogmsg.
- * fixed expression overflow in while(c=putc(GETC....
- * checked nil printing.
- *
- * Revision 3.2 82/10/18 21:13:39 wft
- * I added checks for write errors during the co process, and renamed
- * expandstring() to xpandstring().
- *
- * Revision 3.1 82/10/13 15:52:55 wft
- * changed type of result of getc() from char to int.
- * made keyword expansion loop in expandline() portable to machines
- * without sign-extension.
- */
-
-
-#include "rcsbase.h"
-
-libId(editId, "$FreeBSD$")
-
-static void editEndsPrematurely P((void)) exiting;
-static void editLineNumberOverflow P((void)) exiting;
-static void escape_string P((FILE*,char const*));
-static void keyreplace P((enum markers,struct hshentry const*,int,RILE*,FILE*,int));
-
-FILE *fcopy; /* result file descriptor */
-char const *resultname; /* result pathname */
-int locker_expansion; /* should the locker name be appended to Id val? */
-#if !large_memory
- static RILE *fedit; /* edit file descriptor */
- static char const *editname; /* edit pathname */
-#endif
-static long editline; /* edit line counter; #lines before cursor */
-static long linecorr; /* #adds - #deletes in each edit run. */
- /*used to correct editline in case file is not rewound after */
- /* applying one delta */
-
-/* indexes into dirtpname */
-#define lockdirtp_index 0
-#define newRCSdirtp_index bad_creat0
-#define newworkdirtp_index (newRCSdirtp_index+1)
-#define DIRTEMPNAMES (newworkdirtp_index + 1)
-
-enum maker {notmade, real, effective};
-static struct buf dirtpname[DIRTEMPNAMES]; /* unlink these when done */
-static enum maker volatile dirtpmaker[DIRTEMPNAMES]; /* if these are set */
-#define lockname (dirtpname[lockdirtp_index].string)
-#define newRCSname (dirtpname[newRCSdirtp_index].string)
-
-
-#if has_NFS || bad_unlink
- int
-un_link(s)
- char const *s;
-/*
- * Remove S, even if it is unwritable.
- * Ignore unlink() ENOENT failures; NFS generates bogus ones.
- */
-{
-# if bad_unlink
- if (unlink(s) == 0)
- return 0;
- else {
- int e = errno;
- /*
- * Forge ahead even if errno == ENOENT; some completely
- * brain-damaged hosts (e.g. PCTCP 2.2) yield ENOENT
- * even for existing unwritable files.
- */
- if (chmod(s, S_IWUSR) != 0) {
- errno = e;
- return -1;
- }
- }
-# endif
-# if has_NFS
- return unlink(s)==0 || errno==ENOENT ? 0 : -1;
-# else
- return unlink(s);
-# endif
-}
-#endif
-
-#if !has_rename
-# if !has_NFS
-# define do_link(s,t) link(s,t)
-# else
- static int do_link P((char const*,char const*));
- static int
-do_link(s, t)
- char const *s, *t;
-/* Link S to T, ignoring bogus EEXIST problems due to NFS failures. */
-{
- int r = link(s, t);
-
- if (r != 0 && errno == EEXIST) {
- struct stat sb, tb;
- if (
- stat(s, &sb) == 0 &&
- stat(t, &tb) == 0 &&
- same_file(sb, tb, 0)
- )
- r = 0;
- errno = EEXIST;
- }
- return r;
-}
-# endif
-#endif
-
-
- static void
-editEndsPrematurely()
-{
- fatserror("edit script ends prematurely");
-}
-
- static void
-editLineNumberOverflow()
-{
- fatserror("edit script refers to line past end of file");
-}
-
-
-#if large_memory
-
-#if has_memmove
-# define movelines(s1, s2, n) VOID memmove(s1, s2, (n)*sizeof(Iptr_type))
-#else
- static void movelines P((Iptr_type*,Iptr_type const*,long));
- static void
-movelines(s1, s2, n)
- register Iptr_type *s1;
- register Iptr_type const *s2;
- register long n;
-{
- if (s1 < s2)
- do {
- *s1++ = *s2++;
- } while (--n);
- else {
- s1 += n;
- s2 += n;
- do {
- *--s1 = *--s2;
- } while (--n);
- }
-}
-#endif
-
-static void deletelines P((long,long));
-static void finisheditline P((RILE*,FILE*,Iptr_type,struct hshentry const*));
-static void insertline P((long,Iptr_type));
-static void snapshotline P((FILE*,Iptr_type));
-
-/*
- * `line' contains pointers to the lines in the currently `edited' file.
- * It is a 0-origin array that represents linelim-gapsize lines.
- * line[0 .. gap-1] and line[gap+gapsize .. linelim-1] hold pointers to lines.
- * line[gap .. gap+gapsize-1] contains garbage.
- *
- * Any @s in lines are duplicated.
- * Lines are terminated by \n, or (for a last partial line only) by single @.
- */
-static Iptr_type *line;
-static size_t gap, gapsize, linelim;
-
- static void
-insertline(n, l)
- long n;
- Iptr_type l;
-/* Before line N, insert line L. N is 0-origin. */
-{
- if (linelim-gapsize < n)
- editLineNumberOverflow();
- if (!gapsize)
- line =
- !linelim ?
- tnalloc(Iptr_type, linelim = gapsize = 1024)
- : (
- gap = gapsize = linelim,
- trealloc(Iptr_type, line, linelim <<= 1)
- );
- if (n < gap)
- movelines(line+n+gapsize, line+n, gap-n);
- else if (gap < n)
- movelines(line+gap, line+gap+gapsize, n-gap);
-
- line[n] = l;
- gap = n + 1;
- gapsize--;
-}
-
- static void
-deletelines(n, nlines)
- long n, nlines;
-/* Delete lines N through N+NLINES-1. N is 0-origin. */
-{
- long l = n + nlines;
- if (linelim-gapsize < l || l < n)
- editLineNumberOverflow();
- if (l < gap)
- movelines(line+l+gapsize, line+l, gap-l);
- else if (gap < n)
- movelines(line+gap, line+gap+gapsize, n-gap);
-
- gap = n;
- gapsize += nlines;
-}
-
- static void
-snapshotline(f, l)
- register FILE *f;
- register Iptr_type l;
-{
- register int c;
- do {
- if ((c = *l++) == SDELIM && *l++ != SDELIM)
- return;
- aputc_(c, f)
- } while (c != '\n');
-}
-
- void
-snapshotedit(f)
- FILE *f;
-/* Copy the current state of the edits to F. */
-{
- register Iptr_type *p, *lim, *l=line;
- for (p=l, lim=l+gap; p<lim; )
- snapshotline(f, *p++);
- for (p+=gapsize, lim=l+linelim; p<lim; )
- snapshotline(f, *p++);
-}
-
- static void
-finisheditline(fin, fout, l, delta)
- RILE *fin;
- FILE *fout;
- Iptr_type l;
- struct hshentry const *delta;
-{
- fin->ptr = l;
- if (expandline(fin, fout, delta, true, (FILE*)0, true) < 0)
- faterror("finisheditline internal error");
-}
-
- void
-finishedit(delta, outfile, done)
- struct hshentry const *delta;
- FILE *outfile;
- int done;
-/*
- * Doing expansion if DELTA is set, output the state of the edits to OUTFILE.
- * But do nothing unless DONE is set (which means we are on the last pass).
- */
-{
- if (done) {
- openfcopy(outfile);
- outfile = fcopy;
- if (!delta)
- snapshotedit(outfile);
- else {
- register Iptr_type *p, *lim, *l = line;
- register RILE *fin = finptr;
- Iptr_type here = fin->ptr;
- for (p=l, lim=l+gap; p<lim; )
- finisheditline(fin, outfile, *p++, delta);
- for (p+=gapsize, lim=l+linelim; p<lim; )
- finisheditline(fin, outfile, *p++, delta);
- fin->ptr = here;
- }
- }
-}
-
-/* Open a temporary NAME for output, truncating any previous contents. */
-# define fopen_update_truncate(name) fopenSafer(name, FOPEN_W_WORK)
-#else /* !large_memory */
- static FILE * fopen_update_truncate P((char const*));
- static FILE *
-fopen_update_truncate(name)
- char const *name;
-{
- if (bad_fopen_wplus && un_link(name) != 0)
- efaterror(name);
- return fopenSafer(name, FOPEN_WPLUS_WORK);
-}
-#endif
-
-
- void
-openfcopy(f)
- FILE *f;
-{
- if (!(fcopy = f)) {
- if (!resultname)
- resultname = maketemp(2);
- if (!(fcopy = fopen_update_truncate(resultname)))
- efaterror(resultname);
- }
-}
-
-
-#if !large_memory
-
- static void swapeditfiles P((FILE*));
- static void
-swapeditfiles(outfile)
- FILE *outfile;
-/* Function: swaps resultname and editname, assigns fedit=fcopy,
- * and rewinds fedit for reading. Set fcopy to outfile if nonnull;
- * otherwise, set fcopy to be resultname opened for reading and writing.
- */
-{
- char const *tmpptr;
-
- editline = 0; linecorr = 0;
- Orewind(fcopy);
- fedit = fcopy;
- tmpptr=editname; editname=resultname; resultname=tmpptr;
- openfcopy(outfile);
-}
-
- void
-snapshotedit(f)
- FILE *f;
-/* Copy the current state of the edits to F. */
-{
- finishedit((struct hshentry *)0, (FILE*)0, false);
- fastcopy(fedit, f);
- Irewind(fedit);
-}
-
- void
-finishedit(delta, outfile, done)
- struct hshentry const *delta;
- FILE *outfile;
- int done;
-/* copy the rest of the edit file and close it (if it exists).
- * if delta, perform keyword substitution at the same time.
- * If DONE is set, we are finishing the last pass.
- */
-{
- register RILE *fe;
- register FILE *fc;
-
- fe = fedit;
- if (fe) {
- fc = fcopy;
- if (delta) {
- while (1 < expandline(fe,fc,delta,false,(FILE*)0,true))
- ;
- } else {
- fastcopy(fe,fc);
- }
- Ifclose(fe);
- }
- if (!done)
- swapeditfiles(outfile);
-}
-#endif
-
-
-
-#if large_memory
-# define copylines(upto,delta) (editline = (upto))
-#else
- static void copylines P((long,struct hshentry const*));
- static void
-copylines(upto, delta)
- register long upto;
- struct hshentry const *delta;
-/*
- * Copy input lines editline+1..upto from fedit to fcopy.
- * If delta, keyword expansion is done simultaneously.
- * editline is updated. Rewinds a file only if necessary.
- */
-{
- register int c;
- declarecache;
- register FILE *fc;
- register RILE *fe;
-
- if (upto < editline) {
- /* swap files */
- finishedit((struct hshentry *)0, (FILE*)0, false);
- /* assumes edit only during last pass, from the beginning*/
- }
- fe = fedit;
- fc = fcopy;
- if (editline < upto)
- if (delta)
- do {
- if (expandline(fe,fc,delta,false,(FILE*)0,true) <= 1)
- editLineNumberOverflow();
- } while (++editline < upto);
- else {
- setupcache(fe); cache(fe);
- do {
- do {
- cachegeteof_(c, editLineNumberOverflow();)
- aputc_(c, fc)
- } while (c != '\n');
- } while (++editline < upto);
- uncache(fe);
- }
-}
-#endif
-
-
-
- void
-xpandstring(delta)
- struct hshentry const *delta;
-/* Function: Reads a string terminated by SDELIM from finptr and writes it
- * to fcopy. Double SDELIM is replaced with single SDELIM.
- * Keyword expansion is performed with data from delta.
- * If foutptr is nonnull, the string is also copied unchanged to foutptr.
- */
-{
- while (1 < expandline(finptr,fcopy,delta,true,foutptr,true))
- continue;
-}
-
-
- void
-copystring()
-/* Function: copies a string terminated with a single SDELIM from finptr to
- * fcopy, replacing all double SDELIM with a single SDELIM.
- * If foutptr is nonnull, the string also copied unchanged to foutptr.
- * editline is incremented by the number of lines copied.
- * Assumption: next character read is first string character.
- */
-{ register c;
- declarecache;
- register FILE *frew, *fcop;
- register int amidline;
- register RILE *fin;
-
- fin = finptr;
- setupcache(fin); cache(fin);
- frew = foutptr;
- fcop = fcopy;
- amidline = false;
- for (;;) {
- GETC_(frew,c)
- switch (c) {
- case '\n':
- ++editline;
- ++rcsline;
- amidline = false;
- break;
- case SDELIM:
- GETC_(frew,c)
- if (c != SDELIM) {
- /* end of string */
- nextc = c;
- editline += amidline;
- uncache(fin);
- return;
- }
- /* fall into */
- default:
- amidline = true;
- break;
- }
- aputc_(c,fcop)
- }
-}
-
-
- void
-enterstring()
-/* Like copystring, except the string is put into the edit data structure. */
-{
-#if !large_memory
- editname = 0;
- fedit = 0;
- editline = linecorr = 0;
- resultname = maketemp(1);
- if (!(fcopy = fopen_update_truncate(resultname)))
- efaterror(resultname);
- copystring();
-#else
- register int c;
- declarecache;
- register FILE *frew;
- register long e, oe;
- register int amidline, oamidline;
- register Iptr_type optr;
- register RILE *fin;
-
- e = 0;
- gap = 0;
- gapsize = linelim;
- fin = finptr;
- setupcache(fin); cache(fin);
- advise_access(fin, MADV_NORMAL);
- frew = foutptr;
- amidline = false;
- for (;;) {
- optr = cacheptr();
- GETC_(frew,c)
- oamidline = amidline;
- oe = e;
- switch (c) {
- case '\n':
- ++e;
- ++rcsline;
- amidline = false;
- break;
- case SDELIM:
- GETC_(frew,c)
- if (c != SDELIM) {
- /* end of string */
- nextc = c;
- editline = e + amidline;
- linecorr = 0;
- uncache(fin);
- return;
- }
- /* fall into */
- default:
- amidline = true;
- break;
- }
- if (!oamidline)
- insertline(oe, optr);
- }
-#endif
-}
-
-
-
-
- void
-#if large_memory
-edit_string()
-#else
- editstring(delta)
- struct hshentry const *delta;
-#endif
-/*
- * Read an edit script from finptr and applies it to the edit file.
-#if !large_memory
- * The result is written to fcopy.
- * If delta, keyword expansion is performed simultaneously.
- * If running out of lines in fedit, fedit and fcopy are swapped.
- * editname is the name of the file that goes with fedit.
-#endif
- * If foutptr is set, the edit script is also copied verbatim to foutptr.
- * Assumes that all these files are open.
- * resultname is the name of the file that goes with fcopy.
- * Assumes the next input character from finptr is the first character of
- * the edit script. Resets nextc on exit.
- */
-{
- int ed; /* editor command */
- register int c;
- declarecache;
- register FILE *frew;
-# if !large_memory
- register FILE *f;
- long line_lim = LONG_MAX;
- register RILE *fe;
-# endif
- register long i;
- register RILE *fin;
-# if large_memory
- register long j;
-# endif
- struct diffcmd dc;
-
- editline += linecorr; linecorr=0; /*correct line number*/
- frew = foutptr;
- fin = finptr;
- setupcache(fin);
- initdiffcmd(&dc);
- while (0 <= (ed = getdiffcmd(fin,true,frew,&dc)))
-#if !large_memory
- if (line_lim <= dc.line1)
- editLineNumberOverflow();
- else
-#endif
- if (!ed) {
- copylines(dc.line1-1, delta);
- /* skip over unwanted lines */
- i = dc.nlines;
- linecorr -= i;
- editline += i;
-# if large_memory
- deletelines(editline+linecorr, i);
-# else
- fe = fedit;
- do {
- /*skip next line*/
- do {
- Igeteof_(fe, c, { if (i!=1) editLineNumberOverflow(); line_lim = dc.dafter; break; } )
- } while (c != '\n');
- } while (--i);
-# endif
- } else {
- /* Copy lines without deleting any. */
- copylines(dc.line1, delta);
- i = dc.nlines;
-# if large_memory
- j = editline+linecorr;
-# endif
- linecorr += i;
-#if !large_memory
- f = fcopy;
- if (delta)
- do {
- switch (expandline(fin,f,delta,true,frew,true)){
- case 0: case 1:
- if (i==1)
- return;
- /* fall into */
- case -1:
- editEndsPrematurely();
- }
- } while (--i);
- else
-#endif
- {
- cache(fin);
- do {
-# if large_memory
- insertline(j++, cacheptr());
-# endif
- for (;;) {
- GETC_(frew, c)
- if (c==SDELIM) {
- GETC_(frew, c)
- if (c!=SDELIM) {
- if (--i)
- editEndsPrematurely();
- nextc = c;
- uncache(fin);
- return;
- }
- }
-# if !large_memory
- aputc_(c, f)
-# endif
- if (c == '\n')
- break;
- }
- ++rcsline;
- } while (--i);
- uncache(fin);
- }
- }
-}
-
-
-
-/* The rest is for keyword expansion */
-
-
-
- int
-expandline(infile, outfile, delta, delimstuffed, frewfile, dolog)
- RILE *infile;
- FILE *outfile, *frewfile;
- struct hshentry const *delta;
- int delimstuffed, dolog;
-/*
- * Read a line from INFILE and write it to OUTFILE.
- * Do keyword expansion with data from DELTA.
- * If DELIMSTUFFED is true, double SDELIM is replaced with single SDELIM.
- * If FREWFILE is set, copy the line unchanged to FREWFILE.
- * DELIMSTUFFED must be true if FREWFILE is set.
- * Append revision history to log only if DOLOG is set.
- * Yields -1 if no data is copied, 0 if an incomplete line is copied,
- * 2 if a complete line is copied; adds 1 to yield if expansion occurred.
- */
-{
- register c;
- declarecache;
- register FILE *out, *frew;
- register char * tp;
- register int e, ds, r;
- char const *tlim;
- static struct buf keyval;
- enum markers matchresult;
-
- setupcache(infile); cache(infile);
- out = outfile;
- frew = frewfile;
- ds = delimstuffed;
- bufalloc(&keyval, keylength+3);
- e = 0;
- r = -1;
-
- for (;;) {
- if (ds)
- GETC_(frew, c)
- else
- cachegeteof_(c, goto uncache_exit;)
- for (;;) {
- switch (c) {
- case SDELIM:
- if (ds) {
- GETC_(frew, c)
- if (c != SDELIM) {
- /* end of string */
- nextc=c;
- goto uncache_exit;
- }
- }
- /* fall into */
- default:
- aputc_(c,out)
- r = 0;
- break;
-
- case '\n':
- rcsline += ds;
- aputc_(c,out)
- r = 2;
- goto uncache_exit;
-
- case KDELIM:
- r = 0;
- /* check for keyword */
- /* first, copy a long enough string into keystring */
- tp = keyval.string;
- *tp++ = KDELIM;
- for (;;) {
- if (ds)
- GETC_(frew, c)
- else
- cachegeteof_(c, goto keystring_eof;)
- if (tp <= &keyval.string[keylength])
- switch (ctab[c]) {
- case LETTER: case Letter:
- *tp++ = c;
- continue;
- default:
- break;
- }
- break;
- }
- *tp++ = c; *tp = '\0';
- matchresult = trymatch(keyval.string+1);
- if (matchresult==Nomatch) {
- tp[-1] = 0;
- aputs(keyval.string, out);
- continue; /* last c handled properly */
- }
-
- /* Now we have a keyword terminated with a K/VDELIM */
- if (c==VDELIM) {
- /* try to find closing KDELIM, and replace value */
- tlim = keyval.string + keyval.size;
- for (;;) {
- if (ds)
- GETC_(frew, c)
- else
- cachegeteof_(c, goto keystring_eof;)
- if (c=='\n' || c==KDELIM)
- break;
- *tp++ =c;
- if (tlim <= tp)
- tp = bufenlarge(&keyval, &tlim);
- if (c==SDELIM && ds) { /*skip next SDELIM */
- GETC_(frew, c)
- if (c != SDELIM) {
- /* end of string before closing KDELIM or newline */
- nextc = c;
- goto keystring_eof;
- }
- }
- }
- if (c!=KDELIM) {
- /* couldn't find closing KDELIM -- give up */
- *tp = 0;
- aputs(keyval.string, out);
- continue; /* last c handled properly */
- }
- }
- /* now put out the new keyword value */
- uncache(infile);
- keyreplace(matchresult, delta, ds, infile, out, dolog);
- cache(infile);
- e = 1;
- break;
- }
- break;
- }
- }
-
- keystring_eof:
- *tp = 0;
- aputs(keyval.string, out);
- uncache_exit:
- uncache(infile);
- return r + e;
-}
-
-
- static void
-escape_string(out, s)
- register FILE *out;
- register char const *s;
-/* Output to OUT the string S, escaping chars that would break `ci -k'. */
-{
- register char c;
- for (;;)
- switch ((c = *s++)) {
- case 0: return;
- case '\t': aputs("\\t", out); break;
- case '\n': aputs("\\n", out); break;
- case ' ': aputs("\\040", out); break;
- case KDELIM: aputs("\\044", out); break;
- case '\\': if (VERSION(5)<=RCSversion) {aputs("\\\\", out); break;}
- /* fall into */
- default: aputc_(c, out) break;
- }
-}
-
-char const ciklog[ciklogsize] = "checked in with -k by ";
-
- static void
-keyreplace(marker, delta, delimstuffed, infile, out, dolog)
- enum markers marker;
- register struct hshentry const *delta;
- int delimstuffed;
- RILE *infile;
- register FILE *out;
- int dolog;
-/* function: outputs the keyword value(s) corresponding to marker.
- * Attributes are derived from delta.
- */
-{
- register char const *sp, *cp, *date;
- register int c;
- register size_t cs, cw, ls;
- char const *sp1;
- char datebuf[datesize + zonelenmax];
- int RCSv;
- int exp;
-
- sp = Keyword[(int)marker];
- exp = Expand;
- date = delta->date;
- RCSv = RCSversion;
-
- if (exp != VAL_EXPAND)
- aprintf(out, "%c%s", KDELIM, sp);
- if (exp != KEY_EXPAND) {
-
- if (exp != VAL_EXPAND)
- aprintf(out, "%c%c", VDELIM,
- marker==Log && RCSv<VERSION(5) ? '\t' : ' '
- );
-
- switch (marker) {
- case Author:
- aputs(delta->author, out);
- break;
- case Date:
- aputs(date2str(date,datebuf), out);
- break;
- case Id:
- case LocalId:
- case Header:
- case CVSHeader:
- if (marker == Id || RCSv < VERSION(4) ||
- (marker == LocalId && LocalIdMode == Id))
- escape_string(out, basefilename(RCSname));
- else if (marker == CVSHeader ||
- (marker == LocalId && LocalIdMode == CVSHeader))
- escape_string(out, getfullCVSname());
- else
- escape_string(out, getfullRCSname());
- aprintf(out, " %s %s %s %s",
- delta->num,
- date2str(date, datebuf),
- delta->author,
- RCSv==VERSION(3) && delta->lockedby ? "Locked"
- : delta->state
- );
- if (delta->lockedby)
- if (VERSION(5) <= RCSv) {
- if (locker_expansion || exp==KEYVALLOCK_EXPAND)
- aprintf(out, " %s", delta->lockedby);
- } else if (RCSv == VERSION(4))
- aprintf(out, " Locker: %s", delta->lockedby);
- break;
- case Locker:
- if (delta->lockedby)
- if (
- locker_expansion
- || exp == KEYVALLOCK_EXPAND
- || RCSv <= VERSION(4)
- )
- aputs(delta->lockedby, out);
- break;
- case Log:
- case RCSfile:
- escape_string(out, basefilename(RCSname));
- break;
- case Name:
- if (delta->name)
- aputs(delta->name, out);
- break;
- case Revision:
- aputs(delta->num, out);
- break;
- case Source:
- escape_string(out, getfullRCSname());
- break;
- case State:
- aputs(delta->state, out);
- break;
- default:
- break;
- }
- if (exp != VAL_EXPAND)
- afputc(' ', out);
- }
- if (exp != VAL_EXPAND)
- afputc(KDELIM, out);
-
- if (marker == Log && dolog) {
- struct buf leader;
-
- sp = delta->log.string;
- ls = delta->log.size;
- if (sizeof(ciklog)-1<=ls && !memcmp(sp,ciklog,sizeof(ciklog)-1))
- return;
- bufautobegin(&leader);
- if (RCSversion < VERSION(5)) {
- cp = Comment.string;
- cs = Comment.size;
- } else {
- int kdelim_found = 0;
- Ioffset_type chars_read = Itell(infile);
- declarecache;
- setupcache(infile); cache(infile);
-
- c = 0; /* Pacify `gcc -Wall'. */
-
- /*
- * Back up to the start of the current input line,
- * setting CS to the number of characters before `$Log'.
- */
- cs = 0;
- for (;;) {
- if (!--chars_read)
- goto done_backing_up;
- cacheunget_(infile, c)
- if (c == '\n')
- break;
- if (c == SDELIM && delimstuffed) {
- if (!--chars_read)
- break;
- cacheunget_(infile, c)
- if (c != SDELIM) {
- cacheget_(c)
- break;
- }
- }
- cs += kdelim_found;
- kdelim_found |= c==KDELIM;
- }
- cacheget_(c)
- done_backing_up:;
-
- /* Copy characters before `$Log' into LEADER. */
- bufalloc(&leader, cs);
- cp = leader.string;
- for (cw = 0; cw < cs; cw++) {
- leader.string[cw] = c;
- if (c == SDELIM && delimstuffed)
- cacheget_(c)
- cacheget_(c)
- }
-
- /* Convert traditional C or Pascal leader to ` *'. */
- for (cw = 0; cw < cs; cw++)
- if (ctab[(unsigned char) cp[cw]] != SPACE)
- break;
- if (
- cw+1 < cs
- && cp[cw+1] == '*'
- && (cp[cw] == '/' || cp[cw] == '(')
- ) {
- size_t i = cw+1;
- for (;;)
- if (++i == cs) {
- warn(
- "`%c* $Log' is obsolescent; use ` * $Log'.",
- cp[cw]
- );
- leader.string[cw] = ' ';
- break;
- } else if (ctab[(unsigned char) cp[i]] != SPACE)
- break;
- }
-
- /* Skip `$Log ... $' string. */
- do {
- cacheget_(c)
- } while (c != KDELIM);
- uncache(infile);
- }
- afputc('\n', out);
- awrite(cp, cs, out);
- sp1 = date2str(date, datebuf);
- if (VERSION(5) <= RCSv) {
- aprintf(out, "Revision %s %s %s",
- delta->num, sp1, delta->author
- );
- } else {
- /* oddity: 2 spaces between date and time, not 1 as usual */
- sp1 = strchr(sp1, ' ');
- aprintf(out, "Revision %s %.*s %s %s",
- delta->num, (int)(sp1-datebuf), datebuf, sp1,
- delta->author
- );
- }
- /* Do not include state: it may change and is not updated. */
- cw = cs;
- if (VERSION(5) <= RCSv)
- for (; cw && (cp[cw-1]==' ' || cp[cw-1]=='\t'); --cw)
- continue;
- for (;;) {
- afputc('\n', out);
- awrite(cp, cw, out);
- if (!ls)
- break;
- --ls;
- c = *sp++;
- if (c != '\n') {
- awrite(cp+cw, cs-cw, out);
- do {
- afputc(c,out);
- if (!ls)
- break;
- --ls;
- c = *sp++;
- } while (c != '\n');
- }
- }
- bufautoend(&leader);
- }
-}
-
-#if has_readlink
- static int resolve_symlink P((struct buf*));
- static int
-resolve_symlink(L)
- struct buf *L;
-/*
- * If L is a symbolic link, resolve it to the name that it points to.
- * If unsuccessful, set errno and yield -1.
- * If it points to an existing file, yield 1.
- * Otherwise, set errno=ENOENT and yield 0.
- */
-{
- char *b, a[SIZEABLE_PATH];
- int e;
- size_t s;
- ssize_t r;
- struct buf bigbuf;
- int linkcount = MAXSYMLINKS;
-
- b = a;
- s = sizeof(a);
- bufautobegin(&bigbuf);
- while ((r = readlink(L->string,b,s)) != -1)
- if (r == s) {
- bufalloc(&bigbuf, s<<1);
- b = bigbuf.string;
- s = bigbuf.size;
- } else if (!linkcount--) {
-# ifndef ELOOP
- /*
- * Some pedantic Posix 1003.1-1990 hosts have readlink
- * but not ELOOP. Approximate ELOOP with EMLINK.
- */
-# define ELOOP EMLINK
-# endif
- errno = ELOOP;
- return -1;
- } else {
- /* Splice symbolic link into L. */
- b[r] = '\0';
- L->string[
- ROOTPATH(b) ? 0 : basefilename(L->string) - L->string
- ] = '\0';
- bufscat(L, b);
- }
- e = errno;
- bufautoend(&bigbuf);
- errno = e;
- switch (e) {
- case readlink_isreg_errno: return 1;
- case ENOENT: return 0;
- default: return -1;
- }
-}
-#endif
-
- RILE *
-rcswriteopen(RCSbuf, status, mustread)
- struct buf *RCSbuf;
- struct stat *status;
- int mustread;
-/*
- * Create the lock file corresponding to RCSBUF.
- * Then try to open RCSBUF for reading and yield its RILE* descriptor.
- * Put its status into *STATUS too.
- * MUSTREAD is true if the file must already exist, too.
- * If all goes well, discard any previously acquired locks,
- * and set fdlock to the file descriptor of the RCS lockfile.
- */
-{
- register char *tp;
- register char const *sp, *RCSpath, *x;
- RILE *f;
- size_t l;
- int e, exists, fdesc, fdescSafer, r, waslocked;
- struct buf *dirt;
- struct stat statbuf;
-
- waslocked = 0 <= fdlock;
- exists =
-# if has_readlink
- resolve_symlink(RCSbuf);
-# else
- stat(RCSbuf->string, &statbuf) == 0 ? 1
- : errno==ENOENT ? 0 : -1;
-# endif
- if (exists < (mustread|waslocked))
- /*
- * There's an unusual problem with the RCS file;
- * or the RCS file doesn't exist,
- * and we must read or we already have a lock elsewhere.
- */
- return 0;
-
- RCSpath = RCSbuf->string;
- sp = basefilename(RCSpath);
- l = sp - RCSpath;
- dirt = &dirtpname[waslocked];
- bufscpy(dirt, RCSpath);
- tp = dirt->string + l;
- x = rcssuffix(RCSpath);
-# if has_readlink
- if (!x) {
- error("symbolic link to non RCS file `%s'", RCSpath);
- errno = EINVAL;
- return 0;
- }
-# endif
- if (*sp == *x) {
- error("RCS pathname `%s' incompatible with suffix `%s'", sp, x);
- errno = EINVAL;
- return 0;
- }
- /* Create a lock filename that is a function of the RCS filename. */
- if (*x) {
- /*
- * The suffix is nonempty.
- * The lock filename is the first char of of the suffix,
- * followed by the RCS filename with last char removed. E.g.:
- * foo,v RCS filename with suffix ,v
- * ,foo, lock filename
- */
- *tp++ = *x;
- while (*sp)
- *tp++ = *sp++;
- *--tp = 0;
- } else {
- /*
- * The suffix is empty.
- * The lock filename is the RCS filename
- * with last char replaced by '_'.
- */
- while ((*tp++ = *sp++))
- continue;
- tp -= 2;
- if (*tp == '_') {
- error("RCS pathname `%s' ends with `%c'", RCSpath, *tp);
- errno = EINVAL;
- return 0;
- }
- *tp = '_';
- }
-
- sp = dirt->string;
-
- f = 0;
-
- /*
- * good news:
- * open(f, O_CREAT|O_EXCL|O_TRUNC|..., OPEN_CREAT_READONLY)
- * is atomic according to Posix 1003.1-1990.
- * bad news:
- * NFS ignores O_EXCL and doesn't comply with Posix 1003.1-1990.
- * good news:
- * (O_TRUNC,OPEN_CREAT_READONLY) normally guarantees atomicity
- * even with NFS.
- * bad news:
- * If you're root, (O_TRUNC,OPEN_CREAT_READONLY) doesn't
- * guarantee atomicity.
- * good news:
- * Root-over-the-wire NFS access is rare for security reasons.
- * This bug has never been reported in practice with RCS.
- * So we don't worry about this bug.
- *
- * An even rarer NFS bug can occur when clients retry requests.
- * This can happen in the usual case of NFS over UDP.
- * Suppose client A releases a lock by renaming ",f," to "f,v" at
- * about the same time that client B obtains a lock by creating ",f,",
- * and suppose A's first rename request is delayed, so A reissues it.
- * The sequence of events might be:
- * A sends rename(",f,", "f,v")
- * B sends create(",f,")
- * A sends retry of rename(",f,", "f,v")
- * server receives, does, and acknowledges A's first rename()
- * A receives acknowledgment, and its RCS program exits
- * server receives, does, and acknowledges B's create()
- * server receives, does, and acknowledges A's retry of rename()
- * This not only wrongly deletes B's lock, it removes the RCS file!
- * Most NFS implementations have idempotency caches that usually prevent
- * this scenario, but such caches are finite and can be overrun.
- * This problem afflicts not only RCS, which uses open() and rename()
- * to get and release locks; it also afflicts the traditional
- * Unix method of using link() and unlink() to get and release locks,
- * and the less traditional method of using mkdir() and rmdir().
- * There is no easy workaround.
- * Any new method based on lockf() seemingly would be incompatible with
- * the old methods; besides, lockf() is notoriously buggy under NFS.
- * Since this problem afflicts scads of Unix programs, but is so rare
- * that nobody seems to be worried about it, we won't worry either.
- */
-# if !open_can_creat
-# define create(f) creat(f, OPEN_CREAT_READONLY)
-# else
-# define create(f) open(f, OPEN_O_BINARY|OPEN_O_LOCK|OPEN_O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, OPEN_CREAT_READONLY)
-# endif
-
- catchints();
- ignoreints();
-
- /*
- * Create a lock file for an RCS file. This should be atomic, i.e.
- * if two processes try it simultaneously, at most one should succeed.
- */
- seteid();
- fdesc = create(sp);
- fdescSafer = fdSafer(fdesc); /* Do it now; setrid might use stderr. */
- e = errno;
- setrid();
-
- if (0 <= fdesc)
- dirtpmaker[0] = effective;
-
- if (fdescSafer < 0) {
- if (e == EACCES && stat(sp,&statbuf) == 0)
- /* The RCS file is busy. */
- e = EEXIST;
- } else {
- e = ENOENT;
- if (exists) {
- f = Iopen(RCSpath, FOPEN_RB, status);
- e = errno;
- if (f && waslocked) {
- /* Discard the previous lock in favor of this one. */
- ORCSclose();
- seteid();
- r = un_link(lockname);
- e = errno;
- setrid();
- if (r != 0)
- enfaterror(e, lockname);
- bufscpy(&dirtpname[lockdirtp_index], sp);
- }
- }
- fdlock = fdescSafer;
- }
-
- restoreints();
-
- errno = e;
- return f;
-}
-
- void
-keepdirtemp(name)
- char const *name;
-/* Do not unlink name, either because it's not there any more,
- * or because it has already been unlinked.
- */
-{
- register int i;
- for (i=DIRTEMPNAMES; 0<=--i; )
- if (dirtpname[i].string == name) {
- dirtpmaker[i] = notmade;
- return;
- }
- faterror("keepdirtemp");
-}
-
- char const *
-makedirtemp(isworkfile)
- int isworkfile;
-/*
- * Create a unique pathname and store it into dirtpname.
- * Because of storage in tpnames, dirtempunlink() can unlink the file later.
- * Return a pointer to the pathname created.
- * If ISWORKFILE is 1, put it into the working file's directory;
- * if 0, put the unique file in RCSfile's directory.
- */
-{
- register char *tp, *np;
- register size_t dl;
- register struct buf *bn;
- register char const *name = isworkfile ? workname : RCSname;
-# if has_mktemp
- int fd;
-# endif
-
- dl = basefilename(name) - name;
- bn = &dirtpname[newRCSdirtp_index + isworkfile];
- bufalloc(bn,
-# if has_mktemp
- dl + 9
-# else
- strlen(name) + 3
-# endif
- );
- bufscpy(bn, name);
- np = tp = bn->string;
- tp += dl;
- *tp++ = '_';
- *tp++ = '0'+isworkfile;
- catchints();
-# if has_mktemp
- VOID strcpy(tp, "XXXXXX");
- fd = mkstemp(np);
- if (fd < 0 || !*np)
- faterror("can't make temporary pathname `%.*s_%cXXXXXX'",
- (int)dl, name, '0'+isworkfile
- );
- close(fd);
-# else
- /*
- * Posix 1003.1-1990 has no reliable way
- * to create a unique file in a named directory.
- * We fudge here. If the filename is abcde,
- * the temp filename is _Ncde where N is a digit.
- */
- name += dl;
- if (*name) name++;
- if (*name) name++;
- VOID strcpy(tp, name);
-# endif
- dirtpmaker[newRCSdirtp_index + isworkfile] = real;
- return np;
-}
-
- void
-dirtempunlink()
-/* Clean up makedirtemp() files. May be invoked by signal handler. */
-{
- register int i;
- enum maker m;
-
- for (i = DIRTEMPNAMES; 0 <= --i; )
- if ((m = dirtpmaker[i]) != notmade) {
- if (m == effective)
- seteid();
- VOID un_link(dirtpname[i].string);
- if (m == effective)
- setrid();
- dirtpmaker[i] = notmade;
- }
-}
-
-
- int
-#if has_prototypes
-chnamemod(
- FILE **fromp, char const *from, char const *to,
- int set_mode, mode_t mode, time_t mtime
-)
- /* The `#if has_prototypes' is needed because mode_t might promote to int. */
-#else
- chnamemod(fromp, from, to, set_mode, mode, mtime)
- FILE **fromp; char const *from,*to;
- int set_mode; mode_t mode; time_t mtime;
-#endif
-/*
- * Rename a file (with stream pointer *FROMP) from FROM to TO.
- * FROM already exists.
- * If 0 < SET_MODE, change the mode to MODE, before renaming if possible.
- * If MTIME is not -1, change its mtime to MTIME before renaming.
- * Close and clear *FROMP before renaming it.
- * Unlink TO if it already exists.
- * Return -1 on error (setting errno), 0 otherwise.
- */
-{
- mode_t mode_while_renaming = mode;
- int fchmod_set_mode = 0;
-
-# if bad_a_rename || bad_NFS_rename
- struct stat st;
- if (bad_NFS_rename || (bad_a_rename && set_mode <= 0)) {
- if (fstat(fileno(*fromp), &st) != 0)
- return -1;
- if (bad_a_rename && set_mode <= 0)
- mode = st.st_mode;
- }
-# endif
-
-# if bad_a_rename
- /*
- * There's a short window of inconsistency
- * during which the lock file is writable.
- */
- mode_while_renaming = mode|S_IWUSR;
- if (mode != mode_while_renaming)
- set_mode = 1;
-# endif
-
-# if has_fchmod
- if (0<set_mode && fchmod(fileno(*fromp),mode_while_renaming) == 0)
- fchmod_set_mode = set_mode;
-# endif
- /* If bad_chmod_close, we must close before chmod. */
- Ozclose(fromp);
- if (fchmod_set_mode<set_mode && chmod(from, mode_while_renaming) != 0)
- return -1;
-
- if (setmtime(from, mtime) != 0)
- return -1;
-
-# if !has_rename || bad_b_rename
- /*
- * There's a short window of inconsistency
- * during which TO does not exist.
- */
- if (un_link(to) != 0 && errno != ENOENT)
- return -1;
-# endif
-
-# if has_rename
- if (rename(from,to) != 0 && !(has_NFS && errno==ENOENT))
- return -1;
-# else
- if (do_link(from,to) != 0 || un_link(from) != 0)
- return -1;
-# endif
-
-# if bad_NFS_rename
- {
- /*
- * Check whether the rename falsely reported success.
- * A race condition can occur between the rename and the stat.
- */
- struct stat tostat;
- if (stat(to, &tostat) != 0)
- return -1;
- if (! same_file(st, tostat, 0)) {
- errno = EIO;
- return -1;
- }
- }
-# endif
-
-# if bad_a_rename
- if (0 < set_mode && chmod(to, mode) != 0)
- return -1;
-# endif
-
- return 0;
-}
-
- int
-setmtime(file, mtime)
- char const *file;
- time_t mtime;
-/* Set FILE's last modified time to MTIME, but do nothing if MTIME is -1. */
-{
- static struct utimbuf amtime; /* static so unused fields are zero */
- if (mtime == -1)
- return 0;
- amtime.actime = now();
- amtime.modtime = mtime;
- return utime(file, &amtime);
-}
-
-
-
- int
-findlock(delete, target)
- int delete;
- struct hshentry **target;
-/*
- * Find the first lock held by caller and return a pointer
- * to the locked delta; also removes the lock if DELETE.
- * If one lock, put it into *TARGET.
- * Return 0 for no locks, 1 for one, 2 for two or more.
- */
-{
- register struct rcslock *next, **trail, **found;
-
- found = 0;
- for (trail = &Locks; (next = *trail); trail = &next->nextlock)
- if (strcmp(getcaller(), next->login) == 0) {
- if (found) {
- rcserror("multiple revisions locked by %s; please specify one", getcaller());
- return 2;
- }
- found = trail;
- }
- if (!found)
- return 0;
- next = *found;
- *target = next->delta;
- if (delete) {
- next->delta->lockedby = 0;
- *found = next->nextlock;
- }
- return 1;
-}
-
- int
-addlock(delta, verbose)
- struct hshentry * delta;
- int verbose;
-/*
- * Add a lock held by caller to DELTA and yield 1 if successful.
- * Print an error message if verbose and yield -1 if no lock is added because
- * DELTA is locked by somebody other than caller.
- * Return 0 if the caller already holds the lock.
- */
-{
- register struct rcslock *next;
-
- for (next = Locks; next; next = next->nextlock)
- if (cmpnum(delta->num, next->delta->num) == 0)
- if (strcmp(getcaller(), next->login) == 0)
- return 0;
- else {
- if (verbose)
- rcserror("Revision %s is already locked by %s.",
- delta->num, next->login
- );
- return -1;
- }
- next = ftalloc(struct rcslock);
- delta->lockedby = next->login = getcaller();
- next->delta = delta;
- next->nextlock = Locks;
- Locks = next;
- return 1;
-}
-
-
- int
-addsymbol(num, name, rebind)
- char const *num, *name;
- int rebind;
-/*
- * Associate with revision NUM the new symbolic NAME.
- * If NAME already exists and REBIND is set, associate NAME with NUM;
- * otherwise, print an error message and return false;
- * Return -1 if unsuccessful, 0 if no change, 1 if change.
- */
-{
- register struct assoc *next;
-
- for (next = Symbols; next; next = next->nextassoc)
- if (strcmp(name, next->symbol) == 0)
- if (strcmp(next->num,num) == 0)
- return 0;
- else if (rebind) {
- next->num = num;
- return 1;
- } else {
- rcserror("symbolic name %s already bound to %s",
- name, next->num
- );
- return -1;
- }
- next = ftalloc(struct assoc);
- next->symbol = name;
- next->num = num;
- next->nextassoc = Symbols;
- Symbols = next;
- return 1;
-}
-
-
-
- char const *
-getcaller()
-/* Get the caller's login name. */
-{
-# if has_setuid
- return getusername(euid()!=ruid());
-# else
- return getusername(false);
-# endif
-}
-
-
- int
-checkaccesslist()
-/*
- * Return true if caller is the superuser, the owner of the
- * file, the access list is empty, or caller is on the access list.
- * Otherwise, print an error message and return false.
- */
-{
- register struct access const *next;
-
- if (!AccessList || myself(RCSstat.st_uid) || strcmp(getcaller(),"root")==0)
- return true;
-
- next = AccessList;
- do {
- if (strcmp(getcaller(), next->login) == 0)
- return true;
- } while ((next = next->nextaccess));
-
- rcserror("user %s not on the access list", getcaller());
- return false;
-}
-
-
- int
-dorewrite(lockflag, changed)
- int lockflag, changed;
-/*
- * Do nothing if LOCKFLAG is zero.
- * Prepare to rewrite an RCS file if CHANGED is positive.
- * Stop rewriting if CHANGED is zero, because there won't be any changes.
- * Fail if CHANGED is negative.
- * Return 0 on success, -1 on failure.
- */
-{
- int r = 0, e;
-
- if (lockflag)
- if (changed) {
- if (changed < 0)
- return -1;
- putadmin();
- puttree(Head, frewrite);
- aprintf(frewrite, "\n\n%s%c", Kdesc, nextc);
- foutptr = frewrite;
- } else {
-# if bad_creat0
- int nr = !!frewrite, ne = 0;
-# endif
- ORCSclose();
- seteid();
- ignoreints();
-# if bad_creat0
- if (nr) {
- nr = un_link(newRCSname);
- ne = errno;
- keepdirtemp(newRCSname);
- }
-# endif
- r = un_link(lockname);
- e = errno;
- keepdirtemp(lockname);
- restoreints();
- setrid();
- if (r != 0)
- enerror(e, lockname);
-# if bad_creat0
- if (nr != 0) {
- enerror(ne, newRCSname);
- r = -1;
- }
-# endif
- }
- return r;
-}
-
- int
-donerewrite(changed, newRCStime)
- int changed;
- time_t newRCStime;
-/*
- * Finish rewriting an RCS file if CHANGED is nonzero.
- * Set its mode if CHANGED is positive.
- * Set its modification time to NEWRCSTIME unless it is -1.
- * Return 0 on success, -1 on failure.
- */
-{
- int r = 0, e = 0;
-# if bad_creat0
- int lr, le;
-# endif
-
- if (changed && !nerror) {
- if (finptr) {
- fastcopy(finptr, frewrite);
- Izclose(&finptr);
- }
- if (1 < RCSstat.st_nlink)
- rcswarn("breaking hard link");
- aflush(frewrite);
- seteid();
- ignoreints();
- r = chnamemod(
- &frewrite, newRCSname, RCSname, changed,
- RCSstat.st_mode & (mode_t)~(S_IWUSR|S_IWGRP|S_IWOTH),
- newRCStime
- );
- e = errno;
- keepdirtemp(newRCSname);
-# if bad_creat0
- lr = un_link(lockname);
- le = errno;
- keepdirtemp(lockname);
-# endif
- restoreints();
- setrid();
- if (r != 0) {
- enerror(e, RCSname);
- error("saved in %s", newRCSname);
- }
-# if bad_creat0
- if (lr != 0) {
- enerror(le, lockname);
- r = -1;
- }
-# endif
- }
- return r;
-}
-
- void
-ORCSclose()
-{
- if (0 <= fdlock) {
- if (close(fdlock) != 0)
- efaterror(lockname);
- fdlock = -1;
- }
- Ozclose(&frewrite);
-}
-
- void
-ORCSerror()
-/*
-* Like ORCSclose, except we are cleaning up after an interrupt or fatal error.
-* Do not report errors, since this may loop. This is needed only because
-* some brain-damaged hosts (e.g. OS/2) cannot unlink files that are open, and
-* some nearly-Posix hosts (e.g. NFS) work better if the files are closed first.
-* This isn't a completely reliable away to work around brain-damaged hosts,
-* because of the gap between actual file opening and setting frewrite etc.,
-* but it's better than nothing.
-*/
-{
- if (0 <= fdlock)
- VOID close(fdlock);
- if (frewrite)
- /* Avoid fclose, since stdio may not be reentrant. */
- VOID close(fileno(frewrite));
-}
diff --git a/gnu/usr.bin/rcs/lib/rcsfcmp.c b/gnu/usr.bin/rcs/lib/rcsfcmp.c
deleted file mode 100644
index ef05290..0000000
--- a/gnu/usr.bin/rcs/lib/rcsfcmp.c
+++ /dev/null
@@ -1,354 +0,0 @@
-/* Compare working files, ignoring RCS keyword strings. */
-
-/*****************************************************************************
- * rcsfcmp()
- * Testprogram: define FCMPTEST
- *****************************************************************************
- */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-
-
-
-
-/*
- * Revision 5.14 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.13 1995/06/01 16:23:43 eggert
- * (rcsfcmp): Add -kb support.
- *
- * Revision 5.12 1994/03/17 14:05:48 eggert
- * Normally calculate the $Log prefix from context, not from RCS file.
- * Calculate line numbers correctly even if the $Log prefix contains newlines.
- * Remove lint.
- *
- * Revision 5.11 1993/11/03 17:42:27 eggert
- * Fix yet another off-by-one error when comparing Log string expansions.
- *
- * Revision 5.10 1992/07/28 16:12:44 eggert
- * Statement macro names now end in _.
- *
- * Revision 5.9 1991/10/07 17:32:46 eggert
- * Count log lines correctly.
- *
- * Revision 5.8 1991/08/19 03:13:55 eggert
- * Tune.
- *
- * Revision 5.7 1991/04/21 11:58:22 eggert
- * Fix errno bug. Add MS-DOS support.
- *
- * Revision 5.6 1991/02/28 19:18:47 eggert
- * Open work file at most once.
- *
- * Revision 5.5 1990/11/27 09:26:05 eggert
- * Fix comment leader bug.
- *
- * Revision 5.4 1990/11/01 05:03:42 eggert
- * Permit arbitrary data in logs and comment leaders.
- *
- * Revision 5.3 1990/09/11 02:41:15 eggert
- * Don't ignore differences inside keyword strings if -ko is set.
- *
- * Revision 5.1 1990/08/29 07:13:58 eggert
- * Clean old log messages too.
- *
- * Revision 5.0 1990/08/22 08:12:49 eggert
- * Don't append "checked in with -k by " log to logs,
- * so that checking in a program with -k doesn't change it.
- * Ansify and Posixate. Remove lint.
- *
- * Revision 4.5 89/05/01 15:12:42 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.4 88/08/09 19:12:50 eggert
- * Shrink stdio code size.
- *
- * Revision 4.3 87/12/18 11:40:02 narten
- * lint cleanups (Guy Harris)
- *
- * Revision 4.2 87/10/18 10:33:06 narten
- * updting version number. Changes relative to 1.1 actually relative to
- * 4.1
- *
- * Revision 1.2 87/03/27 14:22:19 jenkins
- * Port to suns
- *
- * Revision 4.1 83/05/10 16:24:04 wft
- * Marker matching now uses trymatch(). Marker pattern is now
- * checked precisely.
- *
- * Revision 3.1 82/12/04 13:21:40 wft
- * Initial revision.
- *
- */
-
-/*
-#define FCMPTEST
-*/
-/* Testprogram; prints out whether two files are identical,
- * except for keywords
- */
-
-#include "rcsbase.h"
-
-libId(fcmpId, "$FreeBSD$")
-
- static int discardkeyval P((int,RILE*));
- static int
-discardkeyval(c, f)
- register int c;
- register RILE *f;
-{
- for (;;)
- switch (c) {
- case KDELIM:
- case '\n':
- return c;
- default:
- Igeteof_(f, c, return EOF;)
- break;
- }
-}
-
- int
-rcsfcmp(xfp, xstatp, uname, delta)
- register RILE *xfp;
- struct stat const *xstatp;
- char const *uname;
- struct hshentry const *delta;
-/* Compare the files xfp and uname. Return zero
- * if xfp has the same contents as uname and neither has keywords,
- * otherwise -1 if they are the same ignoring keyword values,
- * and 1 if they differ even ignoring
- * keyword values. For the LOG-keyword, rcsfcmp skips the log message
- * given by the parameter delta in xfp. Thus, rcsfcmp returns nonpositive
- * if xfp contains the same as uname, with the keywords expanded.
- * Implementation: character-by-character comparison until $ is found.
- * If a $ is found, read in the marker keywords; if they are real keywords
- * and identical, read in keyword value. If value is terminated properly,
- * disregard it and optionally skip log message; otherwise, compare value.
- */
-{
- register int xc, uc;
- char xkeyword[keylength+2];
- int eqkeyvals;
- register RILE *ufp;
- register int xeof, ueof;
- register char * tp;
- register char const *sp;
- register size_t leaderlen;
- int result;
- enum markers match1;
- struct stat ustat;
-
- if (!(ufp = Iopen(uname, FOPEN_R_WORK, &ustat))) {
- efaterror(uname);
- }
- xeof = ueof = false;
- if (MIN_UNEXPAND <= Expand) {
- if (!(result = xstatp->st_size!=ustat.st_size)) {
-# if large_memory && maps_memory
- result = !!memcmp(xfp->base,ufp->base,(size_t)xstatp->st_size);
-# else
- for (;;) {
- /* get the next characters */
- Igeteof_(xfp, xc, xeof=true;)
- Igeteof_(ufp, uc, ueof=true;)
- if (xeof | ueof)
- goto eof;
- if (xc != uc)
- goto return1;
- }
-# endif
- }
- } else {
- xc = 0;
- uc = 0; /* Keep lint happy. */
- leaderlen = 0;
- result = 0;
-
- for (;;) {
- if (xc != KDELIM) {
- /* get the next characters */
- Igeteof_(xfp, xc, xeof=true;)
- Igeteof_(ufp, uc, ueof=true;)
- if (xeof | ueof)
- goto eof;
- } else {
- /* try to get both keywords */
- tp = xkeyword;
- for (;;) {
- Igeteof_(xfp, xc, xeof=true;)
- Igeteof_(ufp, uc, ueof=true;)
- if (xeof | ueof)
- goto eof;
- if (xc != uc)
- break;
- switch (xc) {
- default:
- if (xkeyword+keylength <= tp)
- break;
- *tp++ = xc;
- continue;
- case '\n': case KDELIM: case VDELIM:
- break;
- }
- break;
- }
- if (
- (xc==KDELIM || xc==VDELIM) && (uc==KDELIM || uc==VDELIM) &&
- (*tp = xc, (match1 = trymatch(xkeyword)) != Nomatch)
- ) {
-#ifdef FCMPTEST
- VOID printf("found common keyword %s\n",xkeyword);
-#endif
- result = -1;
- for (;;) {
- if (xc != uc) {
- xc = discardkeyval(xc, xfp);
- uc = discardkeyval(uc, ufp);
- if ((xeof = xc==EOF) | (ueof = uc==EOF))
- goto eof;
- eqkeyvals = false;
- break;
- }
- switch (xc) {
- default:
- Igeteof_(xfp, xc, xeof=true;)
- Igeteof_(ufp, uc, ueof=true;)
- if (xeof | ueof)
- goto eof;
- continue;
-
- case '\n': case KDELIM:
- eqkeyvals = true;
- break;
- }
- break;
- }
- if (xc != uc)
- goto return1;
- if (xc==KDELIM) {
- /* Skip closing KDELIM. */
- Igeteof_(xfp, xc, xeof=true;)
- Igeteof_(ufp, uc, ueof=true;)
- if (xeof | ueof)
- goto eof;
- /* if the keyword is LOG, also skip the log message in xfp*/
- if (match1==Log) {
- /* first, compute the number of line feeds in log msg */
- int lncnt;
- size_t ls, ccnt;
- sp = delta->log.string;
- ls = delta->log.size;
- if (ls<sizeof(ciklog)-1 || memcmp(sp,ciklog,sizeof(ciklog)-1)) {
- /*
- * This log message was inserted. Skip its header.
- * The number of newlines to skip is
- * 1 + (C+1)*(1+L+1), where C is the number of newlines
- * in the comment leader, and L is the number of
- * newlines in the log string.
- */
- int c1 = 1;
- for (ccnt=Comment.size; ccnt--; )
- c1 += Comment.string[ccnt] == '\n';
- lncnt = 2*c1 + 1;
- while (ls--) if (*sp++=='\n') lncnt += c1;
- for (;;) {
- if (xc=='\n')
- if(--lncnt==0) break;
- Igeteof_(xfp, xc, goto returnresult;)
- }
- /* skip last comment leader */
- /* Can't just skip another line here, because there may be */
- /* additional characters on the line (after the Log....$) */
- ccnt = RCSversion<VERSION(5) ? Comment.size : leaderlen;
- do {
- Igeteof_(xfp, xc, goto returnresult;)
- /*
- * Read to the end of the comment leader or '\n',
- * whatever comes first, because the leader's
- * trailing white space was probably stripped.
- */
- } while (ccnt-- && (xc!='\n' || --c1));
- }
- }
- } else {
- /* both end in the same character, but not a KDELIM */
- /* must compare string values.*/
-#ifdef FCMPTEST
- VOID printf("non-terminated keywords %s, potentially different values\n",xkeyword);
-#endif
- if (!eqkeyvals)
- goto return1;
- }
- }
- }
- if (xc != uc)
- goto return1;
- if (xc == '\n')
- leaderlen = 0;
- else
- leaderlen++;
- }
- }
-
- eof:
- if (xeof==ueof)
- goto returnresult;
- return1:
- result = 1;
- returnresult:
- Ifclose(ufp);
- return result;
-}
-
-
-
-#ifdef FCMPTEST
-
-char const cmdid[] = "rcsfcmp";
-
-main(argc, argv)
-int argc; char *argv[];
-/* first argument: comment leader; 2nd: log message, 3rd: expanded file,
- * 4th: unexpanded file
- */
-{ struct hshentry delta;
-
- Comment.string = argv[1];
- Comment.size = strlen(argv[1]);
- delta.log.string = argv[2];
- delta.log.size = strlen(argv[2]);
- if (rcsfcmp(Iopen(argv[3], FOPEN_R_WORK, (struct stat*)0), argv[4], &delta))
- VOID printf("files are the same\n");
- else VOID printf("files are different\n");
-}
-#endif
diff --git a/gnu/usr.bin/rcs/lib/rcsfnms.c b/gnu/usr.bin/rcs/lib/rcsfnms.c
deleted file mode 100644
index 00caec5..0000000
--- a/gnu/usr.bin/rcs/lib/rcsfnms.c
+++ /dev/null
@@ -1,1132 +0,0 @@
-/* RCS filename and pathname handling */
-
-/****************************************************************************
- * creation and deletion of /tmp temporaries
- * pairing of RCS pathnames and working pathnames.
- * Testprogram: define PAIRTEST
- ****************************************************************************
- */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-
-
-
-/*
- * Revision 5.16 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.15 1995/06/01 16:23:43 eggert
- * (basefilename): Renamed from basename to avoid collisions.
- * (dirlen): Remove (for similar reasons).
- * (rcsreadopen): Open with FOPEN_RB.
- * (SLASHSLASH_is_SLASH): Default is 0.
- * (getcwd): Work around bad_wait_if_SIGCHLD_ignored bug.
- *
- * Revision 5.14 1994/03/17 14:05:48 eggert
- * Strip trailing SLASHes from TMPDIR; some systems need this. Remove lint.
- *
- * Revision 5.13 1993/11/03 17:42:27 eggert
- * Determine whether a file name is too long indirectly,
- * by examining inode numbers, instead of trying to use operating system
- * primitives like pathconf, which are not trustworthy in general.
- * File names may now hold white space or $.
- * Do not flatten ../X in pathnames; that may yield wrong answer for symlinks.
- * Add getabsname hook. Improve quality of diagnostics.
- *
- * Revision 5.12 1992/07/28 16:12:44 eggert
- * Add .sty. .pl now implies Perl, not Prolog. Fix fdlock initialization bug.
- * Check that $PWD is really ".". Be consistent about pathnames vs filenames.
- *
- * Revision 5.11 1992/02/17 23:02:25 eggert
- * `a/RCS/b/c' is now an RCS file with an empty extension, not just `a/b/RCS/c'.
- *
- * Revision 5.10 1992/01/24 18:44:19 eggert
- * Fix bug: Expand and Ignored weren't reinitialized.
- * Avoid `char const c=ch;' compiler bug.
- * Add support for bad_creat0.
- *
- * Revision 5.9 1992/01/06 02:42:34 eggert
- * Shorten long (>31 chars) name.
- * while (E) ; -> while (E) continue;
- *
- * Revision 5.8 1991/09/24 00:28:40 eggert
- * Don't export bindex().
- *
- * Revision 5.7 1991/08/19 03:13:55 eggert
- * Fix messages when rcswriteopen fails.
- * Look in $TMP and $TEMP if $TMPDIR isn't set. Tune.
- *
- * Revision 5.6 1991/04/21 11:58:23 eggert
- * Fix errno bugs. Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.5 1991/02/26 17:48:38 eggert
- * Fix setuid bug. Support new link behavior.
- * Define more portable getcwd().
- *
- * Revision 5.4 1990/11/01 05:03:43 eggert
- * Permit arbitrary data in comment leaders.
- *
- * Revision 5.3 1990/09/14 22:56:16 hammer
- * added more filename extensions and their comment leaders
- *
- * Revision 5.2 1990/09/04 08:02:23 eggert
- * Fix typo when !RCSSEP.
- *
- * Revision 5.1 1990/08/29 07:13:59 eggert
- * Work around buggy compilers with defective argument promotion.
- *
- * Revision 5.0 1990/08/22 08:12:50 eggert
- * Ignore signals when manipulating the semaphore file.
- * Modernize list of filename extensions.
- * Permit paths of arbitrary length. Beware filenames beginning with "-".
- * Remove compile-time limits; use malloc instead.
- * Permit dates past 1999/12/31. Make lock and temp files faster and safer.
- * Ansify and Posixate.
- * Don't use access(). Fix test for non-regular files. Tune.
- *
- * Revision 4.8 89/05/01 15:09:41 narten
- * changed getwd to not stat empty directories.
- *
- * Revision 4.7 88/08/09 19:12:53 eggert
- * Fix troff macro comment leader bug; add Prolog; allow cc -R; remove lint.
- *
- * Revision 4.6 87/12/18 11:40:23 narten
- * additional file types added from 4.3 BSD version, and SPARC assembler
- * comment character added. Also, more lint cleanups. (Guy Harris)
- *
- * Revision 4.5 87/10/18 10:34:16 narten
- * Updating version numbers. Changes relative to 1.1 actually relative
- * to verion 4.3
- *
- * Revision 1.3 87/03/27 14:22:21 jenkins
- * Port to suns
- *
- * Revision 1.2 85/06/26 07:34:28 svb
- * Comment leader '% ' for '*.tex' files added.
- *
- * Revision 4.3 83/12/15 12:26:48 wft
- * Added check for KDELIM in filenames to pairfilenames().
- *
- * Revision 4.2 83/12/02 22:47:45 wft
- * Added csh, red, and sl filename suffixes.
- *
- * Revision 4.1 83/05/11 16:23:39 wft
- * Added initialization of Dbranch to InitAdmin(). Canged pairfilenames():
- * 1. added copying of path from workfile to RCS file, if RCS file is omitted;
- * 2. added getting the file status of RCS and working files;
- * 3. added ignoring of directories.
- *
- * Revision 3.7 83/05/11 15:01:58 wft
- * Added comtable[] which pairs filename suffixes with comment leaders;
- * updated InitAdmin() accordingly.
- *
- * Revision 3.6 83/04/05 14:47:36 wft
- * fixed Suffix in InitAdmin().
- *
- * Revision 3.5 83/01/17 18:01:04 wft
- * Added getwd() and rename(); these can be removed by defining
- * V4_2BSD, since they are not needed in 4.2 bsd.
- * Changed sys/param.h to sys/types.h.
- *
- * Revision 3.4 82/12/08 21:55:20 wft
- * removed unused variable.
- *
- * Revision 3.3 82/11/28 20:31:37 wft
- * Changed mktempfile() to store the generated filenames.
- * Changed getfullRCSname() to store the file and pathname, and to
- * delete leading "../" and "./".
- *
- * Revision 3.2 82/11/12 14:29:40 wft
- * changed pairfilenames() to handle file.sfx,v; also deleted checkpathnosfx(),
- * checksuffix(), checkfullpath(). Semaphore name generation updated.
- * mktempfile() now checks for nil path; freefilename initialized properly.
- * Added Suffix .h to InitAdmin. Added testprogram PAIRTEST.
- * Moved rmsema, trysema, trydiraccess, getfullRCSname from rcsutil.c to here.
- *
- * Revision 3.1 82/10/18 14:51:28 wft
- * InitAdmin() now initializes StrictLocks=STRICT_LOCKING (def. in rcsbase.h).
- * renamed checkpath() to checkfullpath().
- */
-
-
-#include "rcsbase.h"
-
-libId(fnmsId, "$FreeBSD$")
-
-static char const *bindex P((char const*,int));
-static int fin2open P((char const*, size_t, char const*, size_t, char const*, size_t, RILE*(*)P((struct buf*,struct stat*,int)), int));
-static int finopen P((RILE*(*)P((struct buf*,struct stat*,int)), int));
-static int suffix_matches P((char const*,char const*));
-static size_t dir_useful_len P((char const*));
-static size_t suffixlen P((char const*));
-static void InitAdmin P((void));
-
-char const *RCSname;
-char *workname;
-int fdlock;
-FILE *workstdout;
-struct stat RCSstat;
-char const *suffixes;
-
-static char const rcsdir[] = "RCS";
-#define rcslen (sizeof(rcsdir)-1)
-
-static struct buf RCSbuf, RCSb;
-static int RCSerrno;
-
-
-/* Temp names to be unlinked when done, if they are not 0. */
-#define TEMPNAMES 5 /* must be at least DIRTEMPNAMES (see rcsedit.c) */
-static char *volatile tpnames[TEMPNAMES];
-
-
-struct compair {
- char const *suffix, *comlead;
-};
-
-/*
-* This table is present only for backwards compatibility.
-* Normally we ignore this table, and use the prefix of the `$Log' line instead.
-*/
-static struct compair const comtable[] = {
- { "a" , "-- " }, /* Ada */
- { "ada" , "-- " },
- { "adb" , "-- " },
- { "ads" , "-- " },
- { "asm" , ";; " }, /* assembler (MS-DOS) */
- { "bat" , ":: " }, /* batch (MS-DOS) */
- { "body", "-- " }, /* Ada */
- { "c" , " * " }, /* C */
- { "c++" , "// " }, /* C++ in all its infinite guises */
- { "cc" , "// " },
- { "cpp" , "// " },
- { "cxx" , "// " },
- { "cl" , ";;; "}, /* Common Lisp */
- { "cmd" , ":: " }, /* command (OS/2) */
- { "cmf" , "c " }, /* CM Fortran */
- { "cs" , " * " }, /* C* */
- { "el" , "; " }, /* Emacs Lisp */
- { "f" , "c " }, /* Fortran */
- { "for" , "c " },
- { "h" , " * " }, /* C-header */
- { "hpp" , "// " }, /* C++ header */
- { "hxx" , "// " },
- { "l" , " * " }, /* lex (NOTE: franzlisp disagrees) */
- { "lisp", ";;; "}, /* Lucid Lisp */
- { "lsp" , ";; " }, /* Microsoft Lisp */
- { "m" , "// " }, /* Objective C */
- { "mac" , ";; " }, /* macro (DEC-10, MS-DOS, PDP-11, VMS, etc) */
- { "me" , ".\\\" "}, /* troff -me */
- { "ml" , "; " }, /* mocklisp */
- { "mm" , ".\\\" "}, /* troff -mm */
- { "ms" , ".\\\" "}, /* troff -ms */
- { "p" , " * " }, /* Pascal */
- { "pas" , " * " },
- { "ps" , "% " }, /* PostScript */
- { "spec", "-- " }, /* Ada */
- { "sty" , "% " }, /* LaTeX style */
- { "tex" , "% " }, /* TeX */
- { "y" , " * " }, /* yacc */
- { 0 , "# " } /* default for unknown suffix; must be last */
-};
-
-#if has_mktemp
- static char const *tmp P((void));
- static char const *
-tmp()
-/* Yield the name of the tmp directory. */
-{
- static char const *s;
- if (!s
- && !(s = cgetenv("TMPDIR")) /* Unix tradition */
- && !(s = cgetenv("TMP")) /* DOS tradition */
- && !(s = cgetenv("TEMP")) /* another DOS tradition */
- )
- s = TMPDIR;
- return s;
-}
-#endif
-
- char const *
-maketemp(n)
- int n;
-/* Create a unique pathname using n and the process id and store it
- * into the nth slot in tpnames.
- * Because of storage in tpnames, tempunlink() can unlink the file later.
- * Return a pointer to the pathname created.
- */
-{
- char *p;
- char const *t = tpnames[n];
-# if has_mktemp
- int fd;
-# endif
-
- if (t)
- return t;
-
- catchints();
- {
-# if has_mktemp
- char const *tp = tmp();
- size_t tplen = dir_useful_len(tp);
- p = testalloc(tplen + 10);
- VOID sprintf(p, "%.*s%cT%cXXXXXX", (int)tplen, tp, SLASH, '0'+n);
- fd = mkstemp(p);
- if (fd < 0 || !*p)
- faterror("can't make temporary pathname `%.*s%cT%cXXXXXX'",
- (int)tplen, tp, SLASH, '0'+n
- );
- close(fd);
-# else
- static char tpnamebuf[TEMPNAMES][L_tmpnam];
- p = tpnamebuf[n];
- if (!tmpnam(p) || !*p)
-# ifdef P_tmpdir
- faterror("can't make temporary pathname `%s...'",P_tmpdir);
-# else
- faterror("can't make temporary pathname");
-# endif
-# endif
- }
-
- tpnames[n] = p;
- return p;
-}
-
- void
-tempunlink()
-/* Clean up maketemp() files. May be invoked by signal handler.
- */
-{
- register int i;
- register char *p;
-
- for (i = TEMPNAMES; 0 <= --i; )
- if ((p = tpnames[i])) {
- VOID unlink(p);
- /*
- * We would tfree(p) here,
- * but this might dump core if we're handing a signal.
- * We're about to exit anyway, so we won't bother.
- */
- tpnames[i] = 0;
- }
-}
-
-
- static char const *
-bindex(sp, c)
- register char const *sp;
- register int c;
-/* Function: Finds the last occurrence of character c in string sp
- * and returns a pointer to the character just beyond it. If the
- * character doesn't occur in the string, sp is returned.
- */
-{
- register char const *r;
- r = sp;
- while (*sp) {
- if (*sp++ == c) r=sp;
- }
- return r;
-}
-
-
-
- static int
-suffix_matches(suffix, pattern)
- register char const *suffix, *pattern;
-{
- register int c;
- if (!pattern)
- return true;
- for (;;)
- switch (*suffix++ - (c = *pattern++)) {
- case 0:
- if (!c)
- return true;
- break;
-
- case 'A'-'a':
- if (ctab[c] == Letter)
- break;
- /* fall into */
- default:
- return false;
- }
-}
-
-
- static void
-InitAdmin()
-/* function: initializes an admin node */
-{
- register char const *Suffix;
- register int i;
-
- Head=0; Dbranch=0; AccessList=0; Symbols=0; Locks=0;
- StrictLocks=STRICT_LOCKING;
-
- /* guess the comment leader from the suffix*/
- Suffix = bindex(workname, '.');
- if (Suffix==workname) Suffix= ""; /* empty suffix; will get default*/
- for (i=0; !suffix_matches(Suffix,comtable[i].suffix); i++)
- continue;
- Comment.string = comtable[i].comlead;
- Comment.size = strlen(comtable[i].comlead);
- Expand = KEYVAL_EXPAND;
- clear_buf(&Ignored);
- Lexinit(); /* note: if !finptr, reads nothing; only initializes */
-}
-
-
-
- void
-bufalloc(b, size)
- register struct buf *b;
- size_t size;
-/* Ensure *B is a name buffer of at least SIZE bytes.
- * *B's old contents can be freed; *B's new contents are undefined.
- */
-{
- if (b->size < size) {
- if (b->size)
- tfree(b->string);
- else
- b->size = sizeof(malloc_type);
- while (b->size < size)
- b->size <<= 1;
- b->string = tnalloc(char, b->size);
- }
-}
-
- void
-bufrealloc(b, size)
- register struct buf *b;
- size_t size;
-/* like bufalloc, except *B's old contents, if any, are preserved */
-{
- if (b->size < size) {
- if (!b->size)
- bufalloc(b, size);
- else {
- while ((b->size <<= 1) < size)
- continue;
- b->string = trealloc(char, b->string, b->size);
- }
- }
-}
-
- void
-bufautoend(b)
- struct buf *b;
-/* Free an auto buffer at block exit. */
-{
- if (b->size)
- tfree(b->string);
-}
-
- struct cbuf
-bufremember(b, s)
- struct buf *b;
- size_t s;
-/*
- * Free the buffer B with used size S.
- * Yield a cbuf with identical contents.
- * The cbuf will be reclaimed when this input file is finished.
- */
-{
- struct cbuf cb;
-
- if ((cb.size = s))
- cb.string = fremember(trealloc(char, b->string, s));
- else {
- bufautoend(b); /* not really auto */
- cb.string = "";
- }
- return cb;
-}
-
- char *
-bufenlarge(b, alim)
- register struct buf *b;
- char const **alim;
-/* Make *B larger. Set *ALIM to its new limit, and yield the relocated value
- * of its old limit.
- */
-{
- size_t s = b->size;
- bufrealloc(b, s + 1);
- *alim = b->string + b->size;
- return b->string + s;
-}
-
- void
-bufscat(b, s)
- struct buf *b;
- char const *s;
-/* Concatenate S to B's end. */
-{
- size_t blen = b->string ? strlen(b->string) : 0;
- bufrealloc(b, blen+strlen(s)+1);
- VOID strcpy(b->string+blen, s);
-}
-
- void
-bufscpy(b, s)
- struct buf *b;
- char const *s;
-/* Copy S into B. */
-{
- bufalloc(b, strlen(s)+1);
- VOID strcpy(b->string, s);
-}
-
-
- char const *
-basefilename(p)
- char const *p;
-/* Yield the address of the base filename of the pathname P. */
-{
- register char const *b = p, *q = p;
- for (;;)
- switch (*q++) {
- case SLASHes: b = q; break;
- case 0: return b;
- }
-}
-
-
- static size_t
-suffixlen(x)
- char const *x;
-/* Yield the length of X, an RCS pathname suffix. */
-{
- register char const *p;
-
- p = x;
- for (;;)
- switch (*p) {
- case 0: case SLASHes:
- return p - x;
-
- default:
- ++p;
- continue;
- }
-}
-
- char const *
-rcssuffix(name)
- char const *name;
-/* Yield the suffix of NAME if it is an RCS pathname, 0 otherwise. */
-{
- char const *x, *p, *nz;
- size_t nl, xl;
-
- nl = strlen(name);
- nz = name + nl;
- x = suffixes;
- do {
- if ((xl = suffixlen(x))) {
- if (xl <= nl && memcmp(p = nz-xl, x, xl) == 0)
- return p;
- } else
- for (p = name; p < nz - rcslen; p++)
- if (
- isSLASH(p[rcslen])
- && (p==name || isSLASH(p[-1]))
- && memcmp(p, rcsdir, rcslen) == 0
- )
- return nz;
- x += xl;
- } while (*x++);
- return 0;
-}
-
- /*ARGSUSED*/ RILE *
-rcsreadopen(RCSpath, status, mustread)
- struct buf *RCSpath;
- struct stat *status;
- int mustread;
-/* Open RCSPATH for reading and yield its FILE* descriptor.
- * If successful, set *STATUS to its status.
- * Pass this routine to pairnames() for read-only access to the file. */
-{
- return Iopen(RCSpath->string, FOPEN_RB, status);
-}
-
- static int
-finopen(rcsopen, mustread)
- RILE *(*rcsopen)P((struct buf*,struct stat*,int));
- int mustread;
-/*
- * Use RCSOPEN to open an RCS file; MUSTREAD is set if the file must be read.
- * Set finptr to the result and yield true if successful.
- * RCSb holds the file's name.
- * Set RCSbuf to the best RCS name found so far, and RCSerrno to its errno.
- * Yield true if successful or if an unusual failure.
- */
-{
- int interesting, preferold;
-
- /*
- * We prefer an old name to that of a nonexisting new RCS file,
- * unless we tried locking the old name and failed.
- */
- preferold = RCSbuf.string[0] && (mustread||0<=fdlock);
-
- finptr = (*rcsopen)(&RCSb, &RCSstat, mustread);
- interesting = finptr || errno!=ENOENT;
- if (interesting || !preferold) {
- /* Use the new name. */
- RCSerrno = errno;
- bufscpy(&RCSbuf, RCSb.string);
- }
- return interesting;
-}
-
- static int
-fin2open(d, dlen, base, baselen, x, xlen, rcsopen, mustread)
- char const *d, *base, *x;
- size_t dlen, baselen, xlen;
- RILE *(*rcsopen)P((struct buf*,struct stat*,int));
- int mustread;
-/*
- * D is a directory name with length DLEN (including trailing slash).
- * BASE is a filename with length BASELEN.
- * X is an RCS pathname suffix with length XLEN.
- * Use RCSOPEN to open an RCS file; MUSTREAD is set if the file must be read.
- * Yield true if successful.
- * Try dRCS/basex first; if that fails and x is nonempty, try dbasex.
- * Put these potential names in RCSb.
- * Set RCSbuf to the best RCS name found so far, and RCSerrno to its errno.
- * Yield true if successful or if an unusual failure.
- */
-{
- register char *p;
-
- bufalloc(&RCSb, dlen + rcslen + 1 + baselen + xlen + 1);
-
- /* Try dRCS/basex. */
- VOID memcpy(p = RCSb.string, d, dlen);
- VOID memcpy(p += dlen, rcsdir, rcslen);
- p += rcslen;
- *p++ = SLASH;
- VOID memcpy(p, base, baselen);
- VOID memcpy(p += baselen, x, xlen);
- p[xlen] = 0;
- if (xlen) {
- if (finopen(rcsopen, mustread))
- return true;
-
- /* Try dbasex. */
- /* Start from scratch, because finopen() may have changed RCSb. */
- VOID memcpy(p = RCSb.string, d, dlen);
- VOID memcpy(p += dlen, base, baselen);
- VOID memcpy(p += baselen, x, xlen);
- p[xlen] = 0;
- }
- return finopen(rcsopen, mustread);
-}
-
- int
-pairnames(argc, argv, rcsopen, mustread, quiet)
- int argc;
- char **argv;
- RILE *(*rcsopen)P((struct buf*,struct stat*,int));
- int mustread, quiet;
-/*
- * Pair the pathnames pointed to by argv; argc indicates
- * how many there are.
- * Place a pointer to the RCS pathname into RCSname,
- * and a pointer to the pathname of the working file into workname.
- * If both are given, and workstdout
- * is set, a warning is printed.
- *
- * If the RCS file exists, places its status into RCSstat.
- *
- * If the RCS file exists, it is RCSOPENed for reading, the file pointer
- * is placed into finptr, and the admin-node is read in; returns 1.
- * If the RCS file does not exist and MUSTREAD,
- * print an error unless QUIET and return 0.
- * Otherwise, initialize the admin node and return -1.
- *
- * 0 is returned on all errors, e.g. files that are not regular files.
- */
-{
- static struct buf tempbuf;
-
- register char *p, *arg, *RCS1;
- char const *base, *RCSbase, *x;
- int paired;
- size_t arglen, dlen, baselen, xlen;
-
- fdlock = -1;
-
- if (!(arg = *argv)) return 0; /* already paired pathname */
- if (*arg == '-') {
- error("%s option is ignored after pathnames", arg);
- return 0;
- }
-
- base = basefilename(arg);
- paired = false;
-
- /* first check suffix to see whether it is an RCS file or not */
- if ((x = rcssuffix(arg)))
- {
- /* RCS pathname given */
- RCS1 = arg;
- RCSbase = base;
- baselen = x - base;
- if (
- 1 < argc &&
- !rcssuffix(workname = p = argv[1]) &&
- baselen <= (arglen = strlen(p)) &&
- ((p+=arglen-baselen) == workname || isSLASH(p[-1])) &&
- memcmp(base, p, baselen) == 0
- ) {
- argv[1] = 0;
- paired = true;
- } else {
- bufscpy(&tempbuf, base);
- workname = p = tempbuf.string;
- p[baselen] = 0;
- }
- } else {
- /* working file given; now try to find RCS file */
- workname = arg;
- baselen = strlen(base);
- /* Derive RCS pathname. */
- if (
- 1 < argc &&
- (x = rcssuffix(RCS1 = argv[1])) &&
- baselen <= x - RCS1 &&
- ((RCSbase=x-baselen)==RCS1 || isSLASH(RCSbase[-1])) &&
- memcmp(base, RCSbase, baselen) == 0
- ) {
- argv[1] = 0;
- paired = true;
- } else
- RCSbase = RCS1 = 0;
- }
- /* Now we have a (tentative) RCS pathname in RCS1 and workname. */
- /* Second, try to find the right RCS file */
- if (RCSbase!=RCS1) {
- /* a path for RCSfile is given; single RCS file to look for */
- bufscpy(&RCSbuf, RCS1);
- finptr = (*rcsopen)(&RCSbuf, &RCSstat, mustread);
- RCSerrno = errno;
- } else {
- bufscpy(&RCSbuf, "");
- if (RCS1)
- /* RCS filename was given without path. */
- VOID fin2open(arg, (size_t)0, RCSbase, baselen,
- x, strlen(x), rcsopen, mustread
- );
- else {
- /* No RCS pathname was given. */
- /* Try each suffix in turn. */
- dlen = base-arg;
- x = suffixes;
- while (! fin2open(arg, dlen, base, baselen,
- x, xlen=suffixlen(x), rcsopen, mustread
- )) {
- x += xlen;
- if (!*x++)
- break;
- }
- }
- }
- RCSname = p = RCSbuf.string;
- if (finptr) {
- if (!S_ISREG(RCSstat.st_mode)) {
- error("%s isn't a regular file -- ignored", p);
- return 0;
- }
- Lexinit(); getadmin();
- } else {
- if (RCSerrno!=ENOENT || mustread || fdlock<0) {
- if (RCSerrno == EEXIST)
- error("RCS file %s is in use", p);
- else if (!quiet || RCSerrno!=ENOENT)
- enerror(RCSerrno, p);
- return 0;
- }
- InitAdmin();
- };
-
- if (paired && workstdout)
- workwarn("Working file ignored due to -p option");
-
- prevkeys = false;
- return finptr ? 1 : -1;
-}
-
-
- char const *
-getfullRCSname()
-/*
- * Return a pointer to the full pathname of the RCS file.
- * Remove leading `./'.
- */
-{
- if (ROOTPATH(RCSname)) {
- return RCSname;
- } else {
- static struct buf rcsbuf;
-# if needs_getabsname
- bufalloc(&rcsbuf, SIZEABLE_PATH + 1);
- while (getabsname(RCSname, rcsbuf.string, rcsbuf.size) != 0)
- if (errno == ERANGE)
- bufalloc(&rcsbuf, rcsbuf.size<<1);
- else
- efaterror("getabsname");
-# else
- static char const *wdptr;
- static struct buf wdbuf;
- static size_t wdlen;
-
- register char const *r;
- register size_t dlen;
- register char *d;
- register char const *wd;
-
- if (!(wd = wdptr)) {
- /* Get working directory for the first time. */
- char *PWD = cgetenv("PWD");
- struct stat PWDstat, dotstat;
- if (! (
- (d = PWD) &&
- ROOTPATH(PWD) &&
- stat(PWD, &PWDstat) == 0 &&
- stat(".", &dotstat) == 0 &&
- same_file(PWDstat, dotstat, 1)
- )) {
- bufalloc(&wdbuf, SIZEABLE_PATH + 1);
-# if has_getcwd || !has_getwd
- while (!(d = getcwd(wdbuf.string, wdbuf.size)))
- if (errno == ERANGE)
- bufalloc(&wdbuf, wdbuf.size<<1);
- else if ((d = PWD))
- break;
- else
- efaterror("getcwd");
-# else
- d = getwd(wdbuf.string);
- if (!d && !(d = PWD))
- efaterror("getwd");
-# endif
- }
- wdlen = dir_useful_len(d);
- d[wdlen] = 0;
- wdptr = wd = d;
- }
- /*
- * Remove leading `./'s from RCSname.
- * Do not try to handle `../', since removing it may yield
- * the wrong answer in the presence of symbolic links.
- */
- for (r = RCSname; r[0]=='.' && isSLASH(r[1]); r += 2)
- /* `.////' is equivalent to `./'. */
- while (isSLASH(r[2]))
- r++;
- /* Build full pathname. */
- dlen = wdlen;
- bufalloc(&rcsbuf, dlen + strlen(r) + 2);
- d = rcsbuf.string;
- VOID memcpy(d, wd, dlen);
- d += dlen;
- *d++ = SLASH;
- VOID strcpy(d, r);
-# endif
- return rcsbuf.string;
- }
-}
-
-/* Derived from code from the XFree86 project */
- char const *
-getfullCVSname()
-/* Function: returns a pointer to the path name of the RCS file with the
- * CVSROOT part stripped off, and with 'Attic/' stripped off (if present).
- */
-{
-
-#define ATTICDIR "/Attic"
-
- char const *namebuf = getfullRCSname();
- char *cvsroot = cgetenv("CVSROOT");
- int cvsrootlen;
- char *c = NULL;
- int alen = strlen(ATTICDIR);
-
- if ((c = strrchr(namebuf, '/')) != NULL) {
- if (namebuf - c >= alen) {
- if (!strncmp(c - alen, ATTICDIR, alen)) {
- while(*c != '\0') {
- *(c - alen) = *c;
- c++;
- }
- *(c - alen) = '\0';
- }
- }
- }
-
- if (!cvsroot)
- return(namebuf);
- else
- {
- cvsrootlen = strlen(cvsroot);
- if (!strncmp(namebuf, cvsroot, cvsrootlen) &&
- namebuf[cvsrootlen] == '/')
- return(namebuf + cvsrootlen + 1);
- else
- return(namebuf);
- }
-}
-
- static size_t
-dir_useful_len(d)
- char const *d;
-/*
-* D names a directory; yield the number of characters of D's useful part.
-* To create a file in D, append a SLASH and a file name to D's useful part.
-* Ignore trailing slashes if possible; not only are they ugly,
-* but some non-Posix systems misbehave unless the slashes are omitted.
-*/
-{
-# ifndef SLASHSLASH_is_SLASH
-# define SLASHSLASH_is_SLASH 0
-# endif
- size_t dlen = strlen(d);
- if (!SLASHSLASH_is_SLASH && dlen==2 && isSLASH(d[0]) && isSLASH(d[1]))
- --dlen;
- else
- while (dlen && isSLASH(d[dlen-1]))
- --dlen;
- return dlen;
-}
-
-#ifndef isSLASH
- int
-isSLASH(c)
- int c;
-{
- switch (c) {
- case SLASHes:
- return true;
- default:
- return false;
- }
-}
-#endif
-
-
-#if !has_getcwd && !has_getwd
-
- char *
-getcwd(path, size)
- char *path;
- size_t size;
-{
- static char const usrbinpwd[] = "/usr/bin/pwd";
-# define binpwd (usrbinpwd+4)
-
- register FILE *fp;
- register int c;
- register char *p, *lim;
- int closeerrno, closeerror, e, fd[2], readerror, toolong, wstatus;
- pid_t child;
-
- if (!size) {
- errno = EINVAL;
- return 0;
- }
- if (pipe(fd) != 0)
- return 0;
-# if bad_wait_if_SIGCHLD_ignored
-# ifndef SIGCHLD
-# define SIGCHLD SIGCLD
-# endif
- VOID signal(SIGCHLD, SIG_DFL);
-# endif
- if (!(child = vfork())) {
- if (
- close(fd[0]) == 0 &&
- (fd[1] == STDOUT_FILENO ||
-# ifdef F_DUPFD
- (VOID close(STDOUT_FILENO),
- fcntl(fd[1], F_DUPFD, STDOUT_FILENO))
-# else
- dup2(fd[1], STDOUT_FILENO)
-# endif
- == STDOUT_FILENO &&
- close(fd[1]) == 0
- )
- ) {
- VOID close(STDERR_FILENO);
- VOID execl(binpwd, binpwd, (char *)0);
- VOID execl(usrbinpwd, usrbinpwd, (char *)0);
- }
- _exit(EXIT_FAILURE);
- }
- e = errno;
- closeerror = close(fd[1]);
- closeerrno = errno;
- fp = 0;
- readerror = toolong = wstatus = 0;
- p = path;
- if (0 <= child) {
- fp = fdopen(fd[0], "r");
- e = errno;
- if (fp) {
- lim = p + size;
- for (p = path; ; *p++ = c) {
- if ((c=getc(fp)) < 0) {
- if (feof(fp))
- break;
- if (ferror(fp)) {
- readerror = 1;
- e = errno;
- break;
- }
- }
- if (p == lim) {
- toolong = 1;
- break;
- }
- }
- }
-# if has_waitpid
- if (waitpid(child, &wstatus, 0) < 0)
- wstatus = 1;
-# else
- {
- pid_t w;
- do {
- if ((w = wait(&wstatus)) < 0) {
- wstatus = 1;
- break;
- }
- } while (w != child);
- }
-# endif
- }
- if (!fp) {
- VOID close(fd[0]);
- errno = e;
- return 0;
- }
- if (fclose(fp) != 0)
- return 0;
- if (readerror) {
- errno = e;
- return 0;
- }
- if (closeerror) {
- errno = closeerrno;
- return 0;
- }
- if (toolong) {
- errno = ERANGE;
- return 0;
- }
- if (wstatus || p == path || *--p != '\n') {
- errno = EACCES;
- return 0;
- }
- *p = '\0';
- return path;
-}
-#endif
-
-
-#ifdef PAIRTEST
-/* test program for pairnames() and getfullRCSname() */
-
-char const cmdid[] = "pair";
-
-main(argc, argv)
-int argc; char *argv[];
-{
- int result;
- int initflag;
- quietflag = initflag = false;
-
- while(--argc, ++argv, argc>=1 && ((*argv)[0] == '-')) {
- switch ((*argv)[1]) {
-
- case 'p': workstdout = stdout;
- break;
- case 'i': initflag=true;
- break;
- case 'q': quietflag=true;
- break;
- default: error("unknown option: %s", *argv);
- break;
- }
- }
-
- do {
- RCSname = workname = 0;
- result = pairnames(argc,argv,rcsreadopen,!initflag,quietflag);
- if (result!=0) {
- diagnose("RCS pathname: %s; working pathname: %s\nFull RCS pathname: %s\n",
- RCSname, workname, getfullRCSname()
- );
- }
- switch (result) {
- case 0: continue; /* already paired file */
-
- case 1: if (initflag) {
- rcserror("already exists");
- } else {
- diagnose("RCS file %s exists\n", RCSname);
- }
- Ifclose(finptr);
- break;
-
- case -1:diagnose("RCS file doesn't exist\n");
- break;
- }
-
- } while (++argv, --argc>=1);
-
-}
-
- void
-exiterr()
-{
- dirtempunlink();
- tempunlink();
- _exit(EXIT_FAILURE);
-}
-#endif
diff --git a/gnu/usr.bin/rcs/lib/rcsgen.c b/gnu/usr.bin/rcs/lib/rcsgen.c
deleted file mode 100644
index 35d8702..0000000
--- a/gnu/usr.bin/rcs/lib/rcsgen.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/* Generate RCS revisions. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.16 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.15 1995/06/01 16:23:43 eggert
- * (putadmin): Open RCS file with FOPEN_WB.
- *
- * Revision 5.14 1994/03/17 14:05:48 eggert
- * Work around SVR4 stdio performance bug.
- * Flush stderr after prompt. Remove lint.
- *
- * Revision 5.13 1993/11/03 17:42:27 eggert
- * Don't discard ignored phrases. Improve quality of diagnostics.
- *
- * Revision 5.12 1992/07/28 16:12:44 eggert
- * Statement macro names now end in _.
- * Be consistent about pathnames vs filenames.
- *
- * Revision 5.11 1992/01/24 18:44:19 eggert
- * Move put routines here from rcssyn.c.
- * Add support for bad_creat0.
- *
- * Revision 5.10 1991/10/07 17:32:46 eggert
- * Fix log bugs, e.g. ci -t/dev/null when has_mmap.
- *
- * Revision 5.9 1991/09/10 22:15:46 eggert
- * Fix test for redirected stdin.
- *
- * Revision 5.8 1991/08/19 03:13:55 eggert
- * Add piece tables. Tune.
- *
- * Revision 5.7 1991/04/21 11:58:24 eggert
- * Add MS-DOS support.
- *
- * Revision 5.6 1990/12/27 19:54:26 eggert
- * Fix bug: rcs -t inserted \n, making RCS file grow.
- *
- * Revision 5.5 1990/12/04 05:18:45 eggert
- * Use -I for prompts and -q for diagnostics.
- *
- * Revision 5.4 1990/11/01 05:03:47 eggert
- * Add -I and new -t behavior. Permit arbitrary data in logs.
- *
- * Revision 5.3 1990/09/21 06:12:43 hammer
- * made putdesc() treat stdin the same whether or not it was from a terminal
- * by making it recognize that a single '.' was then end of the
- * description always
- *
- * Revision 5.2 1990/09/04 08:02:25 eggert
- * Fix `co -p1.1 -ko' bug. Standardize yes-or-no procedure.
- *
- * Revision 5.1 1990/08/29 07:14:01 eggert
- * Clean old log messages too.
- *
- * Revision 5.0 1990/08/22 08:12:52 eggert
- * Remove compile-time limits; use malloc instead.
- * Ansify and Posixate.
- *
- * Revision 4.7 89/05/01 15:12:49 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.6 88/08/28 14:59:10 eggert
- * Shrink stdio code size; allow cc -R; remove lint; isatty() -> ttystdin()
- *
- * Revision 4.5 87/12/18 11:43:25 narten
- * additional lint cleanups, and a bug fix from the 4.3BSD version that
- * keeps "ci" from sticking a '\377' into the description if you run it
- * with a zero-length file as the description. (Guy Harris)
- *
- * Revision 4.4 87/10/18 10:35:10 narten
- * Updating version numbers. Changes relative to 1.1 actually relative to
- * 4.2
- *
- * Revision 1.3 87/09/24 13:59:51 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:27 jenkins
- * Port to suns
- *
- * Revision 4.2 83/12/02 23:01:39 wft
- * merged 4.1 and 3.3.1.1 (clearerr(stdin)).
- *
- * Revision 4.1 83/05/10 16:03:33 wft
- * Changed putamin() to abort if trying to reread redirected stdin.
- * Fixed getdesc() to output a prompt on initial newline.
- *
- * Revision 3.3.1.1 83/10/19 04:21:51 lepreau
- * Added clearerr(stdin) for re-reading description from stdin.
- *
- * Revision 3.3 82/11/28 21:36:49 wft
- * 4.2 prerelease
- *
- * Revision 3.3 82/11/28 21:36:49 wft
- * Replaced ferror() followed by fclose() with ffclose().
- * Putdesc() now suppresses the prompts if stdin
- * is not a terminal. A pointer to the current log message is now
- * inserted into the corresponding delta, rather than leaving it in a
- * global variable.
- *
- * Revision 3.2 82/10/18 21:11:26 wft
- * I added checks for write errors during editing, and improved
- * the prompt on putdesc().
- *
- * Revision 3.1 82/10/13 15:55:09 wft
- * corrected type of variables assigned to by getc (char --> int)
- */
-
-
-
-
-#include "rcsbase.h"
-
-libId(genId, "$FreeBSD$")
-
-int interactiveflag; /* Should we act as if stdin is a tty? */
-struct buf curlogbuf; /* buffer for current log message */
-
-enum stringwork { enter, copy, edit, expand, edit_expand };
-
-static void putdelta P((struct hshentry const*,FILE*));
-static void scandeltatext P((struct hshentry*,enum stringwork,int));
-
-
-
-
- char const *
-buildrevision(deltas, target, outfile, expandflag)
- struct hshentries const *deltas;
- struct hshentry *target;
- FILE *outfile;
- int expandflag;
-/* Function: Generates the revision given by target
- * by retrieving all deltas given by parameter deltas and combining them.
- * If outfile is set, the revision is output to it,
- * otherwise written into a temporary file.
- * Temporary files are allocated by maketemp().
- * if expandflag is set, keyword expansion is performed.
- * Return 0 if outfile is set, the name of the temporary file otherwise.
- *
- * Algorithm: Copy initial revision unchanged. Then edit all revisions but
- * the last one into it, alternating input and output files (resultname and
- * editname). The last revision is then edited in, performing simultaneous
- * keyword substitution (this saves one extra pass).
- * All this simplifies if only one revision needs to be generated,
- * or no keyword expansion is necessary, or if output goes to stdout.
- */
-{
- if (deltas->first == target) {
- /* only latest revision to generate */
- openfcopy(outfile);
- scandeltatext(target, expandflag?expand:copy, true);
- if (outfile)
- return 0;
- else {
- Ozclose(&fcopy);
- return resultname;
- }
- } else {
- /* several revisions to generate */
- /* Get initial revision without keyword expansion. */
- scandeltatext(deltas->first, enter, false);
- while ((deltas=deltas->rest)->rest) {
- /* do all deltas except last one */
- scandeltatext(deltas->first, edit, false);
- }
- if (expandflag || outfile) {
- /* first, get to beginning of file*/
- finishedit((struct hshentry*)0, outfile, false);
- }
- scandeltatext(target, expandflag?edit_expand:edit, true);
- finishedit(
- expandflag ? target : (struct hshentry*)0,
- outfile, true
- );
- if (outfile)
- return 0;
- Ozclose(&fcopy);
- return resultname;
- }
-}
-
-
-
- static void
-scandeltatext(delta, func, needlog)
- struct hshentry *delta;
- enum stringwork func;
- int needlog;
-/* Function: Scans delta text nodes up to and including the one given
- * by delta. For the one given by delta, the log message is saved into
- * delta->log if needlog is set; func specifies how to handle the text.
- * Similarly, if needlog, delta->igtext is set to the ignored phrases.
- * Assumes the initial lexeme must be read in first.
- * Does not advance nexttok after it is finished.
- */
-{
- struct hshentry const *nextdelta;
- struct cbuf cb;
-
- for (;;) {
- if (eoflex())
- fatserror("can't find delta for revision %s", delta->num);
- nextlex();
- if (!(nextdelta=getnum())) {
- fatserror("delta number corrupted");
- }
- getkeystring(Klog);
- if (needlog && delta==nextdelta) {
- cb = savestring(&curlogbuf);
- delta->log = cleanlogmsg(curlogbuf.string, cb.size);
- nextlex();
- delta->igtext = getphrases(Ktext);
- } else {readstring();
- ignorephrases(Ktext);
- }
- getkeystring(Ktext);
-
- if (delta==nextdelta)
- break;
- readstring(); /* skip over it */
-
- }
- switch (func) {
- case enter: enterstring(); break;
- case copy: copystring(); break;
- case expand: xpandstring(delta); break;
- case edit: editstring((struct hshentry *)0); break;
- case edit_expand: editstring(delta); break;
- }
-}
-
- struct cbuf
-cleanlogmsg(m, s)
- char *m;
- size_t s;
-{
- register char *t = m;
- register char const *f = t;
- struct cbuf r;
- while (s) {
- --s;
- if ((*t++ = *f++) == '\n')
- while (m < --t)
- if (t[-1]!=' ' && t[-1]!='\t') {
- *t++ = '\n';
- break;
- }
- }
- while (m < t && (t[-1]==' ' || t[-1]=='\t' || t[-1]=='\n'))
- --t;
- r.string = m;
- r.size = t - m;
- return r;
-}
-
-
-int ttystdin()
-{
- static int initialized;
- if (!initialized) {
- if (!interactiveflag)
- interactiveflag = isatty(STDIN_FILENO);
- initialized = true;
- }
- return interactiveflag;
-}
-
- int
-getcstdin()
-{
- register FILE *in;
- register int c;
-
- in = stdin;
- if (feof(in) && ttystdin())
- clearerr(in);
- c = getc(in);
- if (c == EOF) {
- testIerror(in);
- if (feof(in) && ttystdin())
- afputc('\n',stderr);
- }
- return c;
-}
-
-#if has_prototypes
- int
-yesorno(int default_answer, char const *question, ...)
-#else
- /*VARARGS2*/ int
- yesorno(default_answer, question, va_alist)
- int default_answer; char const *question; va_dcl
-#endif
-{
- va_list args;
- register int c, r;
- if (!quietflag && ttystdin()) {
- oflush();
- vararg_start(args, question);
- fvfprintf(stderr, question, args);
- va_end(args);
- eflush();
- r = c = getcstdin();
- while (c!='\n' && !feof(stdin))
- c = getcstdin();
- if (r=='y' || r=='Y')
- return true;
- if (r=='n' || r=='N')
- return false;
- }
- return default_answer;
-}
-
-
- void
-putdesc(textflag, textfile)
- int textflag;
- char *textfile;
-/* Function: puts the descriptive text into file frewrite.
- * if finptr && !textflag, the text is copied from the old description.
- * Otherwise, if textfile, the text is read from that
- * file, or from stdin, if !textfile.
- * A textfile with a leading '-' is treated as a string, not a pathname.
- * If finptr, the old descriptive text is discarded.
- * Always clears foutptr.
- */
-{
- static struct buf desc;
- static struct cbuf desclean;
-
- register FILE *txt;
- register int c;
- register FILE * frew;
- register char *p;
- register size_t s;
- char const *plim;
-
- frew = frewrite;
- if (finptr && !textflag) {
- /* copy old description */
- aprintf(frew, "\n\n%s%c", Kdesc, nextc);
- foutptr = frewrite;
- getdesc(false);
- foutptr = 0;
- } else {
- foutptr = 0;
- /* get new description */
- if (finptr) {
- /*skip old description*/
- getdesc(false);
- }
- aprintf(frew,"\n\n%s\n%c",Kdesc,SDELIM);
- if (!textfile)
- desclean = getsstdin(
- "t-", "description",
- "NOTE: This is NOT the log message!\n", &desc
- );
- else if (!desclean.string) {
- if (*textfile == '-') {
- p = textfile + 1;
- s = strlen(p);
- } else {
- if (!(txt = fopenSafer(textfile, "r")))
- efaterror(textfile);
- bufalloc(&desc, 1);
- p = desc.string;
- plim = p + desc.size;
- for (;;) {
- if ((c=getc(txt)) == EOF) {
- testIerror(txt);
- if (feof(txt))
- break;
- }
- if (plim <= p)
- p = bufenlarge(&desc, &plim);
- *p++ = c;
- }
- if (fclose(txt) != 0)
- Ierror();
- s = p - desc.string;
- p = desc.string;
- }
- desclean = cleanlogmsg(p, s);
- }
- putstring(frew, false, desclean, true);
- aputc_('\n', frew)
- }
-}
-
- struct cbuf
-getsstdin(option, name, note, buf)
- char const *option, *name, *note;
- struct buf *buf;
-{
- register int c;
- register char *p;
- register size_t i;
- register int tty = ttystdin();
-
- if (tty) {
- aprintf(stderr,
- "enter %s, terminated with single '.' or end of file:\n%s>> ",
- name, note
- );
- eflush();
- } else if (feof(stdin))
- rcsfaterror("can't reread redirected stdin for %s; use -%s<%s>",
- name, option, name
- );
-
- for (
- i = 0, p = 0;
- c = getcstdin(), !feof(stdin);
- bufrealloc(buf, i+1), p = buf->string, p[i++] = c
- )
- if (c == '\n')
- if (i && p[i-1]=='.' && (i==1 || p[i-2]=='\n')) {
- /* Remove trailing '.'. */
- --i;
- break;
- } else if (tty) {
- aputs(">> ", stderr);
- eflush();
- }
- return cleanlogmsg(p, i);
-}
-
-
- void
-putadmin()
-/* Output the admin node. */
-{
- register FILE *fout;
- struct assoc const *curassoc;
- struct rcslock const *curlock;
- struct access const *curaccess;
-
- if (!(fout = frewrite)) {
-# if bad_creat0
- ORCSclose();
- fout = fopenSafer(makedirtemp(0), FOPEN_WB);
-# else
- int fo = fdlock;
- fdlock = -1;
- fout = fdopen(fo, FOPEN_WB);
-# endif
-
- if (!(frewrite = fout))
- efaterror(RCSname);
- }
-
- /*
- * Output the first character with putc, not printf.
- * Otherwise, an SVR4 stdio bug buffers output inefficiently.
- */
- aputc_(*Khead, fout)
- aprintf(fout, "%s\t%s;\n", Khead + 1, Head?Head->num:"");
- if (Dbranch && VERSION(4)<=RCSversion)
- aprintf(fout, "%s\t%s;\n", Kbranch, Dbranch);
-
- aputs(Kaccess, fout);
- curaccess = AccessList;
- while (curaccess) {
- aprintf(fout, "\n\t%s", curaccess->login);
- curaccess = curaccess->nextaccess;
- }
- aprintf(fout, ";\n%s", Ksymbols);
- curassoc = Symbols;
- while (curassoc) {
- aprintf(fout, "\n\t%s:%s", curassoc->symbol, curassoc->num);
- curassoc = curassoc->nextassoc;
- }
- aprintf(fout, ";\n%s", Klocks);
- curlock = Locks;
- while (curlock) {
- aprintf(fout, "\n\t%s:%s", curlock->login, curlock->delta->num);
- curlock = curlock->nextlock;
- }
- if (StrictLocks) aprintf(fout, "; %s", Kstrict);
- aprintf(fout, ";\n");
- if (Comment.size) {
- aprintf(fout, "%s\t", Kcomment);
- putstring(fout, true, Comment, false);
- aprintf(fout, ";\n");
- }
- if (Expand != KEYVAL_EXPAND)
- aprintf(fout, "%s\t%c%s%c;\n",
- Kexpand, SDELIM, expand_names[Expand], SDELIM
- );
- awrite(Ignored.string, Ignored.size, fout);
- aputc_('\n', fout)
-}
-
-
- static void
-putdelta(node, fout)
- register struct hshentry const *node;
- register FILE * fout;
-/* Output the delta NODE to FOUT. */
-{
- struct branchhead const *nextbranch;
-
- if (!node) return;
-
- aprintf(fout, "\n%s\n%s\t%s;\t%s %s;\t%s %s;\nbranches",
- node->num,
- Kdate, node->date,
- Kauthor, node->author,
- Kstate, node->state?node->state:""
- );
- nextbranch = node->branches;
- while (nextbranch) {
- aprintf(fout, "\n\t%s", nextbranch->hsh->num);
- nextbranch = nextbranch->nextbranch;
- }
-
- aprintf(fout, ";\n%s\t%s;\n", Knext, node->next?node->next->num:"");
- awrite(node->ig.string, node->ig.size, fout);
-}
-
-
- void
-puttree(root, fout)
- struct hshentry const *root;
- register FILE *fout;
-/* Output the delta tree with base ROOT in preorder to FOUT. */
-{
- struct branchhead const *nextbranch;
-
- if (!root) return;
-
- if (root->selector)
- putdelta(root, fout);
-
- puttree(root->next, fout);
-
- nextbranch = root->branches;
- while (nextbranch) {
- puttree(nextbranch->hsh, fout);
- nextbranch = nextbranch->nextbranch;
- }
-}
-
-
- int
-putdtext(delta, srcname, fout, diffmt)
- struct hshentry const *delta;
- char const *srcname;
- FILE *fout;
- int diffmt;
-/*
- * Output a deltatext node with delta number DELTA->num, log message DELTA->log,
- * ignored phrases DELTA->igtext and text SRCNAME to FOUT.
- * Double up all SDELIMs in both the log and the text.
- * Make sure the log message ends in \n.
- * Return false on error.
- * If DIFFMT, also check that the text is valid diff -n output.
- */
-{
- RILE *fin;
- if (!(fin = Iopen(srcname, "r", (struct stat*)0))) {
- eerror(srcname);
- return false;
- }
- putdftext(delta, fin, fout, diffmt);
- Ifclose(fin);
- return true;
-}
-
- void
-putstring(out, delim, s, log)
- register FILE *out;
- struct cbuf s;
- int delim, log;
-/*
- * Output to OUT one SDELIM if DELIM, then the string S with SDELIMs doubled.
- * If LOG is set then S is a log string; append a newline if S is nonempty.
- */
-{
- register char const *sp;
- register size_t ss;
-
- if (delim)
- aputc_(SDELIM, out)
- sp = s.string;
- for (ss = s.size; ss; --ss) {
- if (*sp == SDELIM)
- aputc_(SDELIM, out)
- aputc_(*sp++, out)
- }
- if (s.size && log)
- aputc_('\n', out)
- aputc_(SDELIM, out)
-}
-
- void
-putdftext(delta, finfile, foutfile, diffmt)
- struct hshentry const *delta;
- RILE *finfile;
- FILE *foutfile;
- int diffmt;
-/* like putdtext(), except the source file is already open */
-{
- declarecache;
- register FILE *fout;
- register int c;
- register RILE *fin;
- int ed;
- struct diffcmd dc;
-
- fout = foutfile;
- aprintf(fout, DELNUMFORM, delta->num, Klog);
-
- /* put log */
- putstring(fout, true, delta->log, true);
- aputc_('\n', fout)
-
- /* put ignored phrases */
- awrite(delta->igtext.string, delta->igtext.size, fout);
-
- /* put text */
- aprintf(fout, "%s\n%c", Ktext, SDELIM);
-
- fin = finfile;
- setupcache(fin);
- if (!diffmt) {
- /* Copy the file */
- cache(fin);
- for (;;) {
- cachegeteof_(c, break;)
- if (c==SDELIM) aputc_(SDELIM, fout) /*double up SDELIM*/
- aputc_(c, fout)
- }
- } else {
- initdiffcmd(&dc);
- while (0 <= (ed = getdiffcmd(fin, false, fout, &dc)))
- if (ed) {
- cache(fin);
- while (dc.nlines--)
- do {
- cachegeteof_(c, { if (!dc.nlines) goto OK_EOF; unexpected_EOF(); })
- if (c == SDELIM)
- aputc_(SDELIM, fout)
- aputc_(c, fout)
- } while (c != '\n');
- uncache(fin);
- }
- }
- OK_EOF:
- aprintf(fout, "%c\n", SDELIM);
-}
diff --git a/gnu/usr.bin/rcs/lib/rcskeep.c b/gnu/usr.bin/rcs/lib/rcskeep.c
deleted file mode 100644
index 4a90f85..0000000
--- a/gnu/usr.bin/rcs/lib/rcskeep.c
+++ /dev/null
@@ -1,452 +0,0 @@
-/* Extract RCS keyword string values from working files. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.10 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.9 1995/06/01 16:23:43 eggert
- * (getoldkeys): Don't panic if a Name: is empty.
- *
- * Revision 5.8 1994/03/17 14:05:48 eggert
- * Remove lint.
- *
- * Revision 5.7 1993/11/09 17:40:15 eggert
- * Use simpler timezone parsing strategy now that we're using ISO 8601 format.
- *
- * Revision 5.6 1993/11/03 17:42:27 eggert
- * Scan for Name keyword. Improve quality of diagnostics.
- *
- * Revision 5.5 1992/07/28 16:12:44 eggert
- * Statement macro names now end in _.
- *
- * Revision 5.4 1991/08/19 03:13:55 eggert
- * Tune.
- *
- * Revision 5.3 1991/04/21 11:58:25 eggert
- * Shorten names to keep them distinct on shortname hosts.
- *
- * Revision 5.2 1990/10/04 06:30:20 eggert
- * Parse time zone offsets; future RCS versions may output them.
- *
- * Revision 5.1 1990/09/20 02:38:56 eggert
- * ci -k now checks dates more thoroughly.
- *
- * Revision 5.0 1990/08/22 08:12:53 eggert
- * Retrieve old log message if there is one.
- * Don't require final newline.
- * Remove compile-time limits; use malloc instead. Tune.
- * Permit dates past 1999/12/31. Ansify and Posixate.
- *
- * Revision 4.6 89/05/01 15:12:56 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.5 88/08/09 19:13:03 eggert
- * Remove lint and speed up by making FILE *fp local, not global.
- *
- * Revision 4.4 87/12/18 11:44:21 narten
- * more lint cleanups (Guy Harris)
- *
- * Revision 4.3 87/10/18 10:35:50 narten
- * Updating version numbers. Changes relative to 1.1 actually relative
- * to 4.1
- *
- * Revision 1.3 87/09/24 14:00:00 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:29 jenkins
- * Port to suns
- *
- * Revision 4.1 83/05/10 16:26:44 wft
- * Added new markers Id and RCSfile; extraction added.
- * Marker matching with trymatch().
- *
- * Revision 3.2 82/12/24 12:08:26 wft
- * added missing #endif.
- *
- * Revision 3.1 82/12/04 13:22:41 wft
- * Initial revision.
- *
- */
-
-#include "rcsbase.h"
-
-libId(keepId, "$FreeBSD$")
-
-static int badly_terminated P((void));
-static int checknum P((char const*));
-static int get0val P((int,RILE*,struct buf*,int));
-static int getval P((RILE*,struct buf*,int));
-static int keepdate P((RILE*));
-static int keepid P((int,RILE*,struct buf*));
-static int keeprev P((RILE*));
-
-int prevkeys;
-struct buf prevauthor, prevdate, prevname, prevrev, prevstate;
-
- int
-getoldkeys(fp)
- register RILE *fp;
-/* Function: Tries to read keyword values for author, date,
- * revision number, and state out of the file fp.
- * If fp is null, workname is opened and closed instead of using fp.
- * The results are placed into
- * prevauthor, prevdate, prevname, prevrev, prevstate.
- * Aborts immediately if it finds an error and returns false.
- * If it returns true, it doesn't mean that any of the
- * values were found; instead, check to see whether the corresponding arrays
- * contain the empty string.
- */
-{
- register int c;
- char keyword[keylength+1];
- register char * tp;
- int needs_closing;
- int prevname_found;
-
- if (prevkeys)
- return true;
-
- needs_closing = false;
- if (!fp) {
- if (!(fp = Iopen(workname, FOPEN_R_WORK, (struct stat*)0))) {
- eerror(workname);
- return false;
- }
- needs_closing = true;
- }
-
- /* initialize to empty */
- bufscpy(&prevauthor, "");
- bufscpy(&prevdate, "");
- bufscpy(&prevname, ""); prevname_found = 0;
- bufscpy(&prevrev, "");
- bufscpy(&prevstate, "");
-
- c = '\0'; /* anything but KDELIM */
- for (;;) {
- if ( c==KDELIM) {
- do {
- /* try to get keyword */
- tp = keyword;
- for (;;) {
- Igeteof_(fp, c, goto ok;)
- switch (c) {
- default:
- if (keyword+keylength <= tp)
- break;
- *tp++ = c;
- continue;
-
- case '\n': case KDELIM: case VDELIM:
- break;
- }
- break;
- }
- } while (c==KDELIM);
- if (c!=VDELIM) continue;
- *tp = c;
- Igeteof_(fp, c, break;)
- switch (c) {
- case ' ': case '\t': break;
- default: continue;
- }
-
- switch (trymatch(keyword)) {
- case Author:
- if (!keepid(0, fp, &prevauthor))
- return false;
- c = 0;
- break;
- case Date:
- if (!(c = keepdate(fp)))
- return false;
- break;
- case Header:
- case Id:
- case LocalId:
- if (!(
- getval(fp, (struct buf*)0, false) &&
- keeprev(fp) &&
- (c = keepdate(fp)) &&
- keepid(c, fp, &prevauthor) &&
- keepid(0, fp, &prevstate)
- ))
- return false;
- /* Skip either ``who'' (new form) or ``Locker: who'' (old). */
- if (getval(fp, (struct buf*)0, true) &&
- getval(fp, (struct buf*)0, true))
- c = 0;
- else if (nerror)
- return false;
- else
- c = KDELIM;
- break;
- case Locker:
- (void) getval(fp, (struct buf*)0, false);
- c = 0;
- break;
- case Log:
- case RCSfile:
- case Source:
- if (!getval(fp, (struct buf*)0, false))
- return false;
- c = 0;
- break;
- case Name:
- if (getval(fp, &prevname, false)) {
- if (*prevname.string)
- checkssym(prevname.string);
- prevname_found = 1;
- }
- c = 0;
- break;
- case Revision:
- if (!keeprev(fp))
- return false;
- c = 0;
- break;
- case State:
- if (!keepid(0, fp, &prevstate))
- return false;
- c = 0;
- break;
- default:
- continue;
- }
- if (!c)
- Igeteof_(fp, c, c=0;)
- if (c != KDELIM) {
- workerror("closing %c missing on keyword", KDELIM);
- return false;
- }
- if (prevname_found &&
- *prevauthor.string && *prevdate.string &&
- *prevrev.string && *prevstate.string
- )
- break;
- }
- Igeteof_(fp, c, break;)
- }
-
- ok:
- if (needs_closing)
- Ifclose(fp);
- else
- Irewind(fp);
- prevkeys = true;
- return true;
-}
-
- static int
-badly_terminated()
-{
- workerror("badly terminated keyword value");
- return false;
-}
-
- static int
-getval(fp, target, optional)
- register RILE *fp;
- struct buf *target;
- int optional;
-/* Reads a keyword value from FP into TARGET.
- * Returns true if one is found, false otherwise.
- * Does not modify target if it is 0.
- * Do not report an error if OPTIONAL is set and KDELIM is found instead.
- */
-{
- int c;
- Igeteof_(fp, c, return badly_terminated();)
- return get0val(c, fp, target, optional);
-}
-
- static int
-get0val(c, fp, target, optional)
- register int c;
- register RILE *fp;
- struct buf *target;
- int optional;
-/* Reads a keyword value from C+FP into TARGET, perhaps OPTIONALly.
- * Same as getval, except C is the lookahead character.
- */
-{ register char * tp;
- char const *tlim;
- register int got1;
-
- if (target) {
- bufalloc(target, 1);
- tp = target->string;
- tlim = tp + target->size;
- } else
- tlim = tp = 0;
- got1 = false;
- for (;;) {
- switch (c) {
- default:
- got1 = true;
- if (tp) {
- *tp++ = c;
- if (tlim <= tp)
- tp = bufenlarge(target, &tlim);
- }
- break;
-
- case ' ':
- case '\t':
- if (tp) {
- *tp = 0;
-# ifdef KEEPTEST
- VOID printf("getval: %s\n", target);
-# endif
- }
- return got1;
-
- case KDELIM:
- if (!got1 && optional)
- return false;
- /* fall into */
- case '\n':
- case 0:
- return badly_terminated();
- }
- Igeteof_(fp, c, return badly_terminated();)
- }
-}
-
-
- static int
-keepdate(fp)
- RILE *fp;
-/* Function: reads a date prevdate; checks format
- * Return 0 on error, lookahead character otherwise.
- */
-{
- struct buf prevday, prevtime;
- register int c;
-
- c = 0;
- bufautobegin(&prevday);
- if (getval(fp,&prevday,false)) {
- bufautobegin(&prevtime);
- if (getval(fp,&prevtime,false)) {
- Igeteof_(fp, c, c=0;)
- if (c) {
- register char const *d = prevday.string, *t = prevtime.string;
- bufalloc(&prevdate, strlen(d) + strlen(t) + 9);
- VOID sprintf(prevdate.string, "%s%s %s%s",
- /* Parse dates put out by old versions of RCS. */
- isdigit(d[0]) && isdigit(d[1]) && !isdigit(d[2])
- ? "19" : "",
- d, t,
- strchr(t,'-') || strchr(t,'+') ? "" : "+0000"
- );
- }
- }
- bufautoend(&prevtime);
- }
- bufautoend(&prevday);
- return c;
-}
-
- static int
-keepid(c, fp, b)
- int c;
- RILE *fp;
- struct buf *b;
-/* Get previous identifier from C+FP into B. */
-{
- if (!c)
- Igeteof_(fp, c, return false;)
- if (!get0val(c, fp, b, false))
- return false;
- checksid(b->string);
- return !nerror;
-}
-
- static int
-keeprev(fp)
- RILE *fp;
-/* Get previous revision from FP into prevrev. */
-{
- return getval(fp,&prevrev,false) && checknum(prevrev.string);
-}
-
-
- static int
-checknum(s)
- char const *s;
-{
- register char const *sp;
- register int dotcount = 0;
- for (sp=s; ; sp++) {
- switch (*sp) {
- case 0:
- if (dotcount & 1)
- return true;
- else
- break;
-
- case '.':
- dotcount++;
- continue;
-
- default:
- if (isdigit(*sp))
- continue;
- break;
- }
- break;
- }
- workerror("%s is not a revision number", s);
- return false;
-}
-
-
-
-#ifdef KEEPTEST
-
-/* Print the keyword values found. */
-
-char const cmdid[] ="keeptest";
-
- int
-main(argc, argv)
-int argc; char *argv[];
-{
- while (*(++argv)) {
- workname = *argv;
- getoldkeys((RILE*)0);
- VOID printf("%s: revision: %s, date: %s, author: %s, name: %s, state: %s\n",
- *argv, prevrev.string, prevdate.string, prevauthor.string, prevname.string, prevstate.string);
- }
- exitmain(EXIT_SUCCESS);
-}
-#endif
diff --git a/gnu/usr.bin/rcs/lib/rcskeys.c b/gnu/usr.bin/rcs/lib/rcskeys.c
deleted file mode 100644
index 378f57d..0000000
--- a/gnu/usr.bin/rcs/lib/rcskeys.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/* RCS keyword table and match operation */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.4 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.3 1993/11/03 17:42:27 eggert
- * Add Name keyword.
- *
- * Revision 5.2 1991/08/19 03:13:55 eggert
- * Say `T const' instead of `const T'; it's less confusing for pointer types.
- * (This change was made in other source files too.)
- *
- * Revision 5.1 1991/04/21 11:58:25 eggert
- * Don't put , just before } in initializer.
- *
- * Revision 5.0 1990/08/22 08:12:54 eggert
- * Add -k. Ansify and Posixate.
- *
- * Revision 4.3 89/05/01 15:13:02 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.2 87/10/18 10:36:33 narten
- * Updating version numbers. Changes relative to 1.1 actuallyt
- * relative to 4.1
- *
- * Revision 1.2 87/09/24 14:00:10 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 4.1 83/05/04 10:06:53 wft
- * Initial revision.
- *
- */
-
-
-#include "rcsbase.h"
-
-libId(keysId, "$FreeBSD$")
-
-
-char const *Keyword[] = {
- /* This must be in the same order as rcsbase.h's enum markers type. */
- 0,
- AUTHOR, DATE, HEADER, IDH,
- LOCKER, LOG, NAME, RCSFILE, REVISION, SOURCE, STATE, CVSHEADER,
- NULL
-};
-
-/* Expand all keywords by default */
-static int ExpandKeyword[] = {
- false,
- true, true, true, true,
- true, true, true, true, true, true, true, true,
- true
-};
-enum markers LocalIdMode = Id;
-
- enum markers
-trymatch(string)
- char const *string;
-/* function: Checks whether string starts with a keyword followed
- * by a KDELIM or a VDELIM.
- * If successful, returns the appropriate marker, otherwise Nomatch.
- */
-{
- register int j;
- register char const *p, *s;
- for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); ) {
- if (!ExpandKeyword[j])
- continue;
- /* try next keyword */
- p = Keyword[j];
- if (p == NULL)
- continue;
- s = string;
- while (*p++ == *s++) {
- if (!*p)
- switch (*s) {
- case KDELIM:
- case VDELIM:
- return (enum markers)j;
- default:
- return Nomatch;
- }
- }
- }
- return(Nomatch);
-}
-
- void
-setIncExc(arg)
- char const *arg;
-/* Sets up the ExpandKeyword table according to command-line flags */
-{
- char *key;
- char *copy, *next;
- int include = 0, j;
-
- copy = strdup(arg);
- next = copy;
- switch (*next++) {
- case 'e':
- include = false;
- break;
- case 'i':
- include = true;
- break;
- default:
- free(copy);
- return;
- }
- if (include)
- for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); )
- ExpandKeyword[j] = false;
- key = strtok(next, ",");
- while (key) {
- for (j = sizeof(Keyword)/sizeof(*Keyword); (--j); ) {
- if (Keyword[j] == NULL)
- continue;
- if (!strcmp(key, Keyword[j]))
- ExpandKeyword[j] = include;
- }
- key = strtok(NULL, ",");
- }
- free(copy);
- return;
-}
-
- void
-setRCSLocalId(string)
- char const *string;
-/* function: sets local RCS id and RCSLOCALID envariable */
-{
- static char local_id[keylength+1];
- char *copy, *next, *key;
- int j;
-
- copy = strdup(string);
- next = copy;
- key = strtok(next, "=");
- if (strlen(key) > keylength)
- faterror("LocalId is too long");
- VOID strcpy(local_id, key);
- Keyword[LocalId] = local_id;
-
- /* options? */
- while (key = strtok(NULL, ",")) {
- if (!strcmp(key, Keyword[Id]))
- LocalIdMode=Id;
- else if (!strcmp(key, Keyword[Header]))
- LocalIdMode=Header;
- else if (!strcmp(key, Keyword[CVSHeader]))
- LocalIdMode=CVSHeader;
- else
- error("Unknown LocalId mode");
- }
- free(copy);
-}
diff --git a/gnu/usr.bin/rcs/lib/rcslex.c b/gnu/usr.bin/rcs/lib/rcslex.c
deleted file mode 100644
index 7a11f79..0000000
--- a/gnu/usr.bin/rcs/lib/rcslex.c
+++ /dev/null
@@ -1,1568 +0,0 @@
-/* lexical analysis of RCS files */
-
-/******************************************************************************
- * Lexical Analysis.
- * hashtable, Lexinit, nextlex, getlex, getkey,
- * getid, getnum, readstring, printstring, savestring,
- * checkid, fatserror, error, faterror, warn, diagnose
- * Testprogram: define LEXDB
- ******************************************************************************
- */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-
-
-/*
- * Revision 5.19 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.18 1995/06/01 16:23:43 eggert
- * (map_fd_deallocate,mmap_deallocate,read_deallocate,nothing_to_deallocate):
- * New functions.
- * (Iclose): If large_memory and maps_memory, use them to deallocate mapping.
- * (fd2RILE): Use map_fd if available.
- * If one mapping method fails, try the next instead of giving up;
- * if they all fail, fall back on ordinary read.
- * Work around bug: root mmap over NFS succeeds, but accessing dumps core.
- * Use MAP_FAILED macro for mmap failure, and `char *' instead of caddr_t.
- * (advise_access): Use madvise only if this instance used mmap.
- * (Iopen): Use fdSafer to get safer file descriptor.
- * (aflush): Moved here from rcsedit.c.
- *
- * Revision 5.17 1994/03/20 04:52:58 eggert
- * Don't worry if madvise fails. Add Orewind. Remove lint.
- *
- * Revision 5.16 1993/11/09 17:55:29 eggert
- * Fix `label: }' typo.
- *
- * Revision 5.15 1993/11/03 17:42:27 eggert
- * Improve quality of diagnostics by putting file names in them more often.
- * Don't discard ignored phrases.
- *
- * Revision 5.14 1992/07/28 16:12:44 eggert
- * Identifiers may now start with a digit and (unless they are symbolic names)
- * may contain `.'. Avoid `unsigned'. Statement macro names now end in _.
- *
- * Revision 5.13 1992/02/17 23:02:27 eggert
- * Work around NFS mmap SIGBUS problem.
- *
- * Revision 5.12 1992/01/06 02:42:34 eggert
- * Use OPEN_O_BINARY if mode contains 'b'.
- *
- * Revision 5.11 1991/11/03 03:30:44 eggert
- * Fix porting bug to ancient hosts lacking vfprintf.
- *
- * Revision 5.10 1991/10/07 17:32:46 eggert
- * Support piece tables even if !has_mmap.
- *
- * Revision 5.9 1991/09/24 00:28:42 eggert
- * Don't export errsay().
- *
- * Revision 5.8 1991/08/19 03:13:55 eggert
- * Add eoflex(), mmap support. Tune.
- *
- * Revision 5.7 1991/04/21 11:58:26 eggert
- * Add MS-DOS support.
- *
- * Revision 5.6 1991/02/25 07:12:42 eggert
- * Work around fputs bug. strsave -> str_save (DG/UX name clash)
- *
- * Revision 5.5 1990/12/04 05:18:47 eggert
- * Use -I for prompts and -q for diagnostics.
- *
- * Revision 5.4 1990/11/19 20:05:28 hammer
- * no longer gives warning about unknown keywords if -q is specified
- *
- * Revision 5.3 1990/11/01 05:03:48 eggert
- * When ignoring unknown phrases, copy them to the output RCS file.
- *
- * Revision 5.2 1990/09/04 08:02:27 eggert
- * Count RCS lines better.
- *
- * Revision 5.1 1990/08/29 07:14:03 eggert
- * Work around buggy compilers with defective argument promotion.
- *
- * Revision 5.0 1990/08/22 08:12:55 eggert
- * Remove compile-time limits; use malloc instead.
- * Report errno-related errors with perror().
- * Ansify and Posixate. Add support for ISO 8859.
- * Use better hash function.
- *
- * Revision 4.6 89/05/01 15:13:07 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.5 88/08/28 15:01:12 eggert
- * Don't loop when writing error messages to a full filesystem.
- * Flush stderr/stdout when mixing output.
- * Yield exit status compatible with diff(1).
- * Shrink stdio code size; allow cc -R; remove lint.
- *
- * Revision 4.4 87/12/18 11:44:47 narten
- * fixed to use "varargs" in "fprintf"; this is required if it is to
- * work on a SPARC machine such as a Sun-4
- *
- * Revision 4.3 87/10/18 10:37:18 narten
- * Updating version numbers. Changes relative to 1.1 actually relative
- * to version 4.1
- *
- * Revision 1.3 87/09/24 14:00:17 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:33 jenkins
- * Port to suns
- *
- * Revision 4.1 83/03/25 18:12:51 wft
- * Only changed $Header to $Id.
- *
- * Revision 3.3 82/12/10 16:22:37 wft
- * Improved error messages, changed exit status on error to 1.
- *
- * Revision 3.2 82/11/28 21:27:10 wft
- * Renamed ctab to map and included EOFILE; ctab is now a macro in rcsbase.h.
- * Added fflsbuf(), fputs(), and fprintf(), which abort the RCS operations
- * properly in case there is an IO-error (e.g., file system full).
- *
- * Revision 3.1 82/10/11 19:43:56 wft
- * removed unused label out:;
- * made sure all calls to getc() return into an integer, not a char.
- */
-
-
-/*
-#define LEXDB
-*/
-/* version LEXDB is for testing the lexical analyzer. The testprogram
- * reads a stream of lexemes, enters the revision numbers into the
- * hashtable, and prints the recognized tokens. Keywords are recognized
- * as identifiers.
- */
-
-
-
-#include "rcsbase.h"
-
-libId(lexId, "$FreeBSD$")
-
-static char *checkidentifier P((char*,int,int));
-static void errsay P((char const*));
-static void fatsay P((char const*));
-static void lookup P((char const*));
-static void startsay P((const char*,const char*));
-static void warnsay P((char const*));
-
-static struct hshentry *nexthsh; /*pointer to next hash entry, set by lookup*/
-
-enum tokens nexttok; /*next token, set by nextlex */
-
-int hshenter; /*if true, next suitable lexeme will be entered */
- /*into the symbol table. Handle with care. */
-int nextc; /*next input character, initialized by Lexinit */
-
-long rcsline; /*current line-number of input */
-int nerror; /*counter for errors */
-int quietflag; /*indicates quiet mode */
-RILE * finptr; /*input file descriptor */
-
-FILE * frewrite; /*file descriptor for echoing input */
-
-FILE * foutptr; /* copy of frewrite, but 0 to suppress echo */
-
-static struct buf tokbuf; /* token buffer */
-
-char const * NextString; /* next token */
-
-/*
- * Our hash algorithm is h[0] = 0, h[i+1] = 4*h[i] + c,
- * so hshsize should be odd.
- * See B J McKenzie, R Harries & T Bell, Selecting a hashing algorithm,
- * Software--practice & experience 20, 2 (Feb 1990), 209-224.
- */
-#ifndef hshsize
-# define hshsize 511
-#endif
-
-static struct hshentry *hshtab[hshsize]; /*hashtable */
-
-static int ignored_phrases; /* have we ignored phrases in this RCS file? */
-
- void
-warnignore()
-{
- if (!ignored_phrases) {
- ignored_phrases = true;
- rcswarn("Unknown phrases like `%s ...;' are present.", NextString);
- }
-}
-
-
-
- static void
-lookup(str)
- char const *str;
-/* Function: Looks up the character string pointed to by str in the
- * hashtable. If the string is not present, a new entry for it is created.
- * In any case, the address of the corresponding hashtable entry is placed
- * into nexthsh.
- */
-{
- register unsigned ihash; /* index into hashtable */
- register char const *sp;
- register struct hshentry *n, **p;
-
- /* calculate hash code */
- sp = str;
- ihash = 0;
- while (*sp)
- ihash = (ihash<<2) + *sp++;
- ihash %= hshsize;
-
- for (p = &hshtab[ihash]; ; p = &n->nexthsh)
- if (!(n = *p)) {
- /* empty slot found */
- *p = n = ftalloc(struct hshentry);
- n->num = fstr_save(str);
- n->nexthsh = 0;
-# ifdef LEXDB
- VOID printf("\nEntered: %s at %u ", str, ihash);
-# endif
- break;
- } else if (strcmp(str, n->num) == 0)
- /* match found */
- break;
- nexthsh = n;
- NextString = n->num;
-}
-
-
-
-
-
-
- void
-Lexinit()
-/* Function: Initialization of lexical analyzer:
- * initializes the hashtable,
- * initializes nextc, nexttok if finptr != 0
- */
-{ register int c;
-
- for (c = hshsize; 0 <= --c; ) {
- hshtab[c] = 0;
- }
-
- nerror = 0;
- if (finptr) {
- foutptr = 0;
- hshenter = true;
- ignored_phrases = false;
- rcsline = 1;
- bufrealloc(&tokbuf, 2);
- Iget_(finptr, nextc)
- nextlex(); /*initial token*/
- }
-}
-
-
-
-
-
-
-
- void
-nextlex()
-
-/* Function: Reads the next token and sets nexttok to the next token code.
- * Only if hshenter is set, a revision number is entered into the
- * hashtable and a pointer to it is placed into nexthsh.
- * This is useful for avoiding that dates are placed into the hashtable.
- * For ID's and NUM's, NextString is set to the character string.
- * Assumption: nextc contains the next character.
- */
-{ register c;
- declarecache;
- register FILE *frew;
- register char * sp;
- char const *limit;
- register enum tokens d;
- register RILE *fin;
-
- fin=finptr; frew=foutptr;
- setupcache(fin); cache(fin);
- c = nextc;
-
- for (;;) { switch ((d = ctab[c])) {
-
- default:
- fatserror("unknown character `%c'", c);
- /*NOTREACHED*/
-
- case NEWLN:
- ++rcsline;
-# ifdef LEXDB
- afputc('\n',stdout);
-# endif
- /* Note: falls into next case */
-
- case SPACE:
- GETC_(frew, c)
- continue;
-
- case IDCHAR:
- case LETTER:
- case Letter:
- d = ID;
- /* fall into */
- case DIGIT:
- case PERIOD:
- sp = tokbuf.string;
- limit = sp + tokbuf.size;
- *sp++ = c;
- for (;;) {
- GETC_(frew, c)
- switch (ctab[c]) {
- case IDCHAR:
- case LETTER:
- case Letter:
- d = ID;
- /* fall into */
- case DIGIT:
- case PERIOD:
- *sp++ = c;
- if (limit <= sp)
- sp = bufenlarge(&tokbuf, &limit);
- continue;
-
- default:
- break;
- }
- break;
- }
- *sp = 0;
- if (d == DIGIT || d == PERIOD) {
- d = NUM;
- if (hshenter) {
- lookup(tokbuf.string);
- break;
- }
- }
- NextString = fstr_save(tokbuf.string);
- break;
-
- case SBEGIN: /* long string */
- d = STRING;
- /* note: only the initial SBEGIN has been read*/
- /* read the string, and reset nextc afterwards*/
- break;
-
- case COLON:
- case SEMI:
- GETC_(frew, c)
- break;
- } break; }
- nextc = c;
- nexttok = d;
- uncache(fin);
-}
-
- int
-eoflex()
-/*
- * Yield true if we look ahead to the end of the input, false otherwise.
- * nextc becomes undefined at end of file.
- */
-{
- register int c;
- declarecache;
- register FILE *fout;
- register RILE *fin;
-
- c = nextc;
- fin = finptr;
- fout = foutptr;
- setupcache(fin); cache(fin);
-
- for (;;) {
- switch (ctab[c]) {
- default:
- nextc = c;
- uncache(fin);
- return false;
-
- case NEWLN:
- ++rcsline;
- /* fall into */
- case SPACE:
- cachegeteof_(c, {uncache(fin);return true;})
- break;
- }
- if (fout)
- aputc_(c, fout)
- }
-}
-
-
-int getlex(token)
-enum tokens token;
-/* Function: Checks if nexttok is the same as token. If so,
- * advances the input by calling nextlex and returns true.
- * otherwise returns false.
- * Doesn't work for strings and keywords; loses the character string for ids.
- */
-{
- if (nexttok==token) {
- nextlex();
- return(true);
- } else return(false);
-}
-
- int
-getkeyopt(key)
- char const *key;
-/* Function: If the current token is a keyword identical to key,
- * advances the input by calling nextlex and returns true;
- * otherwise returns false.
- */
-{
- if (nexttok==ID && strcmp(key,NextString) == 0) {
- /* match found */
- ffree1(NextString);
- nextlex();
- return(true);
- }
- return(false);
-}
-
- void
-getkey(key)
- char const *key;
-/* Check that the current input token is a keyword identical to key,
- * and advance the input by calling nextlex.
- */
-{
- if (!getkeyopt(key))
- fatserror("missing '%s' keyword", key);
-}
-
- void
-getkeystring(key)
- char const *key;
-/* Check that the current input token is a keyword identical to key,
- * and advance the input by calling nextlex; then look ahead for a string.
- */
-{
- getkey(key);
- if (nexttok != STRING)
- fatserror("missing string after '%s' keyword", key);
-}
-
-
- char const *
-getid()
-/* Function: Checks if nexttok is an identifier. If so,
- * advances the input by calling nextlex and returns a pointer
- * to the identifier; otherwise returns 0.
- * Treats keywords as identifiers.
- */
-{
- register char const *name;
- if (nexttok==ID) {
- name = NextString;
- nextlex();
- return name;
- } else
- return 0;
-}
-
-
-struct hshentry * getnum()
-/* Function: Checks if nexttok is a number. If so,
- * advances the input by calling nextlex and returns a pointer
- * to the hashtable entry. Otherwise returns 0.
- * Doesn't work if hshenter is false.
- */
-{
- register struct hshentry * num;
- if (nexttok==NUM) {
- num=nexthsh;
- nextlex();
- return num;
- } else
- return 0;
-}
-
- struct cbuf
-getphrases(key)
- char const *key;
-/*
-* Get a series of phrases that do not start with KEY. Yield resulting buffer.
-* Stop when the next phrase starts with a token that is not an identifier,
-* or is KEY. Copy input to foutptr if it is set. Unlike ignorephrases(),
-* this routine assumes nextlex() has already been invoked before we start.
-*/
-{
- declarecache;
- register int c;
- register char const *kn;
- struct cbuf r;
- register RILE *fin;
- register FILE *frew;
-# if large_memory
-# define savech_(c) ;
-# else
- register char *p;
- char const *limit;
- struct buf b;
-# define savech_(c) {if (limit<=p)p=bufenlarge(&b,&limit); *p++ =(c);}
-# endif
-
- if (nexttok!=ID || strcmp(NextString,key) == 0)
- clear_buf(&r);
- else {
- warnignore();
- fin = finptr;
- frew = foutptr;
- setupcache(fin); cache(fin);
-# if large_memory
- r.string = (char const*)cacheptr() - strlen(NextString) - 1;
-# else
- bufautobegin(&b);
- bufscpy(&b, NextString);
- p = b.string + strlen(b.string);
- limit = b.string + b.size;
-# endif
- ffree1(NextString);
- c = nextc;
- for (;;) {
- for (;;) {
- savech_(c)
- switch (ctab[c]) {
- default:
- fatserror("unknown character `%c'", c);
- /*NOTREACHED*/
- case NEWLN:
- ++rcsline;
- /* fall into */
- case COLON: case DIGIT: case LETTER: case Letter:
- case PERIOD: case SPACE:
- GETC_(frew, c)
- continue;
- case SBEGIN: /* long string */
- for (;;) {
- for (;;) {
- GETC_(frew, c)
- savech_(c)
- switch (c) {
- case '\n':
- ++rcsline;
- /* fall into */
- default:
- continue;
-
- case SDELIM:
- break;
- }
- break;
- }
- GETC_(frew, c)
- if (c != SDELIM)
- break;
- savech_(c)
- }
- continue;
- case SEMI:
- cacheget_(c)
- if (ctab[c] == NEWLN) {
- if (frew)
- aputc_(c, frew)
- ++rcsline;
- savech_(c)
- cacheget_(c)
- }
-# if large_memory
- r.size = (char const*)cacheptr() - 1 - r.string;
-# endif
- for (;;) {
- switch (ctab[c]) {
- case NEWLN:
- ++rcsline;
- /* fall into */
- case SPACE:
- cacheget_(c)
- continue;
-
- default: break;
- }
- break;
- }
- if (frew)
- aputc_(c, frew)
- break;
- }
- break;
- }
- if (ctab[c] == Letter) {
- for (kn = key; c && *kn==c; kn++)
- GETC_(frew, c)
- if (!*kn)
- switch (ctab[c]) {
- case DIGIT: case LETTER: case Letter:
- case IDCHAR: case PERIOD:
- break;
- default:
- nextc = c;
- NextString = fstr_save(key);
- nexttok = ID;
- uncache(fin);
- goto returnit;
- }
-# if !large_memory
- {
- register char const *ki;
- for (ki=key; ki<kn; )
- savech_(*ki++)
- }
-# endif
- } else {
- nextc = c;
- uncache(fin);
- nextlex();
- break;
- }
- }
- returnit:;
-# if !large_memory
- return bufremember(&b, (size_t)(p - b.string));
-# endif
- }
- return r;
-}
-
-
- void
-readstring()
-/* skip over characters until terminating single SDELIM */
-/* If foutptr is set, copy every character read to foutptr. */
-/* Does not advance nextlex at the end. */
-{ register c;
- declarecache;
- register FILE *frew;
- register RILE *fin;
- fin=finptr; frew=foutptr;
- setupcache(fin); cache(fin);
- for (;;) {
- GETC_(frew, c)
- switch (c) {
- case '\n':
- ++rcsline;
- break;
-
- case SDELIM:
- GETC_(frew, c)
- if (c != SDELIM) {
- /* end of string */
- nextc = c;
- uncache(fin);
- return;
- }
- break;
- }
- }
-}
-
-
- void
-printstring()
-/* Function: copy a string to stdout, until terminated with a single SDELIM.
- * Does not advance nextlex at the end.
- */
-{
- register c;
- declarecache;
- register FILE *fout;
- register RILE *fin;
- fin=finptr;
- fout = stdout;
- setupcache(fin); cache(fin);
- for (;;) {
- cacheget_(c)
- switch (c) {
- case '\n':
- ++rcsline;
- break;
- case SDELIM:
- cacheget_(c)
- if (c != SDELIM) {
- nextc=c;
- uncache(fin);
- return;
- }
- break;
- }
- aputc_(c,fout)
- }
-}
-
-
-
- struct cbuf
-savestring(target)
- struct buf *target;
-/* Copies a string terminated with SDELIM from file finptr to buffer target.
- * Double SDELIM is replaced with SDELIM.
- * If foutptr is set, the string is also copied unchanged to foutptr.
- * Does not advance nextlex at the end.
- * Yield a copy of *TARGET, except with exact length.
- */
-{
- register c;
- declarecache;
- register FILE *frew;
- register char *tp;
- register RILE *fin;
- char const *limit;
- struct cbuf r;
-
- fin=finptr; frew=foutptr;
- setupcache(fin); cache(fin);
- tp = target->string; limit = tp + target->size;
- for (;;) {
- GETC_(frew, c)
- switch (c) {
- case '\n':
- ++rcsline;
- break;
- case SDELIM:
- GETC_(frew, c)
- if (c != SDELIM) {
- /* end of string */
- nextc=c;
- r.string = target->string;
- r.size = tp - r.string;
- uncache(fin);
- return r;
- }
- break;
- }
- if (tp == limit)
- tp = bufenlarge(target, &limit);
- *tp++ = c;
- }
-}
-
-
- static char *
-checkidentifier(id, delimiter, dotok)
- register char *id;
- int delimiter;
- register int dotok;
-/* Function: check whether the string starting at id is an */
-/* identifier and return a pointer to the delimiter*/
-/* after the identifier. White space, delim and 0 */
-/* are legal delimiters. Aborts the program if not*/
-/* a legal identifier. Useful for checking commands*/
-/* If !delim, the only delimiter is 0. */
-/* Allow '.' in identifier only if DOTOK is set. */
-{
- register char *temp;
- register char c;
- register char delim = delimiter;
- int isid = false;
-
- temp = id;
- for (;; id++) {
- switch (ctab[(unsigned char)(c = *id)]) {
- case IDCHAR:
- case LETTER:
- case Letter:
- isid = true;
- continue;
-
- case DIGIT:
- continue;
-
- case PERIOD:
- if (dotok)
- continue;
- break;
-
- default:
- break;
- }
- break;
- }
- if ( ! isid
- || (c && (!delim || (c!=delim && c!=' ' && c!='\t' && c!='\n')))
- ) {
- /* append \0 to end of id before error message */
- while ((c = *id) && c!=' ' && c!='\t' && c!='\n' && c!=delim)
- id++;
- *id = '\0';
- faterror("invalid %s `%s'",
- dotok ? "identifier" : "symbol", temp
- );
- }
- return id;
-}
-
- char *
-checkid(id, delimiter)
- char *id;
- int delimiter;
-{
- return checkidentifier(id, delimiter, true);
-}
-
- char *
-checksym(sym, delimiter)
- char *sym;
- int delimiter;
-{
- return checkidentifier(sym, delimiter, false);
-}
-
- void
-checksid(id)
- char *id;
-/* Check whether the string ID is an identifier. */
-{
- VOID checkid(id, 0);
-}
-
- void
-checkssym(sym)
- char *sym;
-{
- VOID checksym(sym, 0);
-}
-
-
-#if !large_memory
-# define Iclose(f) fclose(f)
-#else
-# if !maps_memory
- static int Iclose P((RILE *));
- static int
- Iclose(f)
- register RILE *f;
- {
- tfree(f->base);
- f->base = 0;
- return fclose(f->stream);
- }
-# else
- static int Iclose P((RILE *));
- static int
- Iclose(f)
- register RILE *f;
- {
- (* f->deallocate) (f);
- f->base = 0;
- return close(f->fd);
- }
-
-# if has_map_fd
- static void map_fd_deallocate P((RILE *));
- static void
- map_fd_deallocate(f)
- register RILE *f;
- {
- if (vm_deallocate(
- task_self(),
- (vm_address_t) f->base,
- (vm_size_t) (f->lim - f->base)
- ) != KERN_SUCCESS)
- efaterror("vm_deallocate");
- }
-# endif
-# if has_mmap
- static void mmap_deallocate P((RILE *));
- static void
- mmap_deallocate(f)
- register RILE *f;
- {
- if (munmap((char *) f->base, (size_t) (f->lim - f->base)) != 0)
- efaterror("munmap");
- }
-# endif
- static void read_deallocate P((RILE *));
- static void
- read_deallocate(f)
- RILE *f;
- {
- tfree(f->base);
- }
-
- static void nothing_to_deallocate P((RILE *));
- static void
- nothing_to_deallocate(f)
- RILE *f;
- {
- }
-# endif
-#endif
-
-
-#if large_memory && maps_memory
- static RILE *fd2_RILE P((int,char const*,struct stat*));
- static RILE *
-fd2_RILE(fd, name, status)
-#else
- static RILE *fd2RILE P((int,char const*,char const*,struct stat*));
- static RILE *
-fd2RILE(fd, name, type, status)
- char const *type;
-#endif
- int fd;
- char const *name;
- register struct stat *status;
-{
- struct stat st;
-
- if (!status)
- status = &st;
- if (fstat(fd, status) != 0)
- efaterror(name);
- if (!S_ISREG(status->st_mode)) {
- error("`%s' is not a regular file", name);
- VOID close(fd);
- errno = EINVAL;
- return 0;
- } else {
-
-# if !(large_memory && maps_memory)
- FILE *stream;
- if (!(stream = fdopen(fd, type)))
- efaterror(name);
-# endif
-
-# if !large_memory
- return stream;
-# else
-# define RILES 3
- {
- static RILE rilebuf[RILES];
-
- register RILE *f;
- size_t s = status->st_size;
-
- if (s != status->st_size)
- faterror("%s: too large", name);
- for (f = rilebuf; f->base; f++)
- if (f == rilebuf+RILES)
- faterror("too many RILEs");
-# if maps_memory
- f->deallocate = nothing_to_deallocate;
-# endif
- if (!s) {
- static unsigned char nothing;
- f->base = &nothing; /* Any nonzero address will do. */
- } else {
- f->base = 0;
-# if has_map_fd
- map_fd(
- fd, (vm_offset_t)0, (vm_address_t*) &f->base,
- TRUE, (vm_size_t)s
- );
- f->deallocate = map_fd_deallocate;
-# endif
-# if has_mmap
- if (!f->base) {
- catchmmapints();
- f->base = (unsigned char *) mmap(
- (char *)0, s, PROT_READ, MAP_SHARED,
- fd, (off_t)0
- );
-# ifndef MAP_FAILED
-# define MAP_FAILED (-1)
-# endif
- if (f->base == (unsigned char *) MAP_FAILED)
- f->base = 0;
- else {
-# if has_NFS && mmap_signal
- /*
- * On many hosts, the superuser
- * can mmap an NFS file it can't read.
- * So access the first page now, and print
- * a nice message if a bus error occurs.
- */
- readAccessFilenameBuffer(name, f->base);
-# endif
- }
- f->deallocate = mmap_deallocate;
- }
-# endif
- if (!f->base) {
- f->base = tnalloc(unsigned char, s);
-# if maps_memory
- {
- /*
- * We can't map the file into memory for some reason.
- * Read it into main memory all at once; this is
- * the simplest substitute for memory mapping.
- */
- char *bufptr = (char *) f->base;
- size_t bufsiz = s;
- do {
- ssize_t r = read(fd, bufptr, bufsiz);
- switch (r) {
- case -1:
- efaterror(name);
-
- case 0:
- /* The file must have shrunk! */
- status->st_size = s -= bufsiz;
- bufsiz = 0;
- break;
-
- default:
- bufptr += r;
- bufsiz -= r;
- break;
- }
- } while (bufsiz);
- if (lseek(fd, (off_t)0, SEEK_SET) == -1)
- efaterror(name);
- f->deallocate = read_deallocate;
- }
-# endif
- }
- }
- f->ptr = f->base;
- f->lim = f->base + s;
- f->fd = fd;
-# if !maps_memory
- f->readlim = f->base;
- f->stream = stream;
-# endif
- if_advise_access(s, f, MADV_SEQUENTIAL);
- return f;
- }
-# endif
- }
-}
-
-#if !maps_memory && large_memory
- int
-Igetmore(f)
- register RILE *f;
-{
- register fread_type r;
- register size_t s = f->lim - f->readlim;
-
- if (BUFSIZ < s)
- s = BUFSIZ;
- if (!(r = Fread(f->readlim, sizeof(*f->readlim), s, f->stream))) {
- testIerror(f->stream);
- f->lim = f->readlim; /* The file might have shrunk! */
- return 0;
- }
- f->readlim += r;
- return 1;
-}
-#endif
-
-#if has_madvise && has_mmap && large_memory
- void
-advise_access(f, advice)
- register RILE *f;
- int advice;
-{
- if (f->deallocate == mmap_deallocate)
- VOID madvise((char *)f->base, (size_t)(f->lim - f->base), advice);
- /* Don't worry if madvise fails; it's only advisory. */
-}
-#endif
-
- RILE *
-#if large_memory && maps_memory
-I_open(name, status)
-#else
-Iopen(name, type, status)
- char const *type;
-#endif
- char const *name;
- struct stat *status;
-/* Open NAME for reading, yield its descriptor, and set *STATUS. */
-{
- int fd = fdSafer(open(name, O_RDONLY
-# if OPEN_O_BINARY
- | (strchr(type,'b') ? OPEN_O_BINARY : 0)
-# endif
- ));
-
- if (fd < 0)
- return 0;
-# if large_memory && maps_memory
- return fd2_RILE(fd, name, status);
-# else
- return fd2RILE(fd, name, type, status);
-# endif
-}
-
-
-static int Oerrloop;
-
- void
-Oerror()
-{
- if (Oerrloop)
- exiterr();
- Oerrloop = true;
- efaterror("output error");
-}
-
-void Ieof() { fatserror("unexpected end of file"); }
-void Ierror() { efaterror("input error"); }
-void testIerror(f) FILE *f; { if (ferror(f)) Ierror(); }
-void testOerror(o) FILE *o; { if (ferror(o)) Oerror(); }
-
-void Ifclose(f) RILE *f; { if (f && Iclose(f)!=0) Ierror(); }
-void Ofclose(f) FILE *f; { if (f && fclose(f)!=0) Oerror(); }
-void Izclose(p) RILE **p; { Ifclose(*p); *p = 0; }
-void Ozclose(p) FILE **p; { Ofclose(*p); *p = 0; }
-
-#if !large_memory
- void
-testIeof(f)
- FILE *f;
-{
- testIerror(f);
- if (feof(f))
- Ieof();
-}
-void Irewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Ierror(); }
-#endif
-
-void Orewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Oerror(); }
-
-void aflush(f) FILE *f; { if (fflush(f) != 0) Oerror(); }
-void eflush() { if (fflush(stderr)!=0 && !Oerrloop) Oerror(); }
-void oflush()
-{
- if (fflush(workstdout ? workstdout : stdout) != 0 && !Oerrloop)
- Oerror();
-}
-
- void
-fatcleanup(already_newline)
- int already_newline;
-{
- VOID fprintf(stderr, already_newline+"\n%s aborted\n", cmdid);
- exiterr();
-}
-
- static void
-startsay(s, t)
- const char *s, *t;
-{
- oflush();
- if (s)
- aprintf(stderr, "%s: %s: %s", cmdid, s, t);
- else
- aprintf(stderr, "%s: %s", cmdid, t);
-}
-
- static void
-fatsay(s)
- char const *s;
-{
- startsay(s, "");
-}
-
- static void
-errsay(s)
- char const *s;
-{
- fatsay(s);
- nerror++;
-}
-
- static void
-warnsay(s)
- char const *s;
-{
- startsay(s, "warning: ");
-}
-
-void eerror(s) char const *s; { enerror(errno,s); }
-
- void
-enerror(e,s)
- int e;
- char const *s;
-{
- errsay((char const*)0);
- errno = e;
- perror(s);
- eflush();
-}
-
-void efaterror(s) char const *s; { enfaterror(errno,s); }
-
- void
-enfaterror(e,s)
- int e;
- char const *s;
-{
- fatsay((char const*)0);
- errno = e;
- perror(s);
- fatcleanup(true);
-}
-
-#if has_prototypes
- void
-error(char const *format,...)
-#else
- /*VARARGS1*/ void error(format, va_alist) char const *format; va_dcl
-#endif
-/* non-fatal error */
-{
- va_list args;
- errsay((char const*)0);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- afputc('\n',stderr);
- eflush();
-}
-
-#if has_prototypes
- void
-rcserror(char const *format,...)
-#else
- /*VARARGS1*/ void rcserror(format, va_alist) char const *format; va_dcl
-#endif
-/* non-fatal RCS file error */
-{
- va_list args;
- errsay(RCSname);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- afputc('\n',stderr);
- eflush();
-}
-
-#if has_prototypes
- void
-workerror(char const *format,...)
-#else
- /*VARARGS1*/ void workerror(format, va_alist) char const *format; va_dcl
-#endif
-/* non-fatal working file error */
-{
- va_list args;
- errsay(workname);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- afputc('\n',stderr);
- eflush();
-}
-
-#if has_prototypes
- void
-fatserror(char const *format,...)
-#else
- /*VARARGS1*/ void
- fatserror(format, va_alist) char const *format; va_dcl
-#endif
-/* fatal RCS file syntax error */
-{
- va_list args;
- oflush();
- VOID fprintf(stderr, "%s: %s:%ld: ", cmdid, RCSname, rcsline);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- fatcleanup(false);
-}
-
-#if has_prototypes
- void
-faterror(char const *format,...)
-#else
- /*VARARGS1*/ void faterror(format, va_alist)
- char const *format; va_dcl
-#endif
-/* fatal error, terminates program after cleanup */
-{
- va_list args;
- fatsay((char const*)0);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- fatcleanup(false);
-}
-
-#if has_prototypes
- void
-rcsfaterror(char const *format,...)
-#else
- /*VARARGS1*/ void rcsfaterror(format, va_alist)
- char const *format; va_dcl
-#endif
-/* fatal RCS file error, terminates program after cleanup */
-{
- va_list args;
- fatsay(RCSname);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- fatcleanup(false);
-}
-
-#if has_prototypes
- void
-warn(char const *format,...)
-#else
- /*VARARGS1*/ void warn(format, va_alist) char const *format; va_dcl
-#endif
-/* warning */
-{
- va_list args;
- if (!quietflag) {
- warnsay((char *)0);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- afputc('\n', stderr);
- eflush();
- }
-}
-
-#if has_prototypes
- void
-rcswarn(char const *format,...)
-#else
- /*VARARGS1*/ void rcswarn(format, va_alist) char const *format; va_dcl
-#endif
-/* RCS file warning */
-{
- va_list args;
- if (!quietflag) {
- warnsay(RCSname);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- afputc('\n', stderr);
- eflush();
- }
-}
-
-#if has_prototypes
- void
-workwarn(char const *format,...)
-#else
- /*VARARGS1*/ void workwarn(format, va_alist) char const *format; va_dcl
-#endif
-/* working file warning */
-{
- va_list args;
- if (!quietflag) {
- warnsay(workname);
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- afputc('\n', stderr);
- eflush();
- }
-}
-
- void
-redefined(c)
- int c;
-{
- warn("redefinition of -%c option", c);
-}
-
-#if has_prototypes
- void
-diagnose(char const *format,...)
-#else
- /*VARARGS1*/ void diagnose(format, va_alist) char const *format; va_dcl
-#endif
-/* prints a diagnostic message */
-/* Unlike the other routines, it does not append a newline. */
-/* This lets some callers suppress the newline, and is faster */
-/* in implementations that flush stderr just at the end of each printf. */
-{
- va_list args;
- if (!quietflag) {
- oflush();
- vararg_start(args, format);
- fvfprintf(stderr, format, args);
- va_end(args);
- eflush();
- }
-}
-
-
-
- void
-afputc(c, f)
-/* afputc(c,f); acts like aputc_(c,f) but is smaller and slower. */
- int c;
- register FILE *f;
-{
- aputc_(c,f)
-}
-
-
- void
-aputs(s, iop)
- char const *s;
- FILE *iop;
-/* Function: Put string s on file iop, abort on error.
- */
-{
-#if has_fputs
- if (fputs(s, iop) < 0)
- Oerror();
-#else
- awrite(s, strlen(s), iop);
-#endif
-}
-
-
-
- void
-#if has_prototypes
-fvfprintf(FILE *stream, char const *format, va_list args)
-#else
- fvfprintf(stream,format,args) FILE *stream; char *format; va_list args;
-#endif
-/* like vfprintf, except abort program on error */
-{
-#if has_vfprintf
- if (vfprintf(stream, format, args) < 0)
- Oerror();
-#else
-# if has__doprintf
- _doprintf(stream, format, args);
-# else
-# if has__doprnt
- _doprnt(format, args, stream);
-# else
- int *a = (int *)args;
- VOID fprintf(stream, format,
- a[0], a[1], a[2], a[3], a[4],
- a[5], a[6], a[7], a[8], a[9]
- );
-# endif
-# endif
- if (ferror(stream))
- Oerror();
-#endif
-}
-
-#if has_prototypes
- void
-aprintf(FILE *iop, char const *fmt, ...)
-#else
- /*VARARGS2*/ void
-aprintf(iop, fmt, va_alist)
-FILE *iop;
-char const *fmt;
-va_dcl
-#endif
-/* Function: formatted output. Same as fprintf in stdio,
- * but aborts program on error
- */
-{
- va_list ap;
- vararg_start(ap, fmt);
- fvfprintf(iop, fmt, ap);
- va_end(ap);
-}
-
-
-
-#ifdef LEXDB
-/* test program reading a stream of lexemes and printing the tokens.
- */
-
-
-
- int
-main(argc,argv)
-int argc; char * argv[];
-{
- cmdid="lextest";
- if (argc<2) {
- aputs("No input file\n",stderr);
- exitmain(EXIT_FAILURE);
- }
- if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) {
- faterror("can't open input file %s",argv[1]);
- }
- Lexinit();
- while (!eoflex()) {
- switch (nexttok) {
-
- case ID:
- VOID printf("ID: %s",NextString);
- break;
-
- case NUM:
- if (hshenter)
- VOID printf("NUM: %s, index: %d",nexthsh->num, nexthsh-hshtab);
- else
- VOID printf("NUM, unentered: %s",NextString);
- hshenter = !hshenter; /*alternate between dates and numbers*/
- break;
-
- case COLON:
- VOID printf("COLON"); break;
-
- case SEMI:
- VOID printf("SEMI"); break;
-
- case STRING:
- readstring();
- VOID printf("STRING"); break;
-
- case UNKN:
- VOID printf("UNKN"); break;
-
- default:
- VOID printf("DEFAULT"); break;
- }
- VOID printf(" | ");
- nextlex();
- }
- exitmain(EXIT_SUCCESS);
-}
-
-void exiterr() { _exit(EXIT_FAILURE); }
-
-
-#endif
diff --git a/gnu/usr.bin/rcs/lib/rcsmap.c b/gnu/usr.bin/rcs/lib/rcsmap.c
deleted file mode 100644
index 89fb08d..0000000
--- a/gnu/usr.bin/rcs/lib/rcsmap.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/* RCS map of character types */
-
-/* Copyright (C) 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1995 by Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#include "rcsbase.h"
-
-libId(mapId, "$FreeBSD$")
-
-/* map of character types */
-/* ISO 8859/1 (Latin-1) */
-enum tokens const ctab[] = {
- UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN,
- SPACE, SPACE, NEWLN, SPACE, SPACE, SPACE, UNKN, UNKN,
- UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN,
- UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN,
- SPACE, IDCHAR, IDCHAR, IDCHAR, DELIM, IDCHAR, IDCHAR, IDCHAR,
- IDCHAR, IDCHAR, IDCHAR, IDCHAR, DELIM, IDCHAR, PERIOD, IDCHAR,
- DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT, DIGIT,
- DIGIT, DIGIT, COLON, SEMI, IDCHAR, IDCHAR, IDCHAR, IDCHAR,
- SBEGIN, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR,
- IDCHAR, Letter, Letter, Letter, Letter, Letter, Letter, Letter,
- Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter,
- Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter,
- Letter, Letter, Letter, IDCHAR, IDCHAR, IDCHAR, IDCHAR, UNKN,
- UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN,
- UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN,
- UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN,
- UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN, UNKN,
- IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR,
- IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR,
- IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR,
- IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR, IDCHAR,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, IDCHAR,
- LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, LETTER, Letter,
- Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter,
- Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter,
- Letter, Letter, Letter, Letter, Letter, Letter, Letter, IDCHAR,
- Letter, Letter, Letter, Letter, Letter, Letter, Letter, Letter
-};
diff --git a/gnu/usr.bin/rcs/lib/rcsrev.c b/gnu/usr.bin/rcs/lib/rcsrev.c
deleted file mode 100644
index 12c6c43..0000000
--- a/gnu/usr.bin/rcs/lib/rcsrev.c
+++ /dev/null
@@ -1,911 +0,0 @@
-/* Handle RCS revision numbers. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.10 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.9 1995/06/01 16:23:43 eggert
- * (cmpdate, normalizeyear): New functions work around MKS RCS incompatibility.
- * (cmpnum, compartial): s[d] -> *(s+d) to work around Cray compiler bug.
- * (genrevs, genbranch): cmpnum -> cmpdate
- *
- * Revision 5.8 1994/03/17 14:05:48 eggert
- * Remove lint.
- *
- * Revision 5.7 1993/11/09 17:40:15 eggert
- * Fix format string typos.
- *
- * Revision 5.6 1993/11/03 17:42:27 eggert
- * Revision number `.N' now stands for `D.N', where D is the default branch.
- * Add -z. Improve quality of diagnostics. Add `namedrev' for Name support.
- *
- * Revision 5.5 1992/07/28 16:12:44 eggert
- * Identifiers may now start with a digit. Avoid `unsigned'.
- *
- * Revision 5.4 1992/01/06 02:42:34 eggert
- * while (E) ; -> while (E) continue;
- *
- * Revision 5.3 1991/08/19 03:13:55 eggert
- * Add `-r$', `-rB.'. Remove botches like `<now>' from messages. Tune.
- *
- * Revision 5.2 1991/04/21 11:58:28 eggert
- * Add tiprev().
- *
- * Revision 5.1 1991/02/25 07:12:43 eggert
- * Avoid overflow when comparing revision numbers.
- *
- * Revision 5.0 1990/08/22 08:13:43 eggert
- * Remove compile-time limits; use malloc instead.
- * Ansify and Posixate. Tune.
- * Remove possibility of an internal error. Remove lint.
- *
- * Revision 4.5 89/05/01 15:13:22 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.4 87/12/18 11:45:22 narten
- * more lint cleanups. Also, the NOTREACHED comment is no longer necessary,
- * since there's now a return value there with a value. (Guy Harris)
- *
- * Revision 4.3 87/10/18 10:38:42 narten
- * Updating version numbers. Changes relative to version 1.1 actually
- * relative to 4.1
- *
- * Revision 1.3 87/09/24 14:00:37 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:37 jenkins
- * Port to suns
- *
- * Revision 4.1 83/03/25 21:10:45 wft
- * Only changed $Header to $Id.
- *
- * Revision 3.4 82/12/04 13:24:08 wft
- * Replaced getdelta() with gettree().
- *
- * Revision 3.3 82/11/28 21:33:15 wft
- * fixed compartial() and compnum() for nil-parameters; fixed nils
- * in error messages. Testprogram output shortenend.
- *
- * Revision 3.2 82/10/18 21:19:47 wft
- * renamed compnum->cmpnum, compnumfld->cmpnumfld,
- * numericrevno->numricrevno.
- *
- * Revision 3.1 82/10/11 19:46:09 wft
- * changed expandsym() to check for source==nil; returns zero length string
- * in that case.
- */
-
-#include "rcsbase.h"
-
-libId(revId, "$FreeBSD$")
-
-static char const *branchtip P((char const*));
-static char const *lookupsym P((char const*));
-static char const *normalizeyear P((char const*,char[5]));
-static struct hshentry *genbranch P((struct hshentry const*,char const*,int,char const*,char const*,char const*,struct hshentries**));
-static void absent P((char const*,int));
-static void cantfindbranch P((char const*,char const[datesize],char const*,char const*));
-static void store1 P((struct hshentries***,struct hshentry*));
-
-
-
- int
-countnumflds(s)
- char const *s;
-/* Given a pointer s to a dotted number (date or revision number),
- * countnumflds returns the number of digitfields in s.
- */
-{
- register char const *sp;
- register int count;
- if (!(sp=s) || !*sp)
- return 0;
- count = 1;
- do {
- if (*sp++ == '.') count++;
- } while (*sp);
- return(count);
-}
-
- void
-getbranchno(revno,branchno)
- char const *revno;
- struct buf *branchno;
-/* Given a revision number revno, getbranchno copies the number of the branch
- * on which revno is into branchno. If revno itself is a branch number,
- * it is copied unchanged.
- */
-{
- register int numflds;
- register char *tp;
-
- bufscpy(branchno, revno);
- numflds=countnumflds(revno);
- if (!(numflds & 1)) {
- tp = branchno->string;
- while (--numflds)
- while (*tp++ != '.')
- continue;
- *(tp-1)='\0';
- }
-}
-
-
-
-int cmpnum(num1, num2)
- char const *num1, *num2;
-/* compares the two dotted numbers num1 and num2 lexicographically
- * by field. Individual fields are compared numerically.
- * returns <0, 0, >0 if num1<num2, num1==num2, and num1>num2, resp.
- * omitted fields are assumed to be higher than the existing ones.
-*/
-{
- register char const *s1, *s2;
- register size_t d1, d2;
- register int r;
-
- s1 = num1 ? num1 : "";
- s2 = num2 ? num2 : "";
-
- for (;;) {
- /* Give precedence to shorter one. */
- if (!*s1)
- return (unsigned char)*s2;
- if (!*s2)
- return -1;
-
- /* Strip leading zeros, then find number of digits. */
- while (*s1=='0') ++s1;
- while (*s2=='0') ++s2;
- for (d1=0; isdigit(*(s1+d1)); d1++) continue;
- for (d2=0; isdigit(*(s2+d2)); d2++) continue;
-
- /* Do not convert to integer; it might overflow! */
- if (d1 != d2)
- return d1<d2 ? -1 : 1;
- if ((r = memcmp(s1, s2, d1)))
- return r;
- s1 += d1;
- s2 += d1;
-
- /* skip '.' */
- if (*s1) s1++;
- if (*s2) s2++;
- }
-}
-
-
-
-int cmpnumfld(num1, num2, fld)
- char const *num1, *num2;
- int fld;
-/* Compare the two dotted numbers at field fld.
- * num1 and num2 must have at least fld fields.
- * fld must be positive.
-*/
-{
- register char const *s1, *s2;
- register size_t d1, d2;
-
- s1 = num1;
- s2 = num2;
- /* skip fld-1 fields */
- while (--fld) {
- while (*s1++ != '.')
- continue;
- while (*s2++ != '.')
- continue;
- }
- /* Now s1 and s2 point to the beginning of the respective fields */
- while (*s1=='0') ++s1; for (d1=0; isdigit(*(s1+d1)); d1++) continue;
- while (*s2=='0') ++s2; for (d2=0; isdigit(*(s2+d2)); d2++) continue;
-
- return d1<d2 ? -1 : d1==d2 ? memcmp(s1,s2,d1) : 1;
-}
-
-
- int
-cmpdate(d1, d2)
- char const *d1, *d2;
-/*
-* Compare the two dates. This is just like cmpnum,
-* except that for compatibility with old versions of RCS,
-* 1900 is added to dates with two-digit years.
-*/
-{
- char year1[5], year2[5];
- int r = cmpnumfld(normalizeyear(d1,year1), normalizeyear(d2,year2), 1);
-
- if (r)
- return r;
- else {
- while (isdigit(*d1)) d1++; d1 += *d1=='.';
- while (isdigit(*d2)) d2++; d2 += *d2=='.';
- return cmpnum(d1, d2);
- }
-}
-
- static char const *
-normalizeyear(date, year)
- char const *date;
- char year[5];
-{
- if (isdigit(date[0]) && isdigit(date[1]) && !isdigit(date[2])) {
- year[0] = '1';
- year[1] = '9';
- year[2] = date[0];
- year[3] = date[1];
- year[4] = 0;
- return year;
- } else
- return date;
-}
-
-
- static void
-cantfindbranch(revno, date, author, state)
- char const *revno, date[datesize], *author, *state;
-{
- char datebuf[datesize + zonelenmax];
-
- rcserror("No revision on branch %s has%s%s%s%s%s%s.",
- revno,
- date ? " a date before " : "",
- date ? date2str(date,datebuf) : "",
- author ? " and author "+(date?0:4) : "",
- author ? author : "",
- state ? " and state "+(date||author?0:4) : "",
- state ? state : ""
- );
-}
-
- static void
-absent(revno, field)
- char const *revno;
- int field;
-{
- struct buf t;
- bufautobegin(&t);
- rcserror("%s %s absent", field&1?"revision":"branch",
- partialno(&t,revno,field)
- );
- bufautoend(&t);
-}
-
-
- int
-compartial(num1, num2, length)
- char const *num1, *num2;
- int length;
-
-/* compare the first "length" fields of two dot numbers;
- the omitted field is considered to be larger than any number */
-/* restriction: at least one number has length or more fields */
-
-{
- register char const *s1, *s2;
- register size_t d1, d2;
- register int r;
-
- s1 = num1; s2 = num2;
- if (!s1) return 1;
- if (!s2) return -1;
-
- for (;;) {
- if (!*s1) return 1;
- if (!*s2) return -1;
-
- while (*s1=='0') ++s1; for (d1=0; isdigit(*(s1+d1)); d1++) continue;
- while (*s2=='0') ++s2; for (d2=0; isdigit(*(s2+d2)); d2++) continue;
-
- if (d1 != d2)
- return d1<d2 ? -1 : 1;
- if ((r = memcmp(s1, s2, d1)))
- return r;
- if (!--length)
- return 0;
-
- s1 += d1;
- s2 += d1;
-
- if (*s1 == '.') s1++;
- if (*s2 == '.') s2++;
- }
-}
-
-
-char * partialno(rev1,rev2,length)
- struct buf *rev1;
- char const *rev2;
- register int length;
-/* Function: Copies length fields of revision number rev2 into rev1.
- * Return rev1's string.
- */
-{
- register char *r1;
-
- bufscpy(rev1, rev2);
- r1 = rev1->string;
- while (length) {
- while (*r1!='.' && *r1)
- ++r1;
- ++r1;
- length--;
- }
- /* eliminate last '.'*/
- *(r1-1)='\0';
- return rev1->string;
-}
-
-
-
-
- static void
-store1(store, next)
- struct hshentries ***store;
- struct hshentry *next;
-/*
- * Allocate a new list node that addresses NEXT.
- * Append it to the list that **STORE is the end pointer of.
- */
-{
- register struct hshentries *p;
-
- p = ftalloc(struct hshentries);
- p->first = next;
- **store = p;
- *store = &p->rest;
-}
-
-struct hshentry * genrevs(revno,date,author,state,store)
- char const *revno, *date, *author, *state;
- struct hshentries **store;
-/* Function: finds the deltas needed for reconstructing the
- * revision given by revno, date, author, and state, and stores pointers
- * to these deltas into a list whose starting address is given by store.
- * The last delta (target delta) is returned.
- * If the proper delta could not be found, 0 is returned.
- */
-{
- int length;
- register struct hshentry * next;
- int result;
- char const *branchnum;
- struct buf t;
- char datebuf[datesize + zonelenmax];
-
- bufautobegin(&t);
-
- if (!(next = Head)) {
- rcserror("RCS file empty");
- goto norev;
- }
-
- length = countnumflds(revno);
-
- if (length >= 1) {
- /* at least one field; find branch exactly */
- while ((result=cmpnumfld(revno,next->num,1)) < 0) {
- store1(&store, next);
- next = next->next;
- if (!next) {
- rcserror("branch number %s too low", partialno(&t,revno,1));
- goto norev;
- }
- }
-
- if (result>0) {
- absent(revno, 1);
- goto norev;
- }
- }
- if (length<=1){
- /* pick latest one on given branch */
- branchnum = next->num; /* works even for empty revno*/
- while (next &&
- cmpnumfld(branchnum,next->num,1) == 0 &&
- (
- (date && cmpdate(date,next->date) < 0) ||
- (author && strcmp(author,next->author) != 0) ||
- (state && strcmp(state,next->state) != 0)
- )
- )
- {
- store1(&store, next);
- next=next->next;
- }
- if (!next ||
- (cmpnumfld(branchnum,next->num,1)!=0))/*overshot*/ {
- cantfindbranch(
- length ? revno : partialno(&t,branchnum,1),
- date, author, state
- );
- goto norev;
- } else {
- store1(&store, next);
- }
- *store = 0;
- return next;
- }
-
- /* length >=2 */
- /* find revision; may go low if length==2*/
- while ((result=cmpnumfld(revno,next->num,2)) < 0 &&
- (cmpnumfld(revno,next->num,1)==0) ) {
- store1(&store, next);
- next = next->next;
- if (!next)
- break;
- }
-
- if (!next || cmpnumfld(revno,next->num,1) != 0) {
- rcserror("revision number %s too low", partialno(&t,revno,2));
- goto norev;
- }
- if ((length>2) && (result!=0)) {
- absent(revno, 2);
- goto norev;
- }
-
- /* print last one */
- store1(&store, next);
-
- if (length>2)
- return genbranch(next,revno,length,date,author,state,store);
- else { /* length == 2*/
- if (date && cmpdate(date,next->date)<0) {
- rcserror("Revision %s has date %s.",
- next->num,
- date2str(next->date, datebuf)
- );
- return 0;
- }
- if (author && strcmp(author,next->author)!=0) {
- rcserror("Revision %s has author %s.",
- next->num, next->author
- );
- return 0;
- }
- if (state && strcmp(state,next->state)!=0) {
- rcserror("Revision %s has state %s.",
- next->num,
- next->state ? next->state : "<empty>"
- );
- return 0;
- }
- *store = 0;
- return next;
- }
-
- norev:
- bufautoend(&t);
- return 0;
-}
-
-
-
-
- static struct hshentry *
-genbranch(bpoint, revno, length, date, author, state, store)
- struct hshentry const *bpoint;
- char const *revno;
- int length;
- char const *date, *author, *state;
- struct hshentries **store;
-/* Function: given a branchpoint, a revision number, date, author, and state,
- * genbranch finds the deltas necessary to reconstruct the given revision
- * from the branch point on.
- * Pointers to the found deltas are stored in a list beginning with store.
- * revno must be on a side branch.
- * Return 0 on error.
- */
-{
- int field;
- register struct hshentry * next, * trail;
- register struct branchhead const *bhead;
- int result;
- struct buf t;
- char datebuf[datesize + zonelenmax];
-
- field = 3;
- bhead = bpoint->branches;
-
- do {
- if (!bhead) {
- bufautobegin(&t);
- rcserror("no side branches present for %s",
- partialno(&t,revno,field-1)
- );
- bufautoend(&t);
- return 0;
- }
-
- /*find branch head*/
- /*branches are arranged in increasing order*/
- while (0 < (result=cmpnumfld(revno,bhead->hsh->num,field))) {
- bhead = bhead->nextbranch;
- if (!bhead) {
- bufautobegin(&t);
- rcserror("branch number %s too high",
- partialno(&t,revno,field)
- );
- bufautoend(&t);
- return 0;
- }
- }
-
- if (result<0) {
- absent(revno, field);
- return 0;
- }
-
- next = bhead->hsh;
- if (length==field) {
- /* pick latest one on that branch */
- trail = 0;
- do { if ((!date || cmpdate(date,next->date)>=0) &&
- (!author || strcmp(author,next->author)==0) &&
- (!state || strcmp(state,next->state)==0)
- ) trail = next;
- next=next->next;
- } while (next);
-
- if (!trail) {
- cantfindbranch(revno, date, author, state);
- return 0;
- } else { /* print up to last one suitable */
- next = bhead->hsh;
- while (next!=trail) {
- store1(&store, next);
- next=next->next;
- }
- store1(&store, next);
- }
- *store = 0;
- return next;
- }
-
- /* length > field */
- /* find revision */
- /* check low */
- if (cmpnumfld(revno,next->num,field+1)<0) {
- bufautobegin(&t);
- rcserror("revision number %s too low",
- partialno(&t,revno,field+1)
- );
- bufautoend(&t);
- return 0;
- }
- do {
- store1(&store, next);
- trail = next;
- next = next->next;
- } while (next && cmpnumfld(revno,next->num,field+1)>=0);
-
- if ((length>field+1) && /*need exact hit */
- (cmpnumfld(revno,trail->num,field+1) !=0)){
- absent(revno, field+1);
- return 0;
- }
- if (length == field+1) {
- if (date && cmpdate(date,trail->date)<0) {
- rcserror("Revision %s has date %s.",
- trail->num,
- date2str(trail->date, datebuf)
- );
- return 0;
- }
- if (author && strcmp(author,trail->author)!=0) {
- rcserror("Revision %s has author %s.",
- trail->num, trail->author
- );
- return 0;
- }
- if (state && strcmp(state,trail->state)!=0) {
- rcserror("Revision %s has state %s.",
- trail->num,
- trail->state ? trail->state : "<empty>"
- );
- return 0;
- }
- }
- bhead = trail->branches;
-
- } while ((field+=2) <= length);
- *store = 0;
- return trail;
-}
-
-
- static char const *
-lookupsym(id)
- char const *id;
-/* Function: looks up id in the list of symbolic names starting
- * with pointer SYMBOLS, and returns a pointer to the corresponding
- * revision number. Return 0 if not present.
- */
-{
- register struct assoc const *next;
- for (next = Symbols; next; next = next->nextassoc)
- if (strcmp(id, next->symbol)==0)
- return next->num;
- return 0;
-}
-
-int expandsym(source, target)
- char const *source;
- struct buf *target;
-/* Function: Source points to a revision number. Expandsym copies
- * the number to target, but replaces all symbolic fields in the
- * source number with their numeric values.
- * Expand a branch followed by `.' to the latest revision on that branch.
- * Ignore `.' after a revision. Remove leading zeros.
- * returns false on error;
- */
-{
- return fexpandsym(source, target, (RILE*)0);
-}
-
- int
-fexpandsym(source, target, fp)
- char const *source;
- struct buf *target;
- RILE *fp;
-/* Same as expandsym, except if FP is nonzero, it is used to expand KDELIM. */
-{
- register char const *sp, *bp;
- register char *tp;
- char const *tlim;
- int dots;
-
- sp = source;
- bufalloc(target, 1);
- tp = target->string;
- if (!sp || !*sp) { /* Accept 0 pointer as a legal value. */
- *tp='\0';
- return true;
- }
- if (sp[0] == KDELIM && !sp[1]) {
- if (!getoldkeys(fp))
- return false;
- if (!*prevrev.string) {
- workerror("working file lacks revision number");
- return false;
- }
- bufscpy(target, prevrev.string);
- return true;
- }
- tlim = tp + target->size;
- dots = 0;
-
- for (;;) {
- register char *p = tp;
- size_t s = tp - target->string;
- int id = false;
- for (;;) {
- switch (ctab[(unsigned char)*sp]) {
- case IDCHAR:
- case LETTER:
- case Letter:
- id = true;
- /* fall into */
- case DIGIT:
- if (tlim <= p)
- p = bufenlarge(target, &tlim);
- *p++ = *sp++;
- continue;
-
- default:
- break;
- }
- break;
- }
- if (tlim <= p)
- p = bufenlarge(target, &tlim);
- *p = 0;
- tp = target->string + s;
-
- if (id) {
- bp = lookupsym(tp);
- if (!bp) {
- rcserror("Symbolic name `%s' is undefined.",tp);
- return false;
- }
- } else {
- /* skip leading zeros */
- for (bp = tp; *bp=='0' && isdigit(bp[1]); bp++)
- continue;
-
- if (!*bp)
- if (s || *sp!='.')
- break;
- else {
- /* Insert default branch before initial `.'. */
- char const *b;
- if (Dbranch)
- b = Dbranch;
- else if (Head)
- b = Head->num;
- else
- break;
- getbranchno(b, target);
- bp = tp = target->string;
- tlim = tp + target->size;
- }
- }
-
- while ((*tp++ = *bp++))
- if (tlim <= tp)
- tp = bufenlarge(target, &tlim);
-
- switch (*sp++) {
- case '\0':
- return true;
-
- case '.':
- if (!*sp) {
- if (dots & 1)
- break;
- if (!(bp = branchtip(target->string)))
- return false;
- bufscpy(target, bp);
- return true;
- }
- ++dots;
- tp[-1] = '.';
- continue;
- }
- break;
- }
-
- rcserror("improper revision number: %s", source);
- return false;
-}
-
- char const *
-namedrev(name, delta)
- char const *name;
- struct hshentry *delta;
-/* Yield NAME if it names DELTA, 0 otherwise. */
-{
- if (name) {
- char const *id = 0, *p, *val;
- for (p = name; ; p++)
- switch (ctab[(unsigned char)*p]) {
- case IDCHAR:
- case LETTER:
- case Letter:
- id = name;
- break;
-
- case DIGIT:
- break;
-
- case UNKN:
- if (!*p && id &&
- (val = lookupsym(id)) &&
- strcmp(val, delta->num) == 0
- )
- return id;
- /* fall into */
- default:
- return 0;
- }
- }
- return 0;
-}
-
- static char const *
-branchtip(branch)
- char const *branch;
-{
- struct hshentry *h;
- struct hshentries *hs;
-
- h = genrevs(branch, (char*)0, (char*)0, (char*)0, &hs);
- return h ? h->num : (char const*)0;
-}
-
- char const *
-tiprev()
-{
- return Dbranch ? branchtip(Dbranch) : Head ? Head->num : (char const*)0;
-}
-
-
-
-#ifdef REVTEST
-
-/*
-* Test the routines that generate a sequence of delta numbers
-* needed to regenerate a given delta.
-*/
-
-char const cmdid[] = "revtest";
-
- int
-main(argc,argv)
-int argc; char * argv[];
-{
- static struct buf numricrevno;
- char symrevno[100]; /* used for input of revision numbers */
- char author[20];
- char state[20];
- char date[20];
- struct hshentries *gendeltas;
- struct hshentry * target;
- int i;
-
- if (argc<2) {
- aputs("No input file\n",stderr);
- exitmain(EXIT_FAILURE);
- }
- if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) {
- faterror("can't open input file %s", argv[1]);
- }
- Lexinit();
- getadmin();
-
- gettree();
-
- getdesc(false);
-
- do {
- /* all output goes to stderr, to have diagnostics and */
- /* errors in sequence. */
- aputs("\nEnter revision number or <return> or '.': ",stderr);
- if (!fgets(symrevno, 100, stdin)) break;
- if (*symrevno == '.') break;
- aprintf(stderr,"%s;\n",symrevno);
- expandsym(symrevno,&numricrevno);
- aprintf(stderr,"expanded number: %s; ",numricrevno.string);
- aprintf(stderr,"Date: ");
- fgets(date, 20, stdin); aprintf(stderr,"%s; ",date);
- aprintf(stderr,"Author: ");
- fgets(author, 20, stdin); aprintf(stderr,"%s; ",author);
- aprintf(stderr,"State: ");
- fgets(state, 20, stdin); aprintf(stderr, "%s;\n", state);
- target = genrevs(numricrevno.string, *date?date:(char *)0, *author?author:(char *)0,
- *state?state:(char*)0, &gendeltas);
- if (target) {
- while (gendeltas) {
- aprintf(stderr,"%s\n",gendeltas->first->num);
- gendeltas = gendeltas->next;
- }
- }
- } while (true);
- aprintf(stderr,"done\n");
- exitmain(EXIT_SUCCESS);
-}
-
-void exiterr() { _exit(EXIT_FAILURE); }
-
-#endif
diff --git a/gnu/usr.bin/rcs/lib/rcssyn.c b/gnu/usr.bin/rcs/lib/rcssyn.c
deleted file mode 100644
index 07f155b..0000000
--- a/gnu/usr.bin/rcs/lib/rcssyn.c
+++ /dev/null
@@ -1,681 +0,0 @@
-/* RCS file syntactic analysis */
-
-/******************************************************************************
- * Syntax Analysis.
- * Keyword table
- * Testprogram: define SYNTEST
- * Compatibility with Release 2: define COMPAT2=1
- ******************************************************************************
- */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.15 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.14 1995/06/01 16:23:43 eggert
- * (expand_names): Add "b" for -kb.
- * (getdelta): Don't strip leading "19" from MKS RCS dates; see cmpdate.
- *
- * Revision 5.13 1994/03/20 04:52:58 eggert
- * Remove lint.
- *
- * Revision 5.12 1993/11/03 17:42:27 eggert
- * Parse MKS RCS dates; ignore \r in diff control lines.
- * Don't discard ignored phrases. Improve quality of diagnostics.
- *
- * Revision 5.11 1992/07/28 16:12:44 eggert
- * Avoid `unsigned'. Statement macro names now end in _.
- *
- * Revision 5.10 1992/01/24 18:44:19 eggert
- * Move put routines to rcsgen.c.
- *
- * Revision 5.9 1992/01/06 02:42:34 eggert
- * ULONG_MAX/10 -> ULONG_MAX_OVER_10
- * while (E) ; -> while (E) continue;
- *
- * Revision 5.8 1991/08/19 03:13:55 eggert
- * Tune.
- *
- * Revision 5.7 1991/04/21 11:58:29 eggert
- * Disambiguate names on shortname hosts.
- * Fix errno bug. Add MS-DOS support.
- *
- * Revision 5.6 1991/02/28 19:18:51 eggert
- * Fix null termination bug in reporting keyword expansion.
- *
- * Revision 5.5 1991/02/25 07:12:44 eggert
- * Check diff output more carefully; avoid overflow.
- *
- * Revision 5.4 1990/11/01 05:28:48 eggert
- * When ignoring unknown phrases, copy them to the output RCS file.
- * Permit arbitrary data in logs and comment leaders.
- * Don't check for nontext on initial checkin.
- *
- * Revision 5.3 1990/09/20 07:58:32 eggert
- * Remove the test for non-text bytes; it caused more pain than it cured.
- *
- * Revision 5.2 1990/09/04 08:02:30 eggert
- * Parse RCS files with no revisions.
- * Don't strip leading white space from diff commands. Count RCS lines better.
- *
- * Revision 5.1 1990/08/29 07:14:06 eggert
- * Add -kkvl. Clean old log messages too.
- *
- * Revision 5.0 1990/08/22 08:13:44 eggert
- * Try to parse future RCS formats without barfing.
- * Add -k. Don't require final newline.
- * Remove compile-time limits; use malloc instead.
- * Don't output branch keyword if there's no default branch,
- * because RCS version 3 doesn't understand it.
- * Tune. Remove lint.
- * Add support for ISO 8859. Ansify and Posixate.
- * Check that a newly checked-in file is acceptable as input to 'diff'.
- * Check diff's output.
- *
- * Revision 4.6 89/05/01 15:13:32 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.5 88/08/09 19:13:21 eggert
- * Allow cc -R; remove lint.
- *
- * Revision 4.4 87/12/18 11:46:16 narten
- * more lint cleanups (Guy Harris)
- *
- * Revision 4.3 87/10/18 10:39:36 narten
- * Updating version numbers. Changes relative to 1.1 actually relative to
- * 4.1
- *
- * Revision 1.3 87/09/24 14:00:49 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:40 jenkins
- * Port to suns
- *
- * Revision 4.1 83/03/28 11:38:49 wft
- * Added parsing and printing of default branch.
- *
- * Revision 3.6 83/01/15 17:46:50 wft
- * Changed readdelta() to initialize selector and log-pointer.
- * Changed puttree to check for selector==DELETE; putdtext() uses DELNUMFORM.
- *
- * Revision 3.5 82/12/08 21:58:58 wft
- * renamed Commentleader to Commleader.
- *
- * Revision 3.4 82/12/04 13:24:40 wft
- * Added routine gettree(), which updates keeplock after reading the
- * delta tree.
- *
- * Revision 3.3 82/11/28 21:30:11 wft
- * Reading and printing of Suffix removed; version COMPAT2 skips the
- * Suffix for files of release 2 format. Fixed problems with printing nil.
- *
- * Revision 3.2 82/10/18 21:18:25 wft
- * renamed putdeltatext to putdtext.
- *
- * Revision 3.1 82/10/11 19:45:11 wft
- * made sure getc() returns into an integer.
- */
-
-
-
-/* version COMPAT2 reads files of the format of release 2 and 3, but
- * generates files of release 3 format. Need not be defined if no
- * old RCS files generated with release 2 exist.
- */
-
-#include "rcsbase.h"
-
-libId(synId, "$FreeBSD$")
-
-static char const *getkeyval P((char const*,enum tokens,int));
-static int getdelta P((void));
-static int strn2expmode P((char const*,size_t));
-static struct hshentry *getdnum P((void));
-static void badDiffOutput P((char const*)) exiting;
-static void diffLineNumberTooLarge P((char const*)) exiting;
-static void getsemi P((char const*));
-
-/* keyword table */
-
-char const
- Kaccess[] = "access",
- Kauthor[] = "author",
- Kbranch[] = "branch",
- Kcomment[] = "comment",
- Kdate[] = "date",
- Kdesc[] = "desc",
- Kexpand[] = "expand",
- Khead[] = "head",
- Klocks[] = "locks",
- Klog[] = "log",
- Knext[] = "next",
- Kstate[] = "state",
- Kstrict[] = "strict",
- Ksymbols[] = "symbols",
- Ktext[] = "text";
-
-static char const
-#if COMPAT2
- Ksuffix[] = "suffix",
-#endif
- K_branches[]= "branches";
-
-static struct buf Commleader;
-struct cbuf Comment;
-struct cbuf Ignored;
-struct access * AccessList;
-struct assoc * Symbols;
-struct rcslock *Locks;
-int Expand;
-int StrictLocks;
-struct hshentry * Head;
-char const * Dbranch;
-int TotalDeltas;
-
-
- static void
-getsemi(key)
- char const *key;
-/* Get a semicolon to finish off a phrase started by KEY. */
-{
- if (!getlex(SEMI))
- fatserror("missing ';' after '%s'", key);
-}
-
- static struct hshentry *
-getdnum()
-/* Get a delta number. */
-{
- register struct hshentry *delta = getnum();
- if (delta && countnumflds(delta->num)&1)
- fatserror("%s isn't a delta number", delta->num);
- return delta;
-}
-
-
- void
-getadmin()
-/* Read an <admin> and initialize the appropriate global variables. */
-{
- register char const *id;
- struct access * newaccess;
- struct assoc * newassoc;
- struct rcslock *newlock;
- struct hshentry * delta;
- struct access **LastAccess;
- struct assoc **LastSymbol;
- struct rcslock **LastLock;
- struct buf b;
- struct cbuf cb;
-
- TotalDeltas=0;
-
- getkey(Khead);
- Head = getdnum();
- getsemi(Khead);
-
- Dbranch = 0;
- if (getkeyopt(Kbranch)) {
- if ((delta = getnum()))
- Dbranch = delta->num;
- getsemi(Kbranch);
- }
-
-
-#if COMPAT2
- /* read suffix. Only in release 2 format */
- if (getkeyopt(Ksuffix)) {
- if (nexttok==STRING) {
- readstring(); nextlex(); /* Throw away the suffix. */
- } else if (nexttok==ID) {
- nextlex();
- }
- getsemi(Ksuffix);
- }
-#endif
-
- getkey(Kaccess);
- LastAccess = &AccessList;
- while ((id = getid())) {
- newaccess = ftalloc(struct access);
- newaccess->login = id;
- *LastAccess = newaccess;
- LastAccess = &newaccess->nextaccess;
- }
- *LastAccess = 0;
- getsemi(Kaccess);
-
- getkey(Ksymbols);
- LastSymbol = &Symbols;
- while ((id = getid())) {
- if (!getlex(COLON))
- fatserror("missing ':' in symbolic name definition");
- if (!(delta=getnum())) {
- fatserror("missing number in symbolic name definition");
- } else { /*add new pair to association list*/
- newassoc = ftalloc(struct assoc);
- newassoc->symbol=id;
- newassoc->num = delta->num;
- *LastSymbol = newassoc;
- LastSymbol = &newassoc->nextassoc;
- }
- }
- *LastSymbol = 0;
- getsemi(Ksymbols);
-
- getkey(Klocks);
- LastLock = &Locks;
- while ((id = getid())) {
- if (!getlex(COLON))
- fatserror("missing ':' in lock");
- if (!(delta=getdnum())) {
- fatserror("missing number in lock");
- } else { /*add new pair to lock list*/
- newlock = ftalloc(struct rcslock);
- newlock->login=id;
- newlock->delta=delta;
- *LastLock = newlock;
- LastLock = &newlock->nextlock;
- }
- }
- *LastLock = 0;
- getsemi(Klocks);
-
- if ((StrictLocks = getkeyopt(Kstrict)))
- getsemi(Kstrict);
-
- clear_buf(&Comment);
- if (getkeyopt(Kcomment)) {
- if (nexttok==STRING) {
- Comment = savestring(&Commleader);
- nextlex();
- }
- getsemi(Kcomment);
- }
-
- Expand = KEYVAL_EXPAND;
- if (getkeyopt(Kexpand)) {
- if (nexttok==STRING) {
- bufautobegin(&b);
- cb = savestring(&b);
- if ((Expand = strn2expmode(cb.string,cb.size)) < 0)
- fatserror("unknown expand mode %.*s",
- (int)cb.size, cb.string
- );
- bufautoend(&b);
- nextlex();
- }
- getsemi(Kexpand);
- }
- Ignored = getphrases(Kdesc);
-}
-
-char const *const expand_names[] = {
- /* These must agree with *_EXPAND in rcsbase.h. */
- "kv", "kvl", "k", "v", "o", "b",
- 0
-};
-
- int
-str2expmode(s)
- char const *s;
-/* Yield expand mode corresponding to S, or -1 if bad. */
-{
- return strn2expmode(s, strlen(s));
-}
-
- static int
-strn2expmode(s, n)
- char const *s;
- size_t n;
-{
- char const *const *p;
-
- for (p = expand_names; *p; ++p)
- if (memcmp(*p,s,n) == 0 && !(*p)[n])
- return p - expand_names;
- return -1;
-}
-
-
- void
-ignorephrases(key)
- const char *key;
-/*
-* Ignore a series of phrases that do not start with KEY.
-* Stop when the next phrase starts with a token that is not an identifier,
-* or is KEY.
-*/
-{
- for (;;) {
- nextlex();
- if (nexttok != ID || strcmp(NextString,key) == 0)
- break;
- warnignore();
- hshenter=false;
- for (;; nextlex()) {
- switch (nexttok) {
- case SEMI: hshenter=true; break;
- case ID:
- case NUM: ffree1(NextString); continue;
- case STRING: readstring(); continue;
- default: continue;
- }
- break;
- }
- }
-}
-
-
- static int
-getdelta()
-/* Function: reads a delta block.
- * returns false if the current block does not start with a number.
- */
-{
- register struct hshentry * Delta, * num;
- struct branchhead **LastBranch, *NewBranch;
-
- if (!(Delta = getdnum()))
- return false;
-
- hshenter = false; /*Don't enter dates into hashtable*/
- Delta->date = getkeyval(Kdate, NUM, false);
- hshenter=true; /*reset hshenter for revision numbers.*/
-
- Delta->author = getkeyval(Kauthor, ID, false);
-
- Delta->state = getkeyval(Kstate, ID, true);
-
- getkey(K_branches);
- LastBranch = &Delta->branches;
- while ((num = getdnum())) {
- NewBranch = ftalloc(struct branchhead);
- NewBranch->hsh = num;
- *LastBranch = NewBranch;
- LastBranch = &NewBranch->nextbranch;
- }
- *LastBranch = 0;
- getsemi(K_branches);
-
- getkey(Knext);
- Delta->next = num = getdnum();
- getsemi(Knext);
- Delta->lockedby = 0;
- Delta->log.string = 0;
- Delta->selector = true;
- Delta->ig = getphrases(Kdesc);
- TotalDeltas++;
- return (true);
-}
-
-
- void
-gettree()
-/* Function: Reads in the delta tree with getdelta(), then
- * updates the lockedby fields.
- */
-{
- struct rcslock const *currlock;
-
- while (getdelta())
- continue;
- currlock=Locks;
- while (currlock) {
- currlock->delta->lockedby = currlock->login;
- currlock = currlock->nextlock;
- }
-}
-
-
- void
-getdesc(prdesc)
-int prdesc;
-/* Function: read in descriptive text
- * nexttok is not advanced afterwards.
- * If prdesc is set, the text is printed to stdout.
- */
-{
-
- getkeystring(Kdesc);
- if (prdesc)
- printstring(); /*echo string*/
- else readstring(); /*skip string*/
-}
-
-
-
-
-
-
- static char const *
-getkeyval(keyword, token, optional)
- char const *keyword;
- enum tokens token;
- int optional;
-/* reads a pair of the form
- * <keyword> <token> ;
- * where token is one of <id> or <num>. optional indicates whether
- * <token> is optional. A pointer to
- * the actual character string of <id> or <num> is returned.
- */
-{
- register char const *val = 0;
-
- getkey(keyword);
- if (nexttok==token) {
- val = NextString;
- nextlex();
- } else {
- if (!optional)
- fatserror("missing %s", keyword);
- }
- getsemi(keyword);
- return(val);
-}
-
-
- void
-unexpected_EOF()
-{
- rcsfaterror("unexpected EOF in diff output");
-}
-
- void
-initdiffcmd(dc)
- register struct diffcmd *dc;
-/* Initialize *dc suitably for getdiffcmd(). */
-{
- dc->adprev = 0;
- dc->dafter = 0;
-}
-
- static void
-badDiffOutput(buf)
- char const *buf;
-{
- rcsfaterror("bad diff output line: %s", buf);
-}
-
- static void
-diffLineNumberTooLarge(buf)
- char const *buf;
-{
- rcsfaterror("diff line number too large: %s", buf);
-}
-
- int
-getdiffcmd(finfile, delimiter, foutfile, dc)
- RILE *finfile;
- FILE *foutfile;
- int delimiter;
- struct diffcmd *dc;
-/* Get a editing command output by 'diff -n' from fin.
- * The input is delimited by SDELIM if delimiter is set, EOF otherwise.
- * Copy a clean version of the command to fout (if nonnull).
- * Yield 0 for 'd', 1 for 'a', and -1 for EOF.
- * Store the command's line number and length into dc->line1 and dc->nlines.
- * Keep dc->adprev and dc->dafter up to date.
- */
-{
- register int c;
- declarecache;
- register FILE *fout;
- register char *p;
- register RILE *fin;
- long line1, nlines, t;
- char buf[BUFSIZ];
-
- fin = finfile;
- fout = foutfile;
- setupcache(fin); cache(fin);
- cachegeteof_(c, { if (delimiter) unexpected_EOF(); return -1; } )
- if (delimiter) {
- if (c==SDELIM) {
- cacheget_(c)
- if (c==SDELIM) {
- buf[0] = c;
- buf[1] = 0;
- badDiffOutput(buf);
- }
- uncache(fin);
- nextc = c;
- if (fout)
- aprintf(fout, "%c%c", SDELIM, c);
- return -1;
- }
- }
- p = buf;
- do {
- if (buf+BUFSIZ-2 <= p) {
- rcsfaterror("diff output command line too long");
- }
- *p++ = c;
- cachegeteof_(c, unexpected_EOF();)
- } while (c != '\n');
- uncache(fin);
- if (delimiter)
- ++rcsline;
- *p = '\0';
- for (p = buf+1; (c = *p++) == ' '; )
- continue;
- line1 = 0;
- while (isdigit(c)) {
- if (
- LONG_MAX/10 < line1 ||
- (t = line1 * 10, (line1 = t + (c - '0')) < t)
- )
- diffLineNumberTooLarge(buf);
- c = *p++;
- }
- while (c == ' ')
- c = *p++;
- nlines = 0;
- while (isdigit(c)) {
- if (
- LONG_MAX/10 < nlines ||
- (t = nlines * 10, (nlines = t + (c - '0')) < t)
- )
- diffLineNumberTooLarge(buf);
- c = *p++;
- }
- if (c == '\r')
- c = *p++;
- if (c || !nlines) {
- badDiffOutput(buf);
- }
- if (line1+nlines < line1)
- diffLineNumberTooLarge(buf);
- switch (buf[0]) {
- case 'a':
- if (line1 < dc->adprev) {
- rcsfaterror("backward insertion in diff output: %s", buf);
- }
- dc->adprev = line1 + 1;
- break;
- case 'd':
- if (line1 < dc->adprev || line1 < dc->dafter) {
- rcsfaterror("backward deletion in diff output: %s", buf);
- }
- dc->adprev = line1;
- dc->dafter = line1 + nlines;
- break;
- default:
- badDiffOutput(buf);
- }
- if (fout) {
- aprintf(fout, "%s\n", buf);
- }
- dc->line1 = line1;
- dc->nlines = nlines;
- return buf[0] == 'a';
-}
-
-
-
-#ifdef SYNTEST
-
-/* Input an RCS file and print its internal data structures. */
-
-char const cmdid[] = "syntest";
-
- int
-main(argc,argv)
-int argc; char * argv[];
-{
-
- if (argc<2) {
- aputs("No input file\n",stderr);
- exitmain(EXIT_FAILURE);
- }
- if (!(finptr = Iopen(argv[1], FOPEN_R, (struct stat*)0))) {
- faterror("can't open input file %s", argv[1]);
- }
- Lexinit();
- getadmin();
- fdlock = STDOUT_FILENO;
- putadmin();
-
- gettree();
-
- getdesc(true);
-
- nextlex();
-
- if (!eoflex()) {
- fatserror("expecting EOF");
- }
- exitmain(EXIT_SUCCESS);
-}
-
-void exiterr() { _exit(EXIT_FAILURE); }
-
-#endif
diff --git a/gnu/usr.bin/rcs/lib/rcstime.c b/gnu/usr.bin/rcs/lib/rcstime.c
deleted file mode 100644
index cfd4660..0000000
--- a/gnu/usr.bin/rcs/lib/rcstime.c
+++ /dev/null
@@ -1,191 +0,0 @@
-/* Convert between RCS time format and Posix and/or C formats. */
-
-/* Copyright 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#include "rcsbase.h"
-#include "partime.h"
-#include "maketime.h"
-
-libId(rcstimeId, "$FreeBSD$")
-
-static long zone_offset; /* seconds east of UTC, or TM_LOCAL_ZONE */
-static int use_zone_offset; /* if zero, use UTC without zone indication */
-
-/*
-* Convert Unix time to RCS format.
-* For compatibility with older versions of RCS,
-* dates from 1900 through 1999 are stored without the leading "19".
-*/
- void
-time2date(unixtime,date)
- time_t unixtime;
- char date[datesize];
-{
- register struct tm const *tm = time2tm(unixtime, RCSversion<VERSION(5));
- VOID sprintf(date,
-# if has_printf_dot
- "%.2d.%.2d.%.2d.%.2d.%.2d.%.2d",
-# else
- "%02d.%02d.%02d.%02d.%02d.%02d",
-# endif
- tm->tm_year + ((unsigned)tm->tm_year < 100 ? 0 : 1900),
- tm->tm_mon+1, tm->tm_mday,
- tm->tm_hour, tm->tm_min, tm->tm_sec
- );
-}
-
-/* Like str2time, except die if an error was found. */
-static time_t str2time_checked P((char const*,time_t,long));
- static time_t
-str2time_checked(source, default_time, default_zone)
- char const *source;
- time_t default_time;
- long default_zone;
-{
- time_t t = str2time(source, default_time, default_zone);
- if (t == -1)
- faterror("unknown date/time: %s", source);
- return t;
-}
-
-/*
-* Parse a free-format date in SOURCE, convert it
-* into RCS internal format, and store the result into TARGET.
-*/
- void
-str2date(source, target)
- char const *source;
- char target[datesize];
-{
- time2date(
- str2time_checked(source, now(),
- use_zone_offset ? zone_offset
- : RCSversion<VERSION(5) ? TM_LOCAL_ZONE
- : 0
- ),
- target
- );
-}
-
-/* Convert an RCS internal format date to time_t. */
- time_t
-date2time(source)
- char const source[datesize];
-{
- char s[datesize + zonelenmax];
- return str2time_checked(date2str(source, s), (time_t)0, 0);
-}
-
-
-/* Set the time zone for date2str output. */
- void
-zone_set(s)
- char const *s;
-{
- if ((use_zone_offset = *s)) {
- long zone;
- char const *zonetail = parzone(s, &zone);
- if (!zonetail || *zonetail)
- error("%s: not a known time zone", s);
- else
- zone_offset = zone;
- }
-}
-
-
-/*
-* Format a user-readable form of the RCS format DATE into the buffer DATEBUF.
-* Yield DATEBUF.
-*/
- char const *
-date2str(date, datebuf)
- char const date[datesize];
- char datebuf[datesize + zonelenmax];
-{
- register char const *p = date;
-
- while (*p++ != '.')
- continue;
- if (!use_zone_offset)
- VOID sprintf(datebuf,
- "19%.*s/%.2s/%.2s %.2s:%.2s:%s"
- + (date[2]=='.' && VERSION(5)<=RCSversion ? 0 : 2),
- (int)(p-date-1), date,
- p, p+3, p+6, p+9, p+12
- );
- else {
- struct tm t;
- struct tm const *z;
- int non_hour;
- long zone;
- char c;
-
- t.tm_year = atoi(date) - (date[2]=='.' ? 0 : 1900);
- t.tm_mon = atoi(p) - 1;
- t.tm_mday = atoi(p+3);
- t.tm_hour = atoi(p+6);
- t.tm_min = atoi(p+9);
- t.tm_sec = atoi(p+12);
- t.tm_wday = -1;
- zone = zone_offset;
- if (zone == TM_LOCAL_ZONE) {
- time_t u = tm2time(&t, 0), d;
- z = localtime(&u);
- d = difftm(z, &t);
- zone = (time_t)-1 < 0 || d < -d ? d : -(long)-d;
- } else {
- adjzone(&t, zone);
- z = &t;
- }
- c = '+';
- if (zone < 0) {
- zone = -zone;
- c = '-';
- }
- VOID sprintf(datebuf,
-# if has_printf_dot
- "%.2d-%.2d-%.2d %.2d:%.2d:%.2d%c%.2d",
-# else
- "%02d-%02d-%02d %02d:%02d:%02d%c%02d",
-# endif
- z->tm_year + 1900,
- z->tm_mon + 1, z->tm_mday, z->tm_hour, z->tm_min, z->tm_sec,
- c, (int) (zone / (60*60))
- );
- if ((non_hour = zone % (60*60))) {
-# if has_printf_dot
- static char const fmt[] = ":%.2d";
-# else
- static char const fmt[] = ":%02d";
-# endif
- VOID sprintf(datebuf + strlen(datebuf), fmt, non_hour / 60);
- if ((non_hour %= 60))
- VOID sprintf(datebuf + strlen(datebuf), fmt, non_hour);
- }
- }
- return datebuf;
-}
diff --git a/gnu/usr.bin/rcs/lib/rcsutil.c b/gnu/usr.bin/rcs/lib/rcsutil.c
deleted file mode 100644
index e10afff..0000000
--- a/gnu/usr.bin/rcs/lib/rcsutil.c
+++ /dev/null
@@ -1,1398 +0,0 @@
-/* RCS utility functions */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-
-
-
-/*
- * Revision 5.20 1995/06/16 06:19:24 eggert
- * (catchsig): Remove `return'.
- * Update FSF address.
- *
- * Revision 5.19 1995/06/02 18:19:00 eggert
- * (catchsigaction): New name for `catchsig', for sa_sigaction signature.
- * Use nRCS even if !has_psiginfo, to remove unused variable warning.
- * (setup_catchsig): Use sa_sigaction only if has_sa_sigaction.
- * Use ENOTSUP only if defined.
- *
- * Revision 5.18 1995/06/01 16:23:43 eggert
- * (catchsig, restoreints, setup_catchsig): Use SA_SIGINFO, not has_psiginfo,
- * to determine whether to use SA_SIGINFO feature,
- * but also check at runtime whether the feature works.
- * (catchsig): If an mmap_signal occurs, report the affected file name.
- * (unsupported_SA_SIGINFO, accessName): New variables.
- * (setup_catchsig): If using SA_SIGINFO, use sa_sigaction, not sa_handler.
- * If SA_SIGINFO fails, fall back on sa_handler method.
- *
- * (readAccessFilenameBuffer, dupSafer, fdSafer, fopenSafer): New functions.
- * (concatenate): Remove.
- *
- * (runv): Work around bad_wait_if_SIGCHLD_ignored bug.
- * Remove reference to OPEN_O_WORK.
- *
- * Revision 5.17 1994/03/20 04:52:58 eggert
- * Specify subprocess input via file descriptor, not file name.
- * Avoid messing with I/O buffers in the child process.
- * Define dup in terms of F_DUPFD if it exists.
- * Move setmtime to rcsedit.c. Remove lint.
- *
- * Revision 5.16 1993/11/09 17:40:15 eggert
- * -V now prints version on stdout and exits.
- *
- * Revision 5.15 1993/11/03 17:42:27 eggert
- * Use psiginfo and setreuid if available. Move date2str to maketime.c.
- *
- * Revision 5.14 1992/07/28 16:12:44 eggert
- * Add -V. has_sigaction overrides sig_zaps_handler. Fix -M bug.
- * Add mmap_signal, which minimizes signal handling for non-mmap hosts.
- *
- * Revision 5.13 1992/02/17 23:02:28 eggert
- * Work around NFS mmap SIGBUS problem. Add -T support.
- *
- * Revision 5.12 1992/01/24 18:44:19 eggert
- * Work around NFS mmap bug that leads to SIGBUS core dumps. lint -> RCS_lint
- *
- * Revision 5.11 1992/01/06 02:42:34 eggert
- * O_BINARY -> OPEN_O_WORK
- * while (E) ; -> while (E) continue;
- *
- * Revision 5.10 1991/10/07 17:32:46 eggert
- * Support piece tables even if !has_mmap.
- *
- * Revision 5.9 1991/08/19 03:13:55 eggert
- * Add spawn() support. Explicate assumptions about getting invoker's name.
- * Standardize user-visible dates. Tune.
- *
- * Revision 5.8 1991/04/21 11:58:30 eggert
- * Plug setuid security hole.
- *
- * Revision 5.6 1991/02/26 17:48:39 eggert
- * Fix setuid bug. Use fread, fwrite more portably.
- * Support waitpid. Don't assume -1 is acceptable to W* macros.
- * strsave -> str_save (DG/UX name clash)
- *
- * Revision 5.5 1990/12/04 05:18:49 eggert
- * Don't output a blank line after a signal diagnostic.
- * Use -I for prompts and -q for diagnostics.
- *
- * Revision 5.4 1990/11/01 05:03:53 eggert
- * Remove unneeded setid check. Add awrite(), fremember().
- *
- * Revision 5.3 1990/10/06 00:16:45 eggert
- * Don't fread F if feof(F).
- *
- * Revision 5.2 1990/09/04 08:02:31 eggert
- * Store fread()'s result in an fread_type object.
- *
- * Revision 5.1 1990/08/29 07:14:07 eggert
- * Declare getpwuid() more carefully.
- *
- * Revision 5.0 1990/08/22 08:13:46 eggert
- * Add setuid support. Permit multiple locks per user.
- * Remove compile-time limits; use malloc instead.
- * Switch to GMT. Permit dates past 1999/12/31.
- * Add -V. Remove snooping. Ansify and Posixate.
- * Tune. Some USG hosts define NSIG but not sys_siglist.
- * Don't run /bin/sh if it's hopeless.
- * Don't leave garbage behind if the output is an empty pipe.
- * Clean up after SIGXCPU or SIGXFSZ. Print name of signal that caused cleanup.
- *
- * Revision 4.6 89/05/01 15:13:40 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.5 88/11/08 16:01:02 narten
- * corrected use of varargs routines
- *
- * Revision 4.4 88/08/09 19:13:24 eggert
- * Check for memory exhaustion.
- * Permit signal handlers to yield either 'void' or 'int'; fix oldSIGINT botch.
- * Use execv(), not system(); yield exit status like diff(1)'s.
- *
- * Revision 4.3 87/10/18 10:40:22 narten
- * Updating version numbers. Changes relative to 1.1 actually
- * relative to 4.1
- *
- * Revision 1.3 87/09/24 14:01:01 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:43 jenkins
- * Port to suns
- *
- * Revision 4.1 83/05/10 15:53:13 wft
- * Added getcaller() and findlock().
- * Changed catchints() to check SIGINT for SIG_IGN before setting up the signal
- * (needed for background jobs in older shells). Added restoreints().
- * Removed printing of full RCS path from logcommand().
- *
- * Revision 3.8 83/02/15 15:41:49 wft
- * Added routine fastcopy() to copy remainder of a file in blocks.
- *
- * Revision 3.7 82/12/24 15:25:19 wft
- * added catchints(), ignoreints() for catching and ingnoring interrupts;
- * fixed catchsig().
- *
- * Revision 3.6 82/12/08 21:52:05 wft
- * Using DATEFORM to format dates.
- *
- * Revision 3.5 82/12/04 18:20:49 wft
- * Replaced SNOOPDIR with SNOOPFILE; changed addlock() to update
- * lockedby-field.
- *
- * Revision 3.4 82/12/03 17:17:43 wft
- * Added check to addlock() ensuring only one lock per person.
- * Addlock also returns a pointer to the lock created. Deleted fancydate().
- *
- * Revision 3.3 82/11/27 12:24:37 wft
- * moved rmsema(), trysema(), trydiraccess(), getfullRCSname() to rcsfnms.c.
- * Introduced macro SNOOP so that snoop can be placed in directory other than
- * TARGETDIR. Changed %02d to %.2d for compatibility reasons.
- *
- * Revision 3.2 82/10/18 21:15:11 wft
- * added function getfullRCSname().
- *
- * Revision 3.1 82/10/13 16:17:37 wft
- * Cleanup message is now suppressed in quiet mode.
- */
-
-
-
-
-#include "rcsbase.h"
-
-libId(utilId, "$FreeBSD$")
-
-#if !has_memcmp
- int
-memcmp(s1, s2, n)
- void const *s1, *s2;
- size_t n;
-{
- register unsigned char const
- *p1 = (unsigned char const*)s1,
- *p2 = (unsigned char const*)s2;
- register size_t i = n;
- register int r = 0;
- while (i-- && !(r = (*p1++ - *p2++)))
- ;
- return r;
-}
-#endif
-
-#if !has_memcpy
- void *
-memcpy(s1, s2, n)
- void *s1;
- void const *s2;
- size_t n;
-{
- register char *p1 = (char*)s1;
- register char const *p2 = (char const*)s2;
- while (n--)
- *p1++ = *p2++;
- return s1;
-}
-#endif
-
-#if RCS_lint
- malloc_type lintalloc;
-#endif
-
-/*
- * list of blocks allocated with ftestalloc()
- * These blocks can be freed by ffree when we're done with the current file.
- * We could put the free block inside struct alloclist, rather than a pointer
- * to the free block, but that would be less portable.
- */
-struct alloclist {
- malloc_type alloc;
- struct alloclist *nextalloc;
-};
-static struct alloclist *alloced;
-
-
- static malloc_type okalloc P((malloc_type));
- static malloc_type
-okalloc(p)
- malloc_type p;
-{
- if (!p)
- faterror("out of memory");
- return p;
-}
-
- malloc_type
-testalloc(size)
- size_t size;
-/* Allocate a block, testing that the allocation succeeded. */
-{
- return okalloc(malloc(size));
-}
-
- malloc_type
-testrealloc(ptr, size)
- malloc_type ptr;
- size_t size;
-/* Reallocate a block, testing that the allocation succeeded. */
-{
- return okalloc(realloc(ptr, size));
-}
-
- malloc_type
-fremember(ptr)
- malloc_type ptr;
-/* Remember PTR in 'alloced' so that it can be freed later. Yield PTR. */
-{
- register struct alloclist *q = talloc(struct alloclist);
- q->nextalloc = alloced;
- alloced = q;
- return q->alloc = ptr;
-}
-
- malloc_type
-ftestalloc(size)
- size_t size;
-/* Allocate a block, putting it in 'alloced' so it can be freed later. */
-{
- return fremember(testalloc(size));
-}
-
- void
-ffree()
-/* Free all blocks allocated with ftestalloc(). */
-{
- register struct alloclist *p, *q;
- for (p = alloced; p; p = q) {
- q = p->nextalloc;
- tfree(p->alloc);
- tfree(p);
- }
- alloced = 0;
-}
-
- void
-ffree1(f)
- register char const *f;
-/* Free the block f, which was allocated by ftestalloc. */
-{
- register struct alloclist *p, **a = &alloced;
-
- while ((p = *a)->alloc != f)
- a = &p->nextalloc;
- *a = p->nextalloc;
- tfree(p->alloc);
- tfree(p);
-}
-
- char *
-str_save(s)
- char const *s;
-/* Save s in permanently allocated storage. */
-{
- return strcpy(tnalloc(char, strlen(s)+1), s);
-}
-
- char *
-fstr_save(s)
- char const *s;
-/* Save s in storage that will be deallocated when we're done with this file. */
-{
- return strcpy(ftnalloc(char, strlen(s)+1), s);
-}
-
- char *
-cgetenv(name)
- char const *name;
-/* Like getenv(), but yield a copy; getenv() can overwrite old results. */
-{
- register char *p;
-
- return (p=getenv(name)) ? str_save(p) : p;
-}
-
- char const *
-getusername(suspicious)
- int suspicious;
-/* Get the caller's login name. Trust only getwpuid if SUSPICIOUS. */
-{
- static char *name;
-
- if (!name) {
- if (
- /* Prefer getenv() unless suspicious; it's much faster. */
-# if getlogin_is_secure
- (suspicious
- || (
- !(name = cgetenv("LOGNAME"))
- && !(name = cgetenv("USER"))
- ))
- && !(name = getlogin())
-# else
- suspicious
- || (
- !(name = cgetenv("LOGNAME"))
- && !(name = cgetenv("USER"))
- && !(name = getlogin())
- )
-# endif
- ) {
-#if has_getuid && has_getpwuid
- struct passwd const *pw = getpwuid(ruid());
- if (!pw)
- faterror("no password entry for userid %lu",
- (unsigned long)ruid()
- );
- name = pw->pw_name;
-#else
-#if has_setuid
- faterror("setuid not supported");
-#else
- faterror("Who are you? Please setenv LOGNAME.");
-#endif
-#endif
- }
- checksid(name);
- }
- return name;
-}
-
-
-
-
-#if has_signal
-
-/*
- * Signal handling
- *
- * Standard C places too many restrictions on signal handlers.
- * We obey as many of them as we can.
- * Posix places fewer restrictions, and we are Posix-compatible here.
- */
-
-static sig_atomic_t volatile heldsignal, holdlevel;
-#ifdef SA_SIGINFO
- static int unsupported_SA_SIGINFO;
- static siginfo_t bufsiginfo;
- static siginfo_t *volatile heldsiginfo;
-#endif
-
-
-#if has_NFS && has_mmap && large_memory && mmap_signal
- static char const *accessName;
-
- void
- readAccessFilenameBuffer(filename, p)
- char const *filename;
- unsigned char const *p;
- {
- unsigned char volatile t;
- accessName = filename;
- t = *p;
- accessName = 0;
- }
-#else
-# define accessName ((char const *) 0)
-#endif
-
-
-#if !has_psignal
-
-# define psignal my_psignal
- static void my_psignal P((int,char const*));
- static void
-my_psignal(sig, s)
- int sig;
- char const *s;
-{
- char const *sname = "Unknown signal";
-# if has_sys_siglist && defined(NSIG)
- if ((unsigned)sig < NSIG)
- sname = sys_siglist[sig];
-# else
- switch (sig) {
-# ifdef SIGHUP
- case SIGHUP: sname = "Hangup"; break;
-# endif
-# ifdef SIGINT
- case SIGINT: sname = "Interrupt"; break;
-# endif
-# ifdef SIGPIPE
- case SIGPIPE: sname = "Broken pipe"; break;
-# endif
-# ifdef SIGQUIT
- case SIGQUIT: sname = "Quit"; break;
-# endif
-# ifdef SIGTERM
- case SIGTERM: sname = "Terminated"; break;
-# endif
-# ifdef SIGXCPU
- case SIGXCPU: sname = "Cputime limit exceeded"; break;
-# endif
-# ifdef SIGXFSZ
- case SIGXFSZ: sname = "Filesize limit exceeded"; break;
-# endif
-# if has_mmap && large_memory
-# if defined(SIGBUS) && mmap_signal==SIGBUS
- case SIGBUS: sname = "Bus error"; break;
-# endif
-# if defined(SIGSEGV) && mmap_signal==SIGSEGV
- case SIGSEGV: sname = "Segmentation fault"; break;
-# endif
-# endif
- }
-# endif
-
- /* Avoid calling sprintf etc., in case they're not reentrant. */
- {
- char const *p;
- char buf[BUFSIZ], *b = buf;
- for (p = s; *p; *b++ = *p++)
- continue;
- *b++ = ':';
- *b++ = ' ';
- for (p = sname; *p; *b++ = *p++)
- continue;
- *b++ = '\n';
- VOID write(STDERR_FILENO, buf, b - buf);
- }
-}
-#endif
-
-static signal_type catchsig P((int));
-#ifdef SA_SIGINFO
- static signal_type catchsigaction P((int,siginfo_t*,void*));
-#endif
-
- static signal_type
-catchsig(s)
- int s;
-#ifdef SA_SIGINFO
-{
- catchsigaction(s, (siginfo_t *)0, (void *)0);
-}
- static signal_type
-catchsigaction(s, i, c)
- int s;
- siginfo_t *i;
- void *c;
-#endif
-{
-# if sig_zaps_handler
- /* If a signal arrives before we reset the handler, we lose. */
- VOID signal(s, SIG_IGN);
-# endif
-
-# ifdef SA_SIGINFO
- if (!unsupported_SA_SIGINFO)
- i = 0;
-# endif
-
- if (holdlevel) {
- heldsignal = s;
-# ifdef SA_SIGINFO
- if (i) {
- bufsiginfo = *i;
- heldsiginfo = &bufsiginfo;
- }
-# endif
- return;
- }
-
- ignoreints();
- setrid();
- if (!quietflag) {
- /* Avoid calling sprintf etc., in case they're not reentrant. */
- char const *p;
- char buf[BUFSIZ], *b = buf;
-
- if ( ! (
-# if has_mmap && large_memory && mmap_signal
- /* Check whether this signal was planned. */
- s == mmap_signal && accessName
-# else
- 0
-# endif
- )) {
- char const *nRCS = "\nRCS";
-# if defined(SA_SIGINFO) && has_si_errno && has_mmap && large_memory && mmap_signal
- if (s == mmap_signal && i && i->si_errno) {
- errno = i->si_errno;
- perror(nRCS++);
- }
-# endif
-# if defined(SA_SIGINFO) && has_psiginfo
- if (i)
- psiginfo(i, nRCS);
- else
- psignal(s, nRCS);
-# else
- psignal(s, nRCS);
-# endif
- }
-
- for (p = "RCS: "; *p; *b++ = *p++)
- continue;
-# if has_mmap && large_memory && mmap_signal
- if (s == mmap_signal) {
- p = accessName;
- if (!p)
- p = "Was a file changed by some other process? ";
- else {
- char const *p1;
- for (p1 = p; *p1; p1++)
- continue;
- VOID write(STDERR_FILENO, buf, b - buf);
- VOID write(STDERR_FILENO, p, p1 - p);
- b = buf;
- p = ": Permission denied. ";
- }
- while (*p)
- *b++ = *p++;
- }
-# endif
- for (p = "Cleaning up.\n"; *p; *b++ = *p++)
- continue;
- VOID write(STDERR_FILENO, buf, b - buf);
- }
- exiterr();
-}
-
- void
-ignoreints()
-{
- ++holdlevel;
-}
-
- void
-restoreints()
-{
- if (!--holdlevel && heldsignal)
-# ifdef SA_SIGINFO
- VOID catchsigaction(heldsignal, heldsiginfo, (void *)0);
-# else
- VOID catchsig(heldsignal);
-# endif
-}
-
-
-static void setup_catchsig P((int const*,int));
-
-#if has_sigaction
-
- static void check_sig P((int));
- static void
- check_sig(r)
- int r;
- {
- if (r != 0)
- efaterror("signal handling");
- }
-
- static void
- setup_catchsig(sig, sigs)
- int const *sig;
- int sigs;
- {
- register int i, j;
- struct sigaction act;
-
- for (i=sigs; 0<=--i; ) {
- check_sig(sigaction(sig[i], (struct sigaction*)0, &act));
- if (act.sa_handler != SIG_IGN) {
- act.sa_handler = catchsig;
-# ifdef SA_SIGINFO
- if (!unsupported_SA_SIGINFO) {
-# if has_sa_sigaction
- act.sa_sigaction = catchsigaction;
-# else
- act.sa_handler = catchsigaction;
-# endif
- act.sa_flags |= SA_SIGINFO;
- }
-# endif
- for (j=sigs; 0<=--j; )
- check_sig(sigaddset(&act.sa_mask, sig[j]));
- if (sigaction(sig[i], &act, (struct sigaction*)0) != 0) {
-# if defined(SA_SIGINFO) && defined(ENOTSUP)
- if (errno == ENOTSUP && !unsupported_SA_SIGINFO) {
- /* Turn off use of SA_SIGINFO and try again. */
- unsupported_SA_SIGINFO = 1;
- i++;
- continue;
- }
-# endif
- check_sig(-1);
- }
- }
- }
- }
-
-#else
-#if has_sigblock
-
- static void
- setup_catchsig(sig, sigs)
- int const *sig;
- int sigs;
- {
- register int i;
- int mask;
-
- mask = 0;
- for (i=sigs; 0<=--i; )
- mask |= sigmask(sig[i]);
- mask = sigblock(mask);
- for (i=sigs; 0<=--i; )
- if (
- signal(sig[i], catchsig) == SIG_IGN &&
- signal(sig[i], SIG_IGN) != catchsig
- )
- faterror("signal catcher failure");
- VOID sigsetmask(mask);
- }
-
-#else
-
- static void
- setup_catchsig(sig, sigs)
- int const *sig;
- int sigs;
- {
- register i;
-
- for (i=sigs; 0<=--i; )
- if (
- signal(sig[i], SIG_IGN) != SIG_IGN &&
- signal(sig[i], catchsig) != SIG_IGN
- )
- faterror("signal catcher failure");
- }
-
-#endif
-#endif
-
-
-static int const regsigs[] = {
-# ifdef SIGHUP
- SIGHUP,
-# endif
-# ifdef SIGINT
- SIGINT,
-# endif
-# ifdef SIGPIPE
- SIGPIPE,
-# endif
-# ifdef SIGQUIT
- SIGQUIT,
-# endif
-# ifdef SIGTERM
- SIGTERM,
-# endif
-# ifdef SIGXCPU
- SIGXCPU,
-# endif
-# ifdef SIGXFSZ
- SIGXFSZ,
-# endif
-};
-
- void
-catchints()
-{
- static int catching_ints;
- if (!catching_ints) {
- catching_ints = true;
- setup_catchsig(regsigs, (int) (sizeof(regsigs)/sizeof(*regsigs)));
- }
-}
-
-#if has_mmap && large_memory && mmap_signal
-
- /*
- * If you mmap an NFS file, and someone on another client removes the last
- * link to that file, and you later reference an uncached part of that file,
- * you'll get a SIGBUS or SIGSEGV (depending on the operating system).
- * Catch the signal and report the problem to the user.
- * Unfortunately, there's no portable way to differentiate between this
- * problem and actual bugs in the program.
- * This NFS problem is rare, thank goodness.
- *
- * This can also occur if someone truncates the file, even without NFS.
- */
-
- static int const mmapsigs[] = { mmap_signal };
-
- void
- catchmmapints()
- {
- static int catching_mmap_ints;
- if (!catching_mmap_ints) {
- catching_mmap_ints = true;
- setup_catchsig(mmapsigs, (int)(sizeof(mmapsigs)/sizeof(*mmapsigs)));
- }
- }
-#endif
-
-#endif /* has_signal */
-
-
- void
-fastcopy(inf,outf)
- register RILE *inf;
- FILE *outf;
-/* Function: copies the remainder of file inf to outf.
- */
-{
-#if large_memory
-# if maps_memory
- awrite((char const*)inf->ptr, (size_t)(inf->lim - inf->ptr), outf);
- inf->ptr = inf->lim;
-# else
- for (;;) {
- awrite((char const*)inf->ptr, (size_t)(inf->readlim - inf->ptr), outf);
- inf->ptr = inf->readlim;
- if (inf->ptr == inf->lim)
- break;
- VOID Igetmore(inf);
- }
-# endif
-#else
- char buf[BUFSIZ*8];
- register fread_type rcount;
-
- /*now read the rest of the file in blocks*/
- while (!feof(inf)) {
- if (!(rcount = Fread(buf,sizeof(*buf),sizeof(buf),inf))) {
- testIerror(inf);
- return;
- }
- awrite(buf, (size_t)rcount, outf);
- }
-#endif
-}
-
-#ifndef SSIZE_MAX
- /* This does not work in #ifs, but it's good enough for us. */
- /* Underestimating SSIZE_MAX may slow us down, but it won't break us. */
-# define SSIZE_MAX ((unsigned)-1 >> 1)
-#endif
-
- void
-awrite(buf, chars, f)
- char const *buf;
- size_t chars;
- FILE *f;
-{
- /* Posix 1003.1-1990 ssize_t hack */
- while (SSIZE_MAX < chars) {
- if (Fwrite(buf, sizeof(*buf), SSIZE_MAX, f) != SSIZE_MAX)
- Oerror();
- buf += SSIZE_MAX;
- chars -= SSIZE_MAX;
- }
-
- if (Fwrite(buf, sizeof(*buf), chars, f) != chars)
- Oerror();
-}
-
-/* dup a file descriptor; the result must not be stdin, stdout, or stderr. */
- static int dupSafer P((int));
- static int
-dupSafer(fd)
- int fd;
-{
-# ifdef F_DUPFD
- return fcntl(fd, F_DUPFD, STDERR_FILENO + 1);
-# else
- int e, f, i, used = 0;
- while (STDIN_FILENO <= (f = dup(fd)) && f <= STDERR_FILENO)
- used |= 1<<f;
- e = errno;
- for (i = STDIN_FILENO; i <= STDERR_FILENO; i++)
- if (used & (1<<i))
- VOID close(i);
- errno = e;
- return f;
-# endif
-}
-
-/* Renumber a file descriptor so that it's not stdin, stdout, or stderr. */
- int
-fdSafer(fd)
- int fd;
-{
- if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) {
- int f = dupSafer(fd);
- int e = errno;
- VOID close(fd);
- errno = e;
- fd = f;
- }
- return fd;
-}
-
-/* Like fopen, except the result is never stdin, stdout, or stderr. */
- FILE *
-fopenSafer(filename, type)
- char const *filename;
- char const *type;
-{
- FILE *stream = fopen(filename, type);
- if (stream) {
- int fd = fileno(stream);
- if (STDIN_FILENO <= fd && fd <= STDERR_FILENO) {
- int f = dupSafer(fd);
- if (f < 0) {
- int e = errno;
- VOID fclose(stream);
- errno = e;
- return 0;
- }
- if (fclose(stream) != 0) {
- int e = errno;
- VOID close(f);
- errno = e;
- return 0;
- }
- stream = fdopen(f, type);
- }
- }
- return stream;
-}
-
-
-#ifdef F_DUPFD
-# undef dup
-# define dup(fd) fcntl(fd, F_DUPFD, 0)
-#endif
-
-
-#if has_fork || has_spawn
-
- static int movefd P((int,int));
- static int
-movefd(old, new)
- int old, new;
-{
- if (old < 0 || old == new)
- return old;
-# ifdef F_DUPFD
- new = fcntl(old, F_DUPFD, new);
-# else
- new = dup2(old, new);
-# endif
- return close(old)==0 ? new : -1;
-}
-
- static int fdreopen P((int,char const*,int));
- static int
-fdreopen(fd, file, flags)
- int fd;
- char const *file;
- int flags;
-{
- int newfd;
- VOID close(fd);
- newfd =
-#if !open_can_creat
- flags&O_CREAT ? creat(file, S_IRUSR|S_IWUSR) :
-#endif
- open(file, flags, S_IRUSR|S_IWUSR);
- return movefd(newfd, fd);
-}
-
-#if has_spawn
- static void redirect P((int,int));
- static void
-redirect(old, new)
- int old, new;
-/*
-* Move file descriptor OLD to NEW.
-* If OLD is -1, do nothing.
-* If OLD is -2, just close NEW.
-*/
-{
- if ((old != -1 && close(new) != 0) || (0 <= old && movefd(old,new) < 0))
- efaterror("spawn I/O redirection");
-}
-#endif
-
-
-#else /* !has_fork && !has_spawn */
-
- static void bufargcat P((struct buf*,int,char const*));
- static void
-bufargcat(b, c, s)
- register struct buf *b;
- int c;
- register char const *s;
-/* Append to B a copy of C, plus a quoted copy of S. */
-{
- register char *p;
- register char const *t;
- size_t bl, sl;
-
- for (t=s, sl=0; *t; )
- sl += 3*(*t++=='\'') + 1;
- bl = strlen(b->string);
- bufrealloc(b, bl + sl + 4);
- p = b->string + bl;
- *p++ = c;
- *p++ = '\'';
- while (*s) {
- if (*s == '\'') {
- *p++ = '\'';
- *p++ = '\\';
- *p++ = '\'';
- }
- *p++ = *s++;
- }
- *p++ = '\'';
- *p = 0;
-}
-
-#endif
-
-#if !has_spawn && has_fork
-/*
-* Output the string S to stderr, without touching any I/O buffers.
-* This is useful if you are a child process, whose buffers are usually wrong.
-* Exit immediately if the write does not completely succeed.
-*/
-static void write_stderr P((char const *));
- static void
-write_stderr(s)
- char const *s;
-{
- size_t slen = strlen(s);
- if (write(STDERR_FILENO, s, slen) != slen)
- _exit(EXIT_TROUBLE);
-}
-#endif
-
-/*
-* Run a command.
-* infd, if not -1, is the input file descriptor.
-* outname, if nonzero, is the name of the output file.
-* args[1..] form the command to be run; args[0] might be modified.
-*/
- int
-runv(infd, outname, args)
- int infd;
- char const *outname, **args;
-{
- int wstatus;
-
-#if bad_wait_if_SIGCHLD_ignored
- static int fixed_SIGCHLD;
- if (!fixed_SIGCHLD) {
- fixed_SIGCHLD = true;
-# ifndef SIGCHLD
-# define SIGCHLD SIGCLD
-# endif
- VOID signal(SIGCHLD, SIG_DFL);
- }
-#endif
-
- oflush();
- eflush();
- {
-#if has_spawn
- int in, out;
- char const *file;
-
- in = -1;
- if (infd != -1 && infd != STDIN_FILENO) {
- if ((in = dup(STDIN_FILENO)) < 0) {
- if (errno != EBADF)
- efaterror("spawn input setup");
- in = -2;
- } else {
-# ifdef F_DUPFD
- if (close(STDIN_FILENO) != 0)
- efaterror("spawn input close");
-# endif
- }
- if (
-# ifdef F_DUPFD
- fcntl(infd, F_DUPFD, STDIN_FILENO) != STDIN_FILENO
-# else
- dup2(infd, STDIN_FILENO) != STDIN_FILENO
-# endif
- )
- efaterror("spawn input redirection");
- }
-
- out = -1;
- if (outname) {
- if ((out = dup(STDOUT_FILENO)) < 0) {
- if (errno != EBADF)
- efaterror("spawn output setup");
- out = -2;
- }
- if (fdreopen(
- STDOUT_FILENO, outname,
- O_CREAT | O_TRUNC | O_WRONLY
- ) < 0)
- efaterror(outname);
- }
-
- wstatus = spawn_RCS(0, args[1], (char**)(args + 1));
-# ifdef RCS_SHELL
- if (wstatus == -1 && errno == ENOEXEC) {
- args[0] = RCS_SHELL;
- wstatus = spawnv(0, args[0], (char**)args);
- }
-# endif
- redirect(in, STDIN_FILENO);
- redirect(out, STDOUT_FILENO);
-#else
-#if has_fork
- pid_t pid;
- if (!(pid = vfork())) {
- char const *notfound;
- if (infd != -1 && infd != STDIN_FILENO && (
-# ifdef F_DUPFD
- (VOID close(STDIN_FILENO),
- fcntl(infd, F_DUPFD, STDIN_FILENO) != STDIN_FILENO)
-# else
- dup2(infd, STDIN_FILENO) != STDIN_FILENO
-# endif
- )) {
- /* Avoid perror since it may misuse buffers. */
- write_stderr(args[1]);
- write_stderr(": I/O redirection failed\n");
- _exit(EXIT_TROUBLE);
- }
-
- if (outname)
- if (fdreopen(
- STDOUT_FILENO, outname,
- O_CREAT | O_TRUNC | O_WRONLY
- ) < 0) {
- /* Avoid perror since it may misuse buffers. */
- write_stderr(args[1]);
- write_stderr(": ");
- write_stderr(outname);
- write_stderr(": cannot create\n");
- _exit(EXIT_TROUBLE);
- }
- VOID exec_RCS(args[1], (char**)(args + 1));
- notfound = args[1];
-# ifdef RCS_SHELL
- if (errno == ENOEXEC) {
- args[0] = notfound = RCS_SHELL;
- VOID execv(args[0], (char**)args);
- }
-# endif
-
- /* Avoid perror since it may misuse buffers. */
- write_stderr(notfound);
- write_stderr(": not found\n");
- _exit(EXIT_TROUBLE);
- }
- if (pid < 0)
- efaterror("fork");
-# if has_waitpid
- if (waitpid(pid, &wstatus, 0) < 0)
- efaterror("waitpid");
-# else
- {
- pid_t w;
- do {
- if ((w = wait(&wstatus)) < 0)
- efaterror("wait");
- } while (w != pid);
- }
-# endif
-#else
- static struct buf b;
- char const *p;
-
- /* Use system(). On many hosts system() discards signals. Yuck! */
- p = args + 1;
- bufscpy(&b, *p);
- while (*++p)
- bufargcat(&b, ' ', *p);
- if (infd != -1 && infd != STDIN_FILENO) {
- char redirection[32];
- VOID sprintf(redirection, "<&%d", infd);
- bufscat(&b, redirection);
- }
- if (outname)
- bufargcat(&b, '>', outname);
- wstatus = system(b.string);
-#endif
-#endif
- }
- if (!WIFEXITED(wstatus)) {
- if (WIFSIGNALED(wstatus)) {
- psignal(WTERMSIG(wstatus), args[1]);
- fatcleanup(1);
- }
- faterror("%s failed for unknown reason", args[1]);
- }
- return WEXITSTATUS(wstatus);
-}
-
-#define CARGSMAX 20
-/*
-* Run a command.
-* infd, if not -1, is the input file descriptor.
-* outname, if nonzero, is the name of the output file.
-* The remaining arguments specify the command and its arguments.
-*/
- int
-#if has_prototypes
-run(int infd, char const *outname, ...)
-#else
- /*VARARGS2*/
-run(infd, outname, va_alist)
- int infd;
- char const *outname;
- va_dcl
-#endif
-{
- va_list ap;
- char const *rgargs[CARGSMAX];
- register int i;
- vararg_start(ap, outname);
- for (i = 1; (rgargs[i++] = va_arg(ap, char const*)); )
- if (CARGSMAX <= i)
- faterror("too many command arguments");
- va_end(ap);
- return runv(infd, outname, rgargs);
-}
-
-
-int RCSversion;
-
- void
-setRCSversion(str)
- char const *str;
-{
- static int oldversion;
-
- register char const *s = str + 2;
-
- if (*s) {
- int v = VERSION_DEFAULT;
-
- if (oldversion)
- redefined('V');
- oldversion = true;
- v = 0;
- while (isdigit(*s))
- v = 10*v + *s++ - '0';
- if (*s)
- error("%s isn't a number", str);
- else if (v < VERSION_min || VERSION_max < v)
- error("%s out of range %d..%d",
- str, VERSION_min, VERSION_max
- );
-
- RCSversion = VERSION(v);
- } else {
- printf("RCS version %s\n", RCS_version_string);
- exit(0);
- }
-}
-
- int
-getRCSINIT(argc, argv, newargv)
- int argc;
- char **argv, ***newargv;
-{
- register char *p, *q, **pp;
- char const *ev;
- size_t n;
-
- if ((ev = cgetenv("RCSLOCALID")))
- setRCSLocalId(ev);
-
- if ((ev = cgetenv("RCSINCEXC")))
- setIncExc(ev);
-
- if (!(q = cgetenv("RCSINIT")))
- *newargv = argv;
- else {
- n = argc + 2;
- /*
- * Count spaces in RCSINIT to allocate a new arg vector.
- * This is an upper bound, but it's OK even if too large.
- */
- for (p = q; ; ) {
- switch (*p++) {
- default:
- continue;
-
- case ' ':
- case '\b': case '\f': case '\n':
- case '\r': case '\t': case '\v':
- n++;
- continue;
-
- case '\0':
- break;
- }
- break;
- }
- *newargv = pp = tnalloc(char*, n);
- *pp++ = *argv++; /* copy program name */
- for (p = q; ; ) {
- for (;;) {
- switch (*q) {
- case '\0':
- goto copyrest;
-
- case ' ':
- case '\b': case '\f': case '\n':
- case '\r': case '\t': case '\v':
- q++;
- continue;
- }
- break;
- }
- *pp++ = p;
- ++argc;
- for (;;) {
- switch ((*p++ = *q++)) {
- case '\0':
- goto copyrest;
-
- case '\\':
- if (!*q)
- goto copyrest;
- p[-1] = *q++;
- continue;
-
- default:
- continue;
-
- case ' ':
- case '\b': case '\f': case '\n':
- case '\r': case '\t': case '\v':
- break;
- }
- break;
- }
- p[-1] = '\0';
- }
- copyrest:
- while ((*pp++ = *argv++))
- continue;
- }
- return argc;
-}
-
-
-#define cacheid(E) static uid_t i; static int s; if (!s){ s=1; i=(E); } return i
-
-#if has_getuid
- uid_t ruid() { cacheid(getuid()); }
-#endif
-#if has_setuid
- uid_t euid() { cacheid(geteuid()); }
-#endif
-
-
-#if has_setuid
-
-/*
- * Setuid execution really works only with Posix 1003.1a Draft 5 seteuid(),
- * because it lets us switch back and forth between arbitrary users.
- * If seteuid() doesn't work, we fall back on setuid(),
- * which works if saved setuid is supported,
- * unless the real or effective user is root.
- * This area is such a mess that we always check switches at runtime.
- */
-
- static void
-#if has_prototypes
-set_uid_to(uid_t u)
-#else
- set_uid_to(u) uid_t u;
-#endif
-/* Become user u. */
-{
- static int looping;
-
- if (euid() == ruid())
- return;
-#if (has_fork||has_spawn) && DIFF_ABSOLUTE
-# if has_setreuid
- if (setreuid(u==euid() ? ruid() : euid(), u) != 0)
- efaterror("setuid");
-# else
- if (seteuid(u) != 0)
- efaterror("setuid");
-# endif
-#endif
- if (geteuid() != u) {
- if (looping)
- return;
- looping = true;
- faterror("root setuid not supported" + (u?5:0));
- }
-}
-
-static int stick_with_euid;
-
- void
-/* Ignore all calls to seteid() and setrid(). */
-nosetid()
-{
- stick_with_euid = true;
-}
-
- void
-seteid()
-/* Become effective user. */
-{
- if (!stick_with_euid)
- set_uid_to(euid());
-}
-
- void
-setrid()
-/* Become real user. */
-{
- if (!stick_with_euid)
- set_uid_to(ruid());
-}
-#endif
-
- time_t
-now()
-{
- static time_t t;
- if (!t && time(&t) == -1)
- efaterror("time");
- return t;
-}
diff --git a/gnu/usr.bin/rcs/lib/version.c b/gnu/usr.bin/rcs/lib/version.c
deleted file mode 100644
index 81f5585..0000000
--- a/gnu/usr.bin/rcs/lib/version.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "rcsbase.h"
-char const RCS_version_string[] = "5.7";
diff --git a/gnu/usr.bin/rcs/merge/Makefile b/gnu/usr.bin/rcs/merge/Makefile
deleted file mode 100644
index 9022bc4..0000000
--- a/gnu/usr.bin/rcs/merge/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG= merge
-SRCS= merge.c
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/merge/merge.1 b/gnu/usr.bin/rcs/merge/merge.1
deleted file mode 100644
index a4fd35b..0000000
--- a/gnu/usr.bin/rcs/merge/merge.1
+++ /dev/null
@@ -1,137 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds r \&\s-1RCS\s0
-.TH MERGE 1 \*(Dt GNU
-.SH NAME
-merge \- three-way file merge
-.SH SYNOPSIS
-.B merge
-[
-.I "options"
-]
-.I "file1 file2 file3"
-.SH DESCRIPTION
-.B merge
-incorporates all changes that lead from
-.I file2
-to
-.I file3
-into
-.IR file1 .
-The result ordinarily goes into
-.IR file1 .
-.B merge
-is useful for combining separate changes to an original. Suppose
-.I file2
-is the original, and both
-.I file1
-and
-.I file3
-are modifications of
-.IR file2 .
-Then
-.B merge
-combines both changes.
-.PP
-A conflict occurs if both
-.I file1
-and
-.I file3
-have changes in a common segment of lines.
-If a conflict is found,
-.B merge
-normally outputs a warning and brackets the conflict with
-.B <<<<<<<
-and
-.B >>>>>>>
-lines.
-A typical conflict will look like this:
-.LP
-.RS
-.nf
-.BI <<<<<<< " file A"
-.I "lines in file A"
-.B "======="
-.I "lines in file B"
-.BI >>>>>>> " file B"
-.RE
-.fi
-.LP
-If there are conflicts, the user should edit the result and delete one of the
-alternatives.
-.SH OPTIONS
-.TP
-.B \-A
-Output conflicts using the
-.B \-A
-style of
-.BR diff3 (1),
-if supported by
-.BR diff3 .
-This merges all changes leading from
-.I file2
-to
-.I file3
-into
-.IR file1 ,
-and generates the most verbose output.
-.TP
-\f3\-E\fP, \f3\-e\fP
-These options specify conflict styles that generate less information
-than
-.BR \-A .
-See
-.BR diff3 (1)
-for details.
-The default is
-.BR \-E .
-With
-.BR \-e ,
-.B merge
-does not warn about conflicts.
-.TP
-.BI \-L " label"
-This option may be given up to three times, and specifies labels
-to be used in place of the corresponding file names in conflict reports.
-That is,
-.B "merge\ \-L\ x\ \-L\ y\ \-L\ z\ a\ b\ c"
-generates output that looks like it came from files
-.BR x ,
-.B y
-and
-.B z
-instead of from files
-.BR a ,
-.B b
-and
-.BR c .
-.TP
-.BI \-p
-Send results to standard output instead of overwriting
-.IR file1 .
-.TP
-.BI \-q
-Quiet; do not warn about conflicts.
-.TP
-.BI \-V
-Print \*r's version number.
-.SH DIAGNOSTICS
-Exit status is 0 for no conflicts, 1 for some conflicts, 2 for trouble.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
-.SH SEE ALSO
-diff3(1), diff(1), rcsmerge(1), co(1).
-.SH BUGS
-It normally does not make sense to merge binary files as if they were text, but
-.B merge
-tries to do it anyway.
-.br
diff --git a/gnu/usr.bin/rcs/merge/merge.c b/gnu/usr.bin/rcs/merge/merge.c
deleted file mode 100644
index aa127bf..0000000
--- a/gnu/usr.bin/rcs/merge/merge.c
+++ /dev/null
@@ -1,113 +0,0 @@
-/* merge - three-way file merge */
-
-/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#include "rcsbase.h"
-
-static void badoption P((char const*));
-
-static char const usage[] =
- "\nmerge: usage: merge [-AeEpqxX3] [-L lab [-L lab [-L lab]]] file1 file2 file3";
-
- static void
-badoption(a)
- char const *a;
-{
- error("unknown option: %s%s", a, usage);
-}
-
-
-mainProg(mergeId, "merge", "$FreeBSD$")
-{
- register char const *a;
- char const *arg[3], *label[3], *edarg = 0;
- int labels, tostdout;
-
- labels = 0;
- tostdout = false;
-
- for (; (a = *++argv) && *a++ == '-'; --argc) {
- switch (*a++) {
- case 'A': case 'E': case 'e':
- if (edarg && edarg[1] != (*argv)[1])
- error("%s and %s are incompatible",
- edarg, *argv
- );
- edarg = *argv;
- break;
-
- case 'p': tostdout = true; break;
- case 'q': quietflag = true; break;
-
- case 'L':
- if (3 <= labels)
- faterror("too many -L options");
- if (!(label[labels++] = *++argv))
- faterror("-L needs following argument");
- --argc;
- break;
-
- case 'V':
- printf("RCS version %s\n", RCS_version_string);
- exitmain(0);
-
- default:
- badoption(a - 2);
- continue;
- }
- if (*a)
- badoption(a - 2);
- }
-
- if (argc != 4)
- faterror("%s arguments%s",
- argc<4 ? "not enough" : "too many", usage
- );
-
- /* This copy keeps us `const'-clean. */
- arg[0] = argv[0];
- arg[1] = argv[1];
- arg[2] = argv[2];
-
- for (; labels < 3; labels++)
- label[labels] = arg[labels];
-
- if (nerror)
- exiterr();
- exitmain(merge(tostdout, edarg, label, arg));
-}
-
-
-#if RCS_lint
-# define exiterr mergeExit
-#endif
- void
-exiterr()
-{
- tempunlink();
- _exit(DIFF_TROUBLE);
-}
diff --git a/gnu/usr.bin/rcs/rcs/Makefile b/gnu/usr.bin/rcs/rcs/Makefile
deleted file mode 100644
index aa7cc5f..0000000
--- a/gnu/usr.bin/rcs/rcs/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
-# $FreeBSD$
-
-PROG= rcs
-MAN= rcs.1 rcsintro.1 rcsfile.5
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/rcs/rcs.1 b/gnu/usr.bin/rcs/rcs/rcs.1
deleted file mode 100644
index 37fb59f..0000000
--- a/gnu/usr.bin/rcs/rcs/rcs.1
+++ /dev/null
@@ -1,454 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds r \&\s-1RCS\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.if !\n(.g \{\
-. if !\w|\*(lq| \{\
-. ds lq ``
-. if \w'\(lq' .ds lq "\(lq
-. \}
-. if !\w|\*(rq| \{\
-. ds rq ''
-. if \w'\(rq' .ds rq "\(rq
-. \}
-.\}
-.TH RCS 1 \*(Dt GNU
-.SH NAME
-rcs \- change RCS file attributes
-.SH SYNOPSIS
-.B rcs
-.IR "options file " .\|.\|.
-.SH DESCRIPTION
-.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.
-For
-.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
-.B \-i
-option is present.
-.PP
-Pathnames matching an \*r suffix denote \*r files;
-all others denote working files.
-Names are paired as explained in
-.BR ci (1).
-Revision numbers use the syntax described in
-.BR ci (1).
-.SH OPTIONS
-.TP
-.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
-.BR ./RCS ,
-and then into the current directory.
-If the \*r file
-already exists, print an error message.
-.TP
-.BI \-a "logins"
-Append the login names appearing in the comma-separated list
-.I logins
-to the access list of the \*r file.
-.TP
-.BI \-A "oldfile"
-Append the access list of
-.I oldfile
-to the access list of the \*r file.
-.TP
-.BR \-e [\f2logins\fP]
-Erase the login names appearing in the comma-separated list
-.I logins
-from the access list of the \*r file.
-If
-.I logins
-is omitted, erase the entire access list.
-.TP
-.BR \-b [\f2rev\fP]
-Set the default branch to
-.IR rev .
-If
-.I rev
-is omitted, the default
-branch is reset to the (dynamically) highest branch on the trunk.
-.TP
-.BI \-c string
-Set the comment leader to
-.IR string .
-An initial
-.BR ci ,
-or an
-.B "rcs\ \-i"
-without
-.BR \-c ,
-guesses the comment leader from the suffix of the working filename.
-.RS
-.PP
-This option is obsolescent, since \*r normally uses the preceding
-.B $\&Log$
-line's prefix when inserting log lines during checkout (see
-.BR co (1)).
-However, older versions of \*r use the comment leader instead of the
-.B $\&Log$
-line's prefix, so
-if you plan to access a file with both old and new versions of \*r,
-make sure its comment leader matches its
-.B $\&Log$
-line prefix.
-.RE
-.TP
-.BI \-k subst
-Set the default keyword substitution to
-.IR subst .
-The effect of keyword substitution is described in
-.BR co (1).
-Giving an explicit
-.B \-k
-option to
-.BR co ,
-.BR rcsdiff ,
-and
-.B rcsmerge
-overrides this default.
-Beware
-.BR "rcs\ \-kv",
-because
-.B \-kv
-is incompatible with
-.BR "co\ \-l".
-Use
-.B "rcs\ \-kkv"
-to restore the normal default keyword substitution.
-.TP
-.BR \-l [\f2rev\fP]
-Lock the revision with number
-.IR rev .
-If a branch is given, lock the latest revision on that branch.
-If
-.I rev
-is omitted, lock the latest revision on the default branch.
-Locking prevents overlapping changes.
-If someone else already holds the lock, the lock is broken as with
-.B "rcs\ \-u"
-(see below).
-.TP
-.BR \-u [\f2rev\fP]
-Unlock the revision with number
-.IR rev .
-If a branch is given, unlock the latest revision on that branch.
-If
-.I rev
-is omitted, remove the latest lock held by the caller.
-Normally, only the locker of a revision can 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
-.BR \&. "\ by"
-itself.
-.TP
-.B \-L
-Set locking to
-.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.
-.TP
-.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
-.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.
-.TP
-\f3\-m\fP\f2rev\fP\f3:\fP\f2msg\fP
-Replace revision
-.IR rev 's
-log message with
-.IR msg .
-.TP
-.B \-M
-Do not send mail when breaking somebody else's lock.
-This option is not meant for casual use;
-it is meant for programs that warn users by other means, and invoke
-.B "rcs\ \-u"
-only as a low-level lock-breaking operation.
-.TP
-\f3\-n\fP\f2name\fP[\f3:\fP[\f2rev\fP]]
-Associate the symbolic name
-.I name
-with the branch or
-revision
-.IR rev .
-Delete the symbolic name if both
-.B :
-and
-.I rev
-are omitted; otherwise, print an error message if
-.I name
-is already associated with
-another number.
-If
-.I rev
-is symbolic, it is expanded before association.
-A
-.I rev
-consisting of a branch number followed by a
-.B .\&
-stands for the current latest revision in the branch.
-A
-.B :
-with an empty
-.I rev
-stands for the current latest revision on the default branch,
-normally the trunk.
-For example,
-.BI "rcs\ \-n" name ":\ RCS/*"
-associates
-.I name
-with the current latest revision of all the named \*r files;
-this contrasts with
-.BI "rcs\ \-n" name ":$\ RCS/*"
-which associates
-.I name
-with the revision numbers extracted from keyword strings
-in the corresponding working files.
-.TP
-\f3\-N\fP\f2name\fP[\f3:\fP[\f2rev\fP]]
-Act like
-.BR \-n ,
-except override any previous assignment of
-.IR name .
-.TP
-.BI \-o range
-deletes (\*(lqoutdates\*(rq) the revisions given by
-.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
-.IB rev1 : rev2
-means
-revisions
-.I rev1
-to
-.I rev2
-on the same branch,
-.BI : rev
-means from the beginning of the branch containing
-.I rev
-up to and including
-.IR rev ,
-and
-.IB rev :
-means
-from revision
-.I rev
-to the end of the branch containing
-.IR rev .
-None of the outdated revisions can have branches or locks.
-.TP
-.B \-q
-Run quietly; do not print diagnostics.
-.TP
-.B \-I
-Run interactively, even if the standard input is not a terminal.
-.TP
-.B \-s\f2state\fP\f1[\fP:\f2rev\fP\f1]\fP
-Set the state attribute of the revision
-.I rev
-to
-.IR state .
-If
-.I rev
-is a branch number, assume the latest revision on that branch.
-If
-.I rev
-is omitted, assume the latest revision on the default branch.
-Any identifier is acceptable for
-.IR state .
-A useful set of states
-is
-.B Exp
-(for experimental),
-.B Stab
-(for stable), and
-.B Rel
-(for
-released).
-By default,
-.BR ci (1)
-sets the state of a revision to
-.BR Exp .
-.TP
-.BR \-t [\f2file\fP]
-Write descriptive text from the contents of the named
-.I file
-into the \*r file, deleting the existing text.
-The
-.IR file
-pathname cannot begin with
-.BR \- .
-If
-.I file
-is omitted, obtain the text from standard input,
-terminated by end-of-file or by a line containing
-.BR \&. "\ by"
-itself.
-Prompt for the text if interaction is possible; see
-.BR \-I .
-With
-.BR \-i ,
-descriptive text is obtained
-even if
-.B \-t
-is not given.
-.TP
-.BI \-t\- string
-Write descriptive text from the
-.I string
-into the \*r file, deleting the existing text.
-.TP
-.B \-T
-Preserve the modification time on the \*r file
-unless a revision is removed.
-This option can suppress extensive recompilation caused by a
-.BR make (1)
-dependency of some copy of the working file on the \*r file.
-Use this option with care; it can suppress recompilation even when it is needed,
-i.e. when a change to the \*r file
-would mean a change to keyword strings in the working file.
-.TP
-.BI \-V
-Print \*r's version number.
-.TP
-.BI \-V n
-Emulate \*r version
-.IR n .
-See
-.BR co (1)
-for details.
-.TP
-.BI \-x "suffixes"
-Use
-.I suffixes
-to characterize \*r files.
-See
-.BR ci (1)
-for details.
-.TP
-.BI \-z zone
-Use
-.I zone
-as the default time zone.
-This option has no effect;
-it is present for compatibility with other \*r commands.
-.PP
-At least one explicit option must be given,
-to ensure compatibility with future planned extensions
-to the
-.B rcs
-command.
-.SH COMPATIBILITY
-The
-.BI \-b rev
-option generates an \*r file that cannot be parsed by \*r version 3 or earlier.
-.PP
-The
-.BI \-k subst
-options (except
-.BR \-kkv )
-generate an \*r file that cannot be parsed by \*r version 4 or earlier.
-.PP
-Use
-.BI "rcs \-V" n
-to make an \*r file acceptable to \*r version
-.I n
-by discarding information that would confuse version
-.IR n .
-.PP
-\*r version 5.5 and earlier does not support the
-.B \-x
-option, and requires a
-.B ,v
-suffix on an \*r pathname.
-.SH FILES
-.B rcs
-accesses files much as
-.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
-.B $
-is specified.
-.SH ENVIRONMENT
-.TP
-.B \s-1RCSINIT\s0
-options prepended to the argument list, separated by spaces.
-See
-.BR ci (1)
-for details.
-.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.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
-.SH "SEE ALSO"
-rcsintro(1), co(1), ci(1), ident(1), rcsclean(1), rcsdiff(1),
-rcsmerge(1), rlog(1), rcsfile(5)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.SH BUGS
-A catastrophe (e.g. a system crash) can cause \*r to leave behind
-a semaphore file that causes later invocations of \*r to claim
-that the \*r file is in use.
-To fix this, remove the semaphore file.
-A semaphore file's name typically begins with
-.B ,
-or ends with
-.BR _ .
-.PP
-The separator for revision ranges in the
-.B \-o
-option used to be
-.B \-
-instead of
-.BR : ,
-but this leads to confusion when symbolic names contain
-.BR \- .
-For backwards compatibility
-.B "rcs \-o"
-still supports the old
-.B \-
-separator, but it warns about this obsolete use.
-.PP
-Symbolic names need not refer to existing revisions or branches.
-For example, the
-.B \-o
-option does not remove symbolic names for the outdated revisions; you must use
-.B \-n
-to remove the names.
-.br
diff --git a/gnu/usr.bin/rcs/rcs/rcs.c b/gnu/usr.bin/rcs/rcs/rcs.c
deleted file mode 100644
index dfb622a..0000000
--- a/gnu/usr.bin/rcs/rcs/rcs.c
+++ /dev/null
@@ -1,1629 +0,0 @@
-/* Change RCS file attributes. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.21 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.20 1995/06/01 16:23:43 eggert
- * (main): Warn if no options were given. Punctuate messages properly.
- *
- * (sendmail): Rewind mailmess before flushing it.
- * Output another warning if mail should work but fails.
- *
- * (buildeltatext): Pass "--binary" if -kb and if --binary makes a difference.
- *
- * Revision 5.19 1994/03/17 14:05:48 eggert
- * Use ORCSerror to clean up after a fatal error. Remove lint.
- * Specify subprocess input via file descriptor, not file name. Remove lint.
- * Flush stderr after prompt.
- *
- * Revision 5.18 1993/11/09 17:40:15 eggert
- * -V now prints version on stdout and exits. Don't print usage twice.
- *
- * Revision 5.17 1993/11/03 17:42:27 eggert
- * Add -z. Don't lose track of -m or -t when there are no other changes.
- * Don't discard ignored phrases. Improve quality of diagnostics.
- *
- * Revision 5.16 1992/07/28 16:12:44 eggert
- * rcs -l now asks whether you want to break the lock.
- * Add -V. Set RCS file's mode and time at right moment.
- *
- * Revision 5.15 1992/02/17 23:02:20 eggert
- * Add -T.
- *
- * Revision 5.14 1992/01/27 16:42:53 eggert
- * Add -M. Avoid invoking umask(); it's one less thing to configure.
- * Add support for bad_creat0. lint -> RCS_lint
- *
- * Revision 5.13 1992/01/06 02:42:34 eggert
- * Avoid changing RCS file in common cases where no change can occur.
- *
- * Revision 5.12 1991/11/20 17:58:08 eggert
- * Don't read the delta tree from a nonexistent RCS file.
- *
- * Revision 5.11 1991/10/07 17:32:46 eggert
- * Remove lint.
- *
- * Revision 5.10 1991/08/19 23:17:54 eggert
- * Add -m, -r$, piece tables. Revision separator is `:', not `-'. Tune.
- *
- * Revision 5.9 1991/04/21 11:58:18 eggert
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.8 1991/02/25 07:12:38 eggert
- * strsave -> str_save (DG/UX name clash)
- * 0444 -> S_IRUSR|S_IRGRP|S_IROTH for portability
- *
- * Revision 5.7 1990/12/18 17:19:21 eggert
- * Fix bug with multiple -n and -N options.
- *
- * Revision 5.6 1990/12/04 05:18:40 eggert
- * Use -I for prompts and -q for diagnostics.
- *
- * Revision 5.5 1990/11/11 00:06:35 eggert
- * Fix `rcs -e' core dump.
- *
- * Revision 5.4 1990/11/01 05:03:33 eggert
- * Add -I and new -t behavior. Permit arbitrary data in logs.
- *
- * Revision 5.3 1990/10/04 06:30:16 eggert
- * Accumulate exit status across files.
- *
- * Revision 5.2 1990/09/04 08:02:17 eggert
- * Standardize yes-or-no procedure.
- *
- * Revision 5.1 1990/08/29 07:13:51 eggert
- * Remove unused setuid support. Clean old log messages too.
- *
- * Revision 5.0 1990/08/22 08:12:42 eggert
- * Don't lose names when applying -a option to multiple files.
- * Remove compile-time limits; use malloc instead. Add setuid support.
- * Permit dates past 1999/12/31. Make lock and temp files faster and safer.
- * Ansify and Posixate. Add -V. Fix umask bug. Make linting easier. Tune.
- * Yield proper exit status. Check diff's output.
- *
- * Revision 4.11 89/05/01 15:12:06 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.10 88/11/08 16:01:54 narten
- * didn't install previous patch correctly
- *
- * Revision 4.9 88/11/08 13:56:01 narten
- * removed include <sysexits.h> (not needed)
- * minor fix for -A option
- *
- * Revision 4.8 88/08/09 19:12:27 eggert
- * Don't access freed storage.
- * Use execv(), not system(); yield proper exit status; remove lint.
- *
- * Revision 4.7 87/12/18 11:37:17 narten
- * lint cleanups (Guy Harris)
- *
- * Revision 4.6 87/10/18 10:28:48 narten
- * Updating verison numbers. Changes relative to 1.1 are actually
- * relative to 4.3
- *
- * Revision 1.4 87/09/24 13:58:52 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.3 87/03/27 14:21:55 jenkins
- * Port to suns
- *
- * Revision 1.2 85/12/17 13:59:09 albitz
- * Changed setstate to rcs_setstate because of conflict with random.o.
- *
- * Revision 4.3 83/12/15 12:27:33 wft
- * rcs -u now breaks most recent lock if it can't find a lock by the caller.
- *
- * Revision 4.2 83/12/05 10:18:20 wft
- * Added conditional compilation for sending mail.
- * Alternatives: V4_2BSD, V6, USG, and other.
- *
- * Revision 4.1 83/05/10 16:43:02 wft
- * Simplified breaklock(); added calls to findlock() and getcaller().
- * Added option -b (default branch). Updated -s and -w for -b.
- * Removed calls to stat(); now done by pairfilenames().
- * Replaced most catchints() calls with restoreints().
- * Removed check for exit status of delivermail().
- * Directed all interactive output to stderr.
- *
- * Revision 3.9.1.1 83/12/02 22:08:51 wft
- * Added conditional compilation for 4.2 sendmail and 4.1 delivermail.
- *
- * Revision 3.9 83/02/15 15:38:39 wft
- * Added call to fastcopy() to copy remainder of RCS file.
- *
- * Revision 3.8 83/01/18 17:37:51 wft
- * Changed sendmail(): now uses delivermail, and asks whether to break the lock.
- *
- * Revision 3.7 83/01/15 18:04:25 wft
- * Removed putree(); replaced with puttree() in rcssyn.c.
- * Combined putdellog() and scanlogtext(); deleted putdellog().
- * Cleaned up diagnostics and error messages. Fixed problem with
- * mutilated files in case of deletions in 2 files in a single command.
- * Changed marking of selector from 'D' to DELETE.
- *
- * Revision 3.6 83/01/14 15:37:31 wft
- * Added ignoring of interrupts while new RCS file is renamed;
- * Avoids deletion of RCS files by interrupts.
- *
- * Revision 3.5 82/12/10 21:11:39 wft
- * Removed unused variables, fixed checking of return code from diff,
- * introduced variant COMPAT2 for skipping Suffix on -A files.
- *
- * Revision 3.4 82/12/04 13:18:20 wft
- * Replaced getdelta() with gettree(), changed breaklock to update
- * field lockedby, added some diagnostics.
- *
- * Revision 3.3 82/12/03 17:08:04 wft
- * Replaced getlogin() with getpwuid(), flcose() with ffclose(),
- * /usr/ucb/Mail with macro MAIL. Removed handling of Suffix (-x).
- * fixed -u for missing revno. Disambiguated structure members.
- *
- * Revision 3.2 82/10/18 21:05:07 wft
- * rcs -i now generates a file mode given by the umask minus write permission;
- * otherwise, rcs keeps the mode, but removes write permission.
- * I added a check for write error, fixed call to getlogin(), replaced
- * curdir() with getfullRCSname(), cleaned up handling -U/L, and changed
- * conflicting, long identifiers.
- *
- * Revision 3.1 82/10/13 16:11:07 wft
- * fixed type of variables receiving from getc() (char -> int).
- */
-
-
-#include "rcsbase.h"
-
-struct Lockrev {
- char const *revno;
- struct Lockrev * nextrev;
-};
-
-struct Symrev {
- char const *revno;
- char const *ssymbol;
- int override;
- struct Symrev * nextsym;
-};
-
-struct Message {
- char const *revno;
- struct cbuf message;
- struct Message *nextmessage;
-};
-
-struct Status {
- char const *revno;
- char const *status;
- struct Status * nextstatus;
-};
-
-enum changeaccess {append, erase};
-struct chaccess {
- char const *login;
- enum changeaccess command;
- struct chaccess *nextchaccess;
-};
-
-struct delrevpair {
- char const *strt;
- char const *end;
- int code;
-};
-
-static int branchpoint P((struct hshentry*,struct hshentry*));
-static int breaklock P((struct hshentry const*));
-static int buildeltatext P((struct hshentries const*));
-static int doaccess P((void));
-static int doassoc P((void));
-static int dolocks P((void));
-static int domessages P((void));
-static int rcs_setstate P((char const*,char const*));
-static int removerevs P((void));
-static int sendmail P((char const*,char const*));
-static int setlock P((char const*));
-static struct Lockrev **rmnewlocklst P((char const*));
-static struct hshentry *searchcutpt P((char const*,int,struct hshentries*));
-static void buildtree P((void));
-static void cleanup P((void));
-static void getaccessor P((char*,enum changeaccess));
-static void getassoclst P((int,char*));
-static void getchaccess P((char const*,enum changeaccess));
-static void getdelrev P((char*));
-static void getmessage P((char*));
-static void getstates P((char*));
-static void scanlogtext P((struct hshentry*,int));
-
-static struct buf numrev;
-static char const *headstate;
-static int chgheadstate, exitstatus, lockhead, unlockcaller;
-static int suppress_mail;
-static struct Lockrev *newlocklst, *rmvlocklst;
-static struct Message *messagelst, **nextmessage;
-static struct Status *statelst, **nextstate;
-static struct Symrev *assoclst, **nextassoc;
-static struct chaccess *chaccess, **nextchaccess;
-static struct delrevpair delrev;
-static struct hshentry *cuthead, *cuttail, *delstrt;
-static struct hshentries *gendeltas;
-
-mainProg(rcsId, "rcs", "$FreeBSD$")
-{
- static char const cmdusage[] =
- "\nrcs usage: rcs -{ae}logins -Afile -{blu}[rev] -cstring -{iILqTU} -ksubst -mrev:msg -{nN}name[:[rev]] -orange -sstate[:rev] -t[text] -Vn -xsuff -zzone file ...";
-
- char *a, **newargv, *textfile;
- char const *branchsym, *commsyml;
- int branchflag, changed, expmode, initflag;
- int strictlock, strict_selected, textflag;
- int keepRCStime, Ttimeflag;
- size_t commsymlen;
- struct buf branchnum;
- struct Lockrev *lockpt;
- struct Lockrev **curlock, **rmvlock;
- struct Status * curstate;
-
- nosetid();
-
- nextassoc = &assoclst;
- nextchaccess = &chaccess;
- nextmessage = &messagelst;
- nextstate = &statelst;
- branchsym = commsyml = textfile = 0;
- branchflag = strictlock = false;
- bufautobegin(&branchnum);
- commsymlen = 0;
- curlock = &newlocklst;
- rmvlock = &rmvlocklst;
- expmode = -1;
- suffixes = X_DEFAULT;
- initflag= textflag = false;
- strict_selected = 0;
- Ttimeflag = false;
-
- /* preprocessing command options */
- if (1 < argc && argv[1][0] != '-')
- warn("No options were given; this usage is obsolescent.");
-
- argc = getRCSINIT(argc, argv, &newargv);
- argv = newargv;
- while (a = *++argv, 0<--argc && *a++=='-') {
- switch (*a++) {
-
- case 'i': /* initial version */
- initflag = true;
- break;
-
- case 'b': /* change default branch */
- if (branchflag) redefined('b');
- branchflag= true;
- branchsym = a;
- break;
-
- case 'c': /* change comment symbol */
- if (commsyml) redefined('c');
- commsyml = a;
- commsymlen = strlen(a);
- break;
-
- case 'a': /* add new accessor */
- getaccessor(*argv+1, append);
- break;
-
- case 'A': /* append access list according to accessfile */
- if (!*a) {
- error("missing pathname after -A");
- break;
- }
- *argv = a;
- if (0 < pairnames(1,argv,rcsreadopen,true,false)) {
- while (AccessList) {
- getchaccess(str_save(AccessList->login),append);
- AccessList = AccessList->nextaccess;
- }
- Izclose(&finptr);
- }
- break;
-
- case 'e': /* remove accessors */
- getaccessor(*argv+1, erase);
- break;
-
- case 'l': /* lock a revision if it is unlocked */
- if (!*a) {
- /* Lock head or default branch. */
- lockhead = true;
- break;
- }
- *curlock = lockpt = talloc(struct Lockrev);
- lockpt->revno = a;
- lockpt->nextrev = 0;
- curlock = &lockpt->nextrev;
- break;
-
- case 'u': /* release lock of a locked revision */
- if (!*a) {
- unlockcaller=true;
- break;
- }
- *rmvlock = lockpt = talloc(struct Lockrev);
- lockpt->revno = a;
- lockpt->nextrev = 0;
- rmvlock = &lockpt->nextrev;
- curlock = rmnewlocklst(lockpt->revno);
- break;
-
- case 'L': /* set strict locking */
- if (strict_selected) {
- if (!strictlock) /* Already selected -U? */
- warn("-U overridden by -L");
- }
- strictlock = true;
- strict_selected = true;
- break;
-
- case 'U': /* release strict locking */
- if (strict_selected) {
- if (strictlock) /* Already selected -L? */
- warn("-L overridden by -U");
- }
- strict_selected = true;
- break;
-
- case 'n': /* add new association: error, if name exists */
- if (!*a) {
- error("missing symbolic name after -n");
- break;
- }
- getassoclst(false, (*argv)+1);
- break;
-
- case 'N': /* add or change association */
- if (!*a) {
- error("missing symbolic name after -N");
- break;
- }
- getassoclst(true, (*argv)+1);
- break;
-
- case 'm': /* change log message */
- getmessage(a);
- break;
-
- case 'M': /* do not send mail */
- suppress_mail = true;
- break;
-
- case 'o': /* delete revisions */
- if (delrev.strt) redefined('o');
- if (!*a) {
- error("missing revision range after -o");
- break;
- }
- getdelrev( (*argv)+1 );
- break;
-
- case 's': /* change state attribute of a revision */
- if (!*a) {
- error("state missing after -s");
- break;
- }
- getstates( (*argv)+1);
- break;
-
- case 't': /* change descriptive text */
- textflag=true;
- if (*a) {
- if (textfile) redefined('t');
- textfile = a;
- }
- break;
-
- case 'T': /* do not update last-mod time for minor changes */
- if (*a)
- goto unknown;
- Ttimeflag = true;
- break;
-
- case 'I':
- interactiveflag = true;
- break;
-
- case 'q':
- quietflag = true;
- break;
-
- case 'x':
- suffixes = a;
- break;
-
- case 'V':
- setRCSversion(*argv);
- break;
-
- case 'z':
- zone_set(a);
- break;
-
- case 'k': /* set keyword expand mode */
- if (0 <= expmode) redefined('k');
- if (0 <= (expmode = str2expmode(a)))
- break;
- /* fall into */
- default:
- unknown:
- error("unknown option: %s%s", *argv, cmdusage);
- };
- } /* end processing of options */
-
- /* Now handle all pathnames. */
- if (nerror) cleanup();
- else if (argc < 1) faterror("no input file%s", cmdusage);
- else for (; 0 < argc; cleanup(), ++argv, --argc) {
-
- ffree();
-
- if ( initflag ) {
- switch (pairnames(argc, argv, rcswriteopen, false, false)) {
- case -1: break; /* not exist; ok */
- case 0: continue; /* error */
- case 1: rcserror("already exists");
- continue;
- }
- }
- else {
- switch (pairnames(argc, argv, rcswriteopen, true, false)) {
- case -1: continue; /* not exist */
- case 0: continue; /* errors */
- case 1: break; /* file exists; ok*/
- }
- }
-
-
- /*
- * RCSname contains the name of the RCS file, and
- * workname contains the name of the working file.
- * if !initflag, finptr contains the file descriptor for the
- * RCS file. The admin node is initialized.
- */
-
- diagnose("RCS file: %s\n", RCSname);
-
- changed = initflag | textflag;
- keepRCStime = Ttimeflag;
- if (!initflag) {
- if (!checkaccesslist()) continue;
- gettree(); /* Read the delta tree. */
- }
-
- /* update admin. node */
- if (strict_selected) {
- changed |= StrictLocks ^ strictlock;
- StrictLocks = strictlock;
- }
- if (
- commsyml &&
- (
- commsymlen != Comment.size ||
- memcmp(commsyml, Comment.string, commsymlen) != 0
- )
- ) {
- Comment.string = commsyml;
- Comment.size = strlen(commsyml);
- changed = true;
- }
- if (0 <= expmode && Expand != expmode) {
- Expand = expmode;
- changed = true;
- }
-
- /* update default branch */
- if (branchflag && expandsym(branchsym, &branchnum)) {
- if (countnumflds(branchnum.string)) {
- if (cmpnum(Dbranch, branchnum.string) != 0) {
- Dbranch = branchnum.string;
- changed = true;
- }
- } else
- if (Dbranch) {
- Dbranch = 0;
- changed = true;
- }
- }
-
- changed |= doaccess(); /* Update access list. */
-
- changed |= doassoc(); /* Update association list. */
-
- changed |= dolocks(); /* Update locks. */
-
- changed |= domessages(); /* Update log messages. */
-
- /* update state attribution */
- if (chgheadstate) {
- /* change state of default branch or head */
- if (!Dbranch) {
- if (!Head)
- rcswarn("can't change states in an empty tree");
- else if (strcmp(Head->state, headstate) != 0) {
- Head->state = headstate;
- changed = true;
- }
- } else
- changed |= rcs_setstate(Dbranch,headstate);
- }
- for (curstate = statelst; curstate; curstate = curstate->nextstatus)
- changed |= rcs_setstate(curstate->revno,curstate->status);
-
- cuthead = cuttail = 0;
- if (delrev.strt && removerevs()) {
- /* rebuild delta tree if some deltas are deleted */
- if ( cuttail )
- VOID genrevs(
- cuttail->num, (char *)0, (char *)0, (char *)0,
- &gendeltas
- );
- buildtree();
- changed = true;
- keepRCStime = false;
- }
-
- if (nerror)
- continue;
-
- putadmin();
- if ( Head )
- puttree(Head, frewrite);
- putdesc(textflag,textfile);
-
- if ( Head) {
- if (delrev.strt || messagelst) {
- if (!cuttail || buildeltatext(gendeltas)) {
- advise_access(finptr, MADV_SEQUENTIAL);
- scanlogtext((struct hshentry *)0, false);
- /* copy rest of delta text nodes that are not deleted */
- changed = true;
- }
- }
- }
-
- if (initflag) {
- /* Adjust things for donerewrite's sake. */
- if (stat(workname, &RCSstat) != 0) {
-# if bad_creat0
- mode_t m = umask(0);
- (void) umask(m);
- RCSstat.st_mode = (S_IRUSR|S_IRGRP|S_IROTH) & ~m;
-# else
- changed = -1;
-# endif
- }
- RCSstat.st_nlink = 0;
- keepRCStime = false;
- }
- if (donerewrite(changed,
- keepRCStime ? RCSstat.st_mtime : (time_t)-1
- ) != 0)
- break;
-
- diagnose("done\n");
- }
-
- tempunlink();
- exitmain(exitstatus);
-} /* end of main (rcs) */
-
- static void
-cleanup()
-{
- if (nerror) exitstatus = EXIT_FAILURE;
- Izclose(&finptr);
- Ozclose(&fcopy);
- ORCSclose();
- dirtempunlink();
-}
-
- void
-exiterr()
-{
- ORCSerror();
- dirtempunlink();
- tempunlink();
- _exit(EXIT_FAILURE);
-}
-
-
- static void
-getassoclst(flag, sp)
-int flag;
-char * sp;
-/* Function: associate a symbolic name to a revision or branch, */
-/* and store in assoclst */
-
-{
- struct Symrev * pt;
- char const *temp;
- int c;
-
- while ((c = *++sp) == ' ' || c == '\t' || c =='\n')
- continue;
- temp = sp;
- sp = checksym(sp, ':'); /* check for invalid symbolic name */
- c = *sp; *sp = '\0';
- while( c == ' ' || c == '\t' || c == '\n') c = *++sp;
-
- if ( c != ':' && c != '\0') {
- error("invalid string %s after option -n or -N",sp);
- return;
- }
-
- pt = talloc(struct Symrev);
- pt->ssymbol = temp;
- pt->override = flag;
- if (c == '\0') /* delete symbol */
- pt->revno = 0;
- else {
- while ((c = *++sp) == ' ' || c == '\n' || c == '\t')
- continue;
- pt->revno = sp;
- }
- pt->nextsym = 0;
- *nextassoc = pt;
- nextassoc = &pt->nextsym;
-}
-
-
- static void
-getchaccess(login, command)
- char const *login;
- enum changeaccess command;
-{
- register struct chaccess *pt;
-
- pt = talloc(struct chaccess);
- pt->login = login;
- pt->command = command;
- pt->nextchaccess = 0;
- *nextchaccess = pt;
- nextchaccess = &pt->nextchaccess;
-}
-
-
-
- static void
-getaccessor(opt, command)
- char *opt;
- enum changeaccess command;
-/* Function: get the accessor list of options -e and -a, */
-/* and store in chaccess */
-
-
-{
- register c;
- register char *sp;
-
- sp = opt;
- while ((c = *++sp) == ' ' || c == '\n' || c == '\t' || c == ',')
- continue;
- if ( c == '\0') {
- if (command == erase && sp-opt == 1) {
- getchaccess((char*)0, command);
- return;
- }
- error("missing login name after option -a or -e");
- return;
- }
-
- while( c != '\0') {
- getchaccess(sp, command);
- sp = checkid(sp,',');
- c = *sp; *sp = '\0';
- while( c == ' ' || c == '\n' || c == '\t'|| c == ',')c =(*++sp);
- }
-}
-
-
- static void
-getmessage(option)
- char *option;
-{
- struct Message *pt;
- struct cbuf cb;
- char *m;
-
- if (!(m = strchr(option, ':'))) {
- error("-m option lacks revision number");
- return;
- }
- *m++ = 0;
- cb = cleanlogmsg(m, strlen(m));
- if (!cb.size) {
- error("-m option lacks log message");
- return;
- }
- pt = talloc(struct Message);
- pt->revno = option;
- pt->message = cb;
- pt->nextmessage = 0;
- *nextmessage = pt;
- nextmessage = &pt->nextmessage;
-}
-
-
- static void
-getstates(sp)
-char *sp;
-/* Function: get one state attribute and the corresponding */
-/* revision and store in statelst */
-
-{
- char const *temp;
- struct Status *pt;
- register c;
-
- while ((c = *++sp) ==' ' || c == '\t' || c == '\n')
- continue;
- temp = sp;
- sp = checkid(sp,':'); /* check for invalid state attribute */
- c = *sp; *sp = '\0';
- while( c == ' ' || c == '\t' || c == '\n' ) c = *++sp;
-
- if ( c == '\0' ) { /* change state of def. branch or Head */
- chgheadstate = true;
- headstate = temp;
- return;
- }
- else if ( c != ':' ) {
- error("missing ':' after state in option -s");
- return;
- }
-
- while ((c = *++sp) == ' ' || c == '\t' || c == '\n')
- continue;
- pt = talloc(struct Status);
- pt->status = temp;
- pt->revno = sp;
- pt->nextstatus = 0;
- *nextstate = pt;
- nextstate = &pt->nextstatus;
-}
-
-
-
- static void
-getdelrev(sp)
-char *sp;
-/* Function: get revision range or branch to be deleted, */
-/* and place in delrev */
-{
- int c;
- struct delrevpair *pt;
- int separator;
-
- pt = &delrev;
- while ((c = (*++sp)) == ' ' || c == '\n' || c == '\t')
- continue;
-
- /* Support old ambiguous '-' syntax; this will go away. */
- if (strchr(sp,':'))
- separator = ':';
- else {
- if (strchr(sp,'-') && VERSION(5) <= RCSversion)
- warn("`-' is obsolete in `-o%s'; use `:' instead", sp);
- separator = '-';
- }
-
- if (c == separator) { /* -o:rev */
- while ((c = (*++sp)) == ' ' || c == '\n' || c == '\t')
- continue;
- pt->strt = sp; pt->code = 1;
- while( c != ' ' && c != '\n' && c != '\t' && c != '\0') c =(*++sp);
- *sp = '\0';
- pt->end = 0;
- return;
- }
- else {
- pt->strt = sp;
- while( c != ' ' && c != '\n' && c != '\t' && c != '\0'
- && c != separator ) c = *++sp;
- *sp = '\0';
- while( c == ' ' || c == '\n' || c == '\t' ) c = *++sp;
- if ( c == '\0' ) { /* -o rev or branch */
- pt->code = 0;
- pt->end = 0;
- return;
- }
- if (c != separator) {
- error("invalid range %s %s after -o", pt->strt, sp);
- }
- while ((c = *++sp) == ' ' || c == '\n' || c == '\t')
- continue;
- if (!c) { /* -orev: */
- pt->code = 2;
- pt->end = 0;
- return;
- }
- }
- /* -orev1:rev2 */
- pt->end = sp; pt->code = 3;
- while( c!= ' ' && c != '\n' && c != '\t' && c != '\0') c = *++sp;
- *sp = '\0';
-}
-
-
-
-
- static void
-scanlogtext(delta,edit)
- struct hshentry *delta;
- int edit;
-/* Function: Scans delta text nodes up to and including the one given
- * by delta, or up to last one present, if !delta.
- * For the one given by delta (if delta), the log message is saved into
- * delta->log if delta==cuttail; the text is edited if EDIT is set, else copied.
- * Assumes the initial lexeme must be read in first.
- * Does not advance nexttok after it is finished, except if !delta.
- */
-{
- struct hshentry const *nextdelta;
- struct cbuf cb;
-
- for (;;) {
- foutptr = 0;
- if (eoflex()) {
- if(delta)
- rcsfaterror("can't find delta for revision %s",
- delta->num
- );
- return; /* no more delta text nodes */
- }
- nextlex();
- if (!(nextdelta=getnum()))
- fatserror("delta number corrupted");
- if (nextdelta->selector) {
- foutptr = frewrite;
- aprintf(frewrite,DELNUMFORM,nextdelta->num,Klog);
- }
- getkeystring(Klog);
- if (nextdelta == cuttail) {
- cb = savestring(&curlogbuf);
- if (!delta->log.string)
- delta->log = cleanlogmsg(curlogbuf.string, cb.size);
- nextlex();
- delta->igtext = getphrases(Ktext);
- } else {
- if (nextdelta->log.string && nextdelta->selector) {
- foutptr = 0;
- readstring();
- foutptr = frewrite;
- putstring(foutptr, false, nextdelta->log, true);
- afputc(nextc, foutptr);
- } else
- readstring();
- ignorephrases(Ktext);
- }
- getkeystring(Ktext);
-
- if (delta==nextdelta)
- break;
- readstring(); /* skip over it */
-
- }
- /* got the one we're looking for */
- if (edit)
- editstring((struct hshentry*)0);
- else
- enterstring();
-}
-
-
-
- static struct Lockrev **
-rmnewlocklst(which)
- char const *which;
-/* Remove lock to revision WHICH from newlocklst. */
-{
- struct Lockrev *pt, **pre;
-
- pre = &newlocklst;
- while ((pt = *pre))
- if (strcmp(pt->revno, which) != 0)
- pre = &pt->nextrev;
- else {
- *pre = pt->nextrev;
- tfree(pt);
- }
- return pre;
-}
-
-
-
- static int
-doaccess()
-{
- register struct chaccess *ch;
- register struct access **p, *t;
- register int changed = false;
-
- for (ch = chaccess; ch; ch = ch->nextchaccess) {
- switch (ch->command) {
- case erase:
- if (!ch->login) {
- if (AccessList) {
- AccessList = 0;
- changed = true;
- }
- } else
- for (p = &AccessList; (t = *p); p = &t->nextaccess)
- if (strcmp(ch->login, t->login) == 0) {
- *p = t->nextaccess;
- changed = true;
- break;
- }
- break;
- case append:
- for (p = &AccessList; ; p = &t->nextaccess)
- if (!(t = *p)) {
- *p = t = ftalloc(struct access);
- t->login = ch->login;
- t->nextaccess = 0;
- changed = true;
- break;
- } else if (strcmp(ch->login, t->login) == 0)
- break;
- break;
- }
- }
- return changed;
-}
-
-
- static int
-sendmail(Delta, who)
- char const *Delta, *who;
-/* Function: mail to who, informing him that his lock on delta was
- * broken by caller. Ask first whether to go ahead. Return false on
- * error or if user decides not to break the lock.
- */
-{
-#ifdef SENDMAIL
- char const *messagefile;
- int old1, old2, c, status;
- FILE * mailmess;
-#endif
-
-
- aprintf(stderr, "Revision %s is already locked by %s.\n", Delta, who);
- if (suppress_mail)
- return true;
- if (!yesorno(false, "Do you want to break the lock? [ny](n): "))
- return false;
-
- /* go ahead with breaking */
-#ifdef SENDMAIL
- messagefile = maketemp(0);
- if (!(mailmess = fopenSafer(messagefile, "w+"))) {
- efaterror(messagefile);
- }
-
- aprintf(mailmess, "Subject: Broken lock on %s\n\nYour lock on revision %s of file %s\nhas been broken by %s for the following reason:\n",
- basefilename(RCSname), Delta, getfullRCSname(), getcaller()
- );
- aputs("State the reason for breaking the lock:\n(terminate with single '.' or end of file)\n>> ", stderr);
- eflush();
-
- old1 = '\n'; old2 = ' ';
- for (; ;) {
- c = getcstdin();
- if (feof(stdin)) {
- aprintf(mailmess, "%c\n", old1);
- break;
- }
- else if ( c == '\n' && old1 == '.' && old2 == '\n')
- break;
- else {
- afputc(old1, mailmess);
- old2 = old1; old1 = c;
- if (c == '\n') {
- aputs(">> ", stderr);
- eflush();
- }
- }
- }
- Orewind(mailmess);
- aflush(mailmess);
- status = run(fileno(mailmess), (char*)0, SENDMAIL, who, (char*)0);
- Ozclose(&mailmess);
- if (status == 0)
- return true;
- warn("Mail failed.");
-#endif
- warn("Mail notification of broken locks is not available.");
- warn("Please tell `%s' why you broke the lock.", who);
- return(true);
-}
-
-
-
- static int
-breaklock(delta)
- struct hshentry const *delta;
-/* function: Finds the lock held by caller on delta,
- * and removes it.
- * Sends mail if a lock different from the caller's is broken.
- * Prints an error message if there is no such lock or error.
- */
-{
- register struct rcslock *next, **trail;
- char const *num;
-
- num=delta->num;
- for (trail = &Locks; (next = *trail); trail = &next->nextlock)
- if (strcmp(num, next->delta->num) == 0) {
- if (
- strcmp(getcaller(),next->login) != 0
- && !sendmail(num, next->login)
- ) {
- rcserror("revision %s still locked by %s",
- num, next->login
- );
- return false;
- }
- diagnose("%s unlocked\n", next->delta->num);
- *trail = next->nextlock;
- next->delta->lockedby = 0;
- return true;
- }
- rcserror("no lock set on revision %s", num);
- return false;
-}
-
-
-
- static struct hshentry *
-searchcutpt(object, length, store)
- char const *object;
- int length;
- struct hshentries *store;
-/* Function: Search store and return entry with number being object. */
-/* cuttail = 0, if the entry is Head; otherwise, cuttail */
-/* is the entry point to the one with number being object */
-
-{
- cuthead = 0;
- while (compartial(store->first->num, object, length)) {
- cuthead = store->first;
- store = store->rest;
- }
- return store->first;
-}
-
-
-
- static int
-branchpoint(strt, tail)
-struct hshentry *strt, *tail;
-/* Function: check whether the deltas between strt and tail */
-/* are locked or branch point, return 1 if any is */
-/* locked or branch point; otherwise, return 0 and */
-/* mark deleted */
-
-{
- struct hshentry *pt;
- struct rcslock const *lockpt;
-
- for (pt = strt; pt != tail; pt = pt->next) {
- if ( pt->branches ){ /* a branch point */
- rcserror("can't remove branch point %s", pt->num);
- return true;
- }
- for (lockpt = Locks; lockpt; lockpt = lockpt->nextlock)
- if (lockpt->delta == pt) {
- rcserror("can't remove locked revision %s", pt->num);
- return true;
- }
- pt->selector = false;
- diagnose("deleting revision %s\n",pt->num);
- }
- return false;
-}
-
-
-
- static int
-removerevs()
-/* Function: get the revision range to be removed, and place the */
-/* first revision removed in delstrt, the revision before */
-/* delstrt in cuthead (0, if delstrt is head), and the */
-/* revision after the last removed revision in cuttail (0 */
-/* if the last is a leaf */
-
-{
- struct hshentry *target, *target2, *temp;
- int length;
- int cmp;
-
- if (!expandsym(delrev.strt, &numrev)) return 0;
- target = genrevs(numrev.string,(char*)0,(char*)0,(char*)0,&gendeltas);
- if ( ! target ) return 0;
- cmp = cmpnum(target->num, numrev.string);
- length = countnumflds(numrev.string);
-
- if (delrev.code == 0) { /* -o rev or -o branch */
- if (length & 1)
- temp=searchcutpt(target->num,length+1,gendeltas);
- else if (cmp) {
- rcserror("Revision %s doesn't exist.", numrev.string);
- return 0;
- }
- else
- temp = searchcutpt(numrev.string, length, gendeltas);
- cuttail = target->next;
- if ( branchpoint(temp, cuttail) ) {
- cuttail = 0;
- return 0;
- }
- delstrt = temp; /* first revision to be removed */
- return 1;
- }
-
- if (length & 1) { /* invalid branch after -o */
- rcserror("invalid branch range %s after -o", numrev.string);
- return 0;
- }
-
- if (delrev.code == 1) { /* -o -rev */
- if ( length > 2 ) {
- temp = searchcutpt( target->num, length-1, gendeltas);
- cuttail = target->next;
- }
- else {
- temp = searchcutpt(target->num, length, gendeltas);
- cuttail = target;
- while( cuttail && ! cmpnumfld(target->num,cuttail->num,1) )
- cuttail = cuttail->next;
- }
- if ( branchpoint(temp, cuttail) ){
- cuttail = 0;
- return 0;
- }
- delstrt = temp;
- return 1;
- }
-
- if (delrev.code == 2) { /* -o rev- */
- if ( length == 2 ) {
- temp = searchcutpt(target->num, 1,gendeltas);
- if (cmp)
- cuttail = target;
- else
- cuttail = target->next;
- }
- else {
- if (cmp) {
- cuthead = target;
- if ( !(temp = target->next) ) return 0;
- }
- else
- temp = searchcutpt(target->num, length, gendeltas);
- getbranchno(temp->num, &numrev); /* get branch number */
- VOID genrevs(numrev.string, (char*)0, (char*)0, (char*)0, &gendeltas);
- }
- if ( branchpoint( temp, cuttail ) ) {
- cuttail = 0;
- return 0;
- }
- delstrt = temp;
- return 1;
- }
-
- /* -o rev1-rev2 */
- if (!expandsym(delrev.end, &numrev)) return 0;
- if (
- length != countnumflds(numrev.string)
- || (length>2 && compartial(numrev.string, target->num, length-1))
- ) {
- rcserror("invalid revision range %s-%s",
- target->num, numrev.string
- );
- return 0;
- }
-
- target2 = genrevs(numrev.string,(char*)0,(char*)0,(char*)0,&gendeltas);
- if ( ! target2 ) return 0;
-
- if ( length > 2) { /* delete revisions on branches */
- if ( cmpnum(target->num, target2->num) > 0) {
- cmp = cmpnum(target2->num, numrev.string);
- temp = target;
- target = target2;
- target2 = temp;
- }
- if (cmp) {
- if ( ! cmpnum(target->num, target2->num) ) {
- rcserror("Revisions %s-%s don't exist.",
- delrev.strt, delrev.end
- );
- return 0;
- }
- cuthead = target;
- temp = target->next;
- }
- else
- temp = searchcutpt(target->num, length, gendeltas);
- cuttail = target2->next;
- }
- else { /* delete revisions on trunk */
- if ( cmpnum( target->num, target2->num) < 0 ) {
- temp = target;
- target = target2;
- target2 = temp;
- }
- else
- cmp = cmpnum(target2->num, numrev.string);
- if (cmp) {
- if ( ! cmpnum(target->num, target2->num) ) {
- rcserror("Revisions %s-%s don't exist.",
- delrev.strt, delrev.end
- );
- return 0;
- }
- cuttail = target2;
- }
- else
- cuttail = target2->next;
- temp = searchcutpt(target->num, length, gendeltas);
- }
- if ( branchpoint(temp, cuttail) ) {
- cuttail = 0;
- return 0;
- }
- delstrt = temp;
- return 1;
-}
-
-
-
- static int
-doassoc()
-/* Add or delete (if !revno) association that is stored in assoclst. */
-{
- char const *p;
- int changed = false;
- struct Symrev const *curassoc;
- struct assoc **pre, *pt;
-
- /* add new associations */
- for (curassoc = assoclst; curassoc; curassoc = curassoc->nextsym) {
- char const *ssymbol = curassoc->ssymbol;
-
- if (!curassoc->revno) { /* delete symbol */
- for (pre = &Symbols; ; pre = &pt->nextassoc)
- if (!(pt = *pre)) {
- rcswarn("can't delete nonexisting symbol %s", ssymbol);
- break;
- } else if (strcmp(pt->symbol, ssymbol) == 0) {
- *pre = pt->nextassoc;
- changed = true;
- break;
- }
- }
- else {
- if (curassoc->revno[0]) {
- p = 0;
- if (expandsym(curassoc->revno, &numrev))
- p = fstr_save(numrev.string);
- } else if (!(p = tiprev()))
- rcserror("no latest revision to associate with symbol %s",
- ssymbol
- );
- if (p)
- changed |= addsymbol(p, ssymbol, curassoc->override);
- }
- }
- return changed;
-}
-
-
-
- static int
-dolocks()
-/* Function: remove lock for caller or first lock if unlockcaller is set;
- * remove locks which are stored in rmvlocklst,
- * add new locks which are stored in newlocklst,
- * add lock for Dbranch or Head if lockhead is set.
- */
-{
- struct Lockrev const *lockpt;
- struct hshentry *target;
- int changed = false;
-
- if (unlockcaller) { /* find lock for caller */
- if ( Head ) {
- if (Locks) {
- switch (findlock(true, &target)) {
- case 0:
- /* remove most recent lock */
- changed |= breaklock(Locks->delta);
- break;
- case 1:
- diagnose("%s unlocked\n",target->num);
- changed = true;
- break;
- }
- } else {
- rcswarn("No locks are set.");
- }
- } else {
- rcswarn("can't unlock an empty tree");
- }
- }
-
- /* remove locks which are stored in rmvlocklst */
- for (lockpt = rmvlocklst; lockpt; lockpt = lockpt->nextrev)
- if (expandsym(lockpt->revno, &numrev)) {
- target = genrevs(numrev.string, (char *)0, (char *)0, (char *)0, &gendeltas);
- if ( target )
- if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string))
- rcserror("can't unlock nonexisting revision %s",
- lockpt->revno
- );
- else
- changed |= breaklock(target);
- /* breaklock does its own diagnose */
- }
-
- /* add new locks which stored in newlocklst */
- for (lockpt = newlocklst; lockpt; lockpt = lockpt->nextrev)
- changed |= setlock(lockpt->revno);
-
- if (lockhead) /* lock default branch or head */
- if (Dbranch)
- changed |= setlock(Dbranch);
- else if (Head)
- changed |= setlock(Head->num);
- else
- rcswarn("can't lock an empty tree");
- return changed;
-}
-
-
-
- static int
-setlock(rev)
- char const *rev;
-/* Function: Given a revision or branch number, finds the corresponding
- * delta and locks it for caller.
- */
-{
- struct hshentry *target;
- int r;
-
- if (expandsym(rev, &numrev)) {
- target = genrevs(numrev.string, (char*)0, (char*)0,
- (char*)0, &gendeltas);
- if ( target )
- if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string))
- rcserror("can't lock nonexisting revision %s",
- numrev.string
- );
- else {
- if ((r = addlock(target, false)) < 0 && breaklock(target))
- r = addlock(target, true);
- if (0 <= r) {
- if (r)
- diagnose("%s locked\n", target->num);
- return r;
- }
- }
- }
- return 0;
-}
-
-
- static int
-domessages()
-{
- struct hshentry *target;
- struct Message *p;
- int changed = false;
-
- for (p = messagelst; p; p = p->nextmessage)
- if (
- expandsym(p->revno, &numrev) &&
- (target = genrevs(
- numrev.string, (char*)0, (char*)0, (char*)0, &gendeltas
- ))
- ) {
- /*
- * We can't check the old log -- it's much later in the file.
- * We pessimistically assume that it changed.
- */
- target->log = p->message;
- changed = true;
- }
- return changed;
-}
-
-
- static int
-rcs_setstate(rev,status)
- char const *rev, *status;
-/* Function: Given a revision or branch number, finds the corresponding delta
- * and sets its state to status.
- */
-{
- struct hshentry *target;
-
- if (expandsym(rev, &numrev)) {
- target = genrevs(numrev.string, (char*)0, (char*)0,
- (char*)0, &gendeltas);
- if ( target )
- if (!(countnumflds(numrev.string)&1) && cmpnum(target->num,numrev.string))
- rcserror("can't set state of nonexisting revision %s",
- numrev.string
- );
- else if (strcmp(target->state, status) != 0) {
- target->state = status;
- return true;
- }
- }
- return false;
-}
-
-
-
-
-
- static int
-buildeltatext(deltas)
- struct hshentries const *deltas;
-/* Function: put the delta text on frewrite and make necessary */
-/* change to delta text */
-{
- register FILE *fcut; /* temporary file to rebuild delta tree */
- char const *cutname;
-
- fcut = 0;
- cuttail->selector = false;
- scanlogtext(deltas->first, false);
- if ( cuthead ) {
- cutname = maketemp(3);
- if (!(fcut = fopenSafer(cutname, FOPEN_WPLUS_WORK))) {
- efaterror(cutname);
- }
-
- while (deltas->first != cuthead) {
- deltas = deltas->rest;
- scanlogtext(deltas->first, true);
- }
-
- snapshotedit(fcut);
- Orewind(fcut);
- aflush(fcut);
- }
-
- while (deltas->first != cuttail)
- scanlogtext((deltas = deltas->rest)->first, true);
- finishedit((struct hshentry*)0, (FILE*)0, true);
- Ozclose(&fcopy);
-
- if (fcut) {
- char const *diffname = maketemp(0);
- char const *diffv[6 + !!OPEN_O_BINARY];
- char const **diffp = diffv;
- *++diffp = DIFF;
- *++diffp = DIFFFLAGS;
-# if OPEN_O_BINARY
- if (Expand == BINARY_EXPAND)
- *++diffp == "--binary";
-# endif
- *++diffp = "-";
- *++diffp = resultname;
- *++diffp = 0;
- switch (runv(fileno(fcut), diffname, diffv)) {
- case DIFF_FAILURE: case DIFF_SUCCESS: break;
- default: rcsfaterror("diff failed");
- }
- Ofclose(fcut);
- return putdtext(cuttail,diffname,frewrite,true);
- } else
- return putdtext(cuttail,resultname,frewrite,false);
-}
-
-
-
- static void
-buildtree()
-/* Function: actually removes revisions whose selector field */
-/* is false, and rebuilds the linkage of deltas. */
-/* asks for reconfirmation if deleting last revision*/
-{
- struct hshentry * Delta;
- struct branchhead *pt, *pre;
-
- if ( cuthead )
- if ( cuthead->next == delstrt )
- cuthead->next = cuttail;
- else {
- pre = pt = cuthead->branches;
- while( pt && pt->hsh != delstrt ) {
- pre = pt;
- pt = pt->nextbranch;
- }
- if ( cuttail )
- pt->hsh = cuttail;
- else if ( pt == pre )
- cuthead->branches = pt->nextbranch;
- else
- pre->nextbranch = pt->nextbranch;
- }
- else {
- if (!cuttail && !quietflag) {
- if (!yesorno(false, "Do you really want to delete all revisions? [ny](n): ")) {
- rcserror("No revision deleted");
- Delta = delstrt;
- while( Delta) {
- Delta->selector = true;
- Delta = Delta->next;
- }
- return;
- }
- }
- Head = cuttail;
- }
- return;
-}
-
-#if RCS_lint
-/* This lets us lint everything all at once. */
-
-char const cmdid[] = "";
-
-#define go(p,e) {int p P((int,char**)); void e P((void)); if(*argv)return p(argc,argv);if(*argv[1])e();}
-
- int
-main(argc, argv)
- int argc;
- char **argv;
-{
- go(ciId, ciExit);
- go(coId, coExit);
- go(identId, identExit);
- go(mergeId, mergeExit);
- go(rcsId, exiterr);
- go(rcscleanId, rcscleanExit);
- go(rcsdiffId, rdiffExit);
- go(rcsmergeId, rmergeExit);
- go(rlogId, rlogExit);
- return 0;
-}
-#endif
diff --git a/gnu/usr.bin/rcs/rcs/rcsfile.5 b/gnu/usr.bin/rcs/rcs/rcsfile.5
deleted file mode 100644
index 0d8aac8..0000000
--- a/gnu/usr.bin/rcs/rcs/rcsfile.5
+++ /dev/null
@@ -1,425 +0,0 @@
-.lf 1 ./rcsfile.5in
-.\" Set p to 1 if your formatter can handle pic output.
-.if t .nr p 1
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds r \s-1RCS\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.TH RCSFILE 5 \*(Dt GNU
-.SH NAME
-rcsfile \- format of RCS file
-.SH DESCRIPTION
-An \*r file's
-contents are described by the grammar
-below.
-.PP
-The text is free format: space, backspace, tab, newline, vertical
-tab, form feed, and carriage return (collectively,
-.IR "white space")
-have no significance except in strings.
-However, white space cannot appear within an id, num, or sym,
-and an \*r file must end with a newline.
-.PP
-Strings are enclosed by
-.BR @ .
-If a string contains a
-.BR @ ,
-it must be doubled;
-otherwise, strings can contain arbitrary binary data.
-.PP
-The meta syntax uses the following conventions: `|' (bar) separates
-alternatives; `{' and `}' enclose optional phrases; `{' and `}*' enclose
-phrases that can be repeated zero or more times;
-`{' and '}+' enclose phrases that must appear at least once and can be
-repeated;
-Terminal symbols are in
-.BR boldface ;
-nonterminal symbols are in
-.IR italics .
-.LP
-.nr w \w'\f3deltatext\fP '
-.nr y \w'\f3newphrase\fP '
-.if \nw<\ny .nr w \ny
-.nr x \w'\f3branches\fP'
-.nr y \w'{ \f3comment\fP'
-.if \nx<\ny .nr x \ny
-.nr y \w'\f3{ branch\fP'
-.if \nx<\ny .nr x \ny
-.ta \nwu +\w'::= 'u +\nxu+\w' 'u
-.fc #
-.nf
-\f2rcstext\fP ::= \f2admin\fP {\f2delta\fP}* \f2desc\fP {\f2deltatext\fP}*
-.LP
-\f2admin\fP ::= \f3head\fP {\f2num\fP}\f3;\fP
- { \f3branch\fP {\f2num\fP}\f3;\fP }
- \f3access\fP {\f2id\fP}*\f3;\fP
- \f3symbols\fP {\f2sym\fP \f3:\fP \f2num\fP}*\f3;\fP
- \f3locks\fP {\f2id\fP \f3:\fP \f2num\fP}*\f3;\fP {\f3strict ;\fP}
- { \f3comment\fP {\f2string\fP}\f3;\fP }
- { \f3expand\fP {\f2string\fP}\f3;\fP }
- { \f2newphrase\fP }*
-.LP
-\f2delta\fP ::= \f2num\fP
- \f3date\fP \f2num\fP\f3;\fP
- \f3author\fP \f2id\fP\f3;\fP
- \f3state\fP {\f2id\fP}\f3;\fP
- \f3branches\fP {\f2num\fP}*\f3;\fP
- \f3next\fP {\f2num\fP}\f3;\fP
- { \f2newphrase\fP }*
-.LP
-\f2desc\fP ::= \f3desc\fP \f2string\fP
-.LP
-\f2deltatext\fP ::= \f2num\fP
- \f3log\fP \f2string\fP
- { \f2newphrase\fP }*
- \f3text\fP \f2string\fP
-.LP
-\f2num\fP ::= {\f2digit\fP | \f3.\fP}+
-.LP
-\f2digit\fP ::= \f30\fP | \f31\fP | \f32\fP | \f33\fP | \f34\fP | \f35\fP | \f36\fP | \f37\fP | \f38\fP | \f39\fP
-.LP
-\f2id\fP ::= {\f2num\fP} \f2idchar\fP {\f2idchar\fP | \f2num\fP}*
-.LP
-\f2sym\fP ::= {\f2digit\fP}* \f2idchar\fP {\f2idchar\fP | \f2digit\fP}*
-.LP
-\f2idchar\fP ::= any visible graphic character except \f2special\fP
-.LP
-\f2special\fP ::= \f3$\fP | \f3,\fP | \f3.\fP | \f3:\fP | \f3;\fP | \f3@\fP
-.LP
-\f2string\fP ::= \f3@\fP{any character, with \f3@\fP doubled}*\f3@\fP
-.LP
-\f2newphrase\fP ::= \f2id\fP \f2word\fP* \f3;\fP
-.LP
-\f2word\fP ::= \f2id\fP | \f2num\fP | \f2string\fP | \f3:\fP
-.fi
-.PP
-Identifiers are case sensitive. Keywords are in lower case only.
-The sets of keywords and identifiers can overlap.
-In most environments \*r uses the \s-1ISO\s0 8859/1 encoding:
-visible graphic characters are codes 041\-176 and 240\-377,
-and white space characters are codes 010\-015 and 040.
-.PP
-Dates, which appear after the
-.B date
-keyword, are of the form
-\f2Y\fP\f3.\fP\f2mm\fP\f3.\fP\f2dd\fP\f3.\fP\f2hh\fP\f3.\fP\f2mm\fP\f3.\fP\f2ss\fP,
-where
-.I Y
-is the year,
-.I mm
-the month (01\-12),
-.I dd
-the day (01\-31),
-.I hh
-the hour (00\-23),
-.I mm
-the minute (00\-59),
-and
-.I ss
-the second (00\-60).
-.I Y
-contains just the last two digits of the year
-for years from 1900 through 1999,
-and all the digits of years thereafter.
-Dates use the Gregorian calendar; times use UTC.
-.PP
-The
-.I newphrase
-productions in the grammar are reserved for future extensions
-to the format of \*r files.
-No
-.I newphrase
-will begin with any keyword already in use.
-.PP
-The
-.I delta
-nodes form a tree. All nodes whose numbers
-consist of a single pair
-(e.g., 2.3, 2.1, 1.3, etc.)
-are on the trunk, and are linked through the
-.B next
-field in order of decreasing numbers.
-The
-.B head
-field in the
-.I admin
-node points to the head of that sequence (i.e., contains
-the highest pair).
-The
-.B branch
-node in the admin node indicates the default
-branch (or revision) for most \*r operations.
-If empty, the default
-branch is the highest branch on the trunk.
-.PP
-All
-.I delta
-nodes whose numbers consist of
-.RI 2 n
-fields
-.RI ( n \(>=2)
-(e.g., 3.1.1.1, 2.1.2.2, etc.)
-are linked as follows.
-All nodes whose first
-.RI 2 n \-1
-number fields are identical are linked through the
-.B next
-field in order of increasing numbers.
-For each such sequence,
-the
-.I delta
-node whose number is identical to the first
-.RI 2 n \-2
-number fields of the deltas on that sequence is called the branchpoint.
-The
-.B branches
-field of a node contains a list of the
-numbers of the first nodes of all sequences for which it is a branchpoint.
-This list is ordered in increasing numbers.
-.LP
-The following diagram shows an example of an \*r file's organization.
-.if !\np \{\
-.nf
-.vs 12
-.ne 36
-.cs 1 20
-.eo
-
- Head
- |
- |
- v / \
- --------- / \
- / \ / \ | | / \ / \
- / \ / \ | 2.1 | / \ / \
- / \ / \ | | / \ / \
-/1.2.1.3\ /1.3.1.1\ | | /1.2.2.2\ /1.2.2.1.1.1\
---------- --------- --------- --------- -------------
- ^ ^ | ^ ^
- | | | | |
- | | v | |
- / \ | --------- / \ |
- / \ | \ 1.3 / / \ |
- / \ ---------\ / / \-----------
-/1.2.1.1\ \ / /1.2.2.1\
---------- \ / ---------
- ^ | ^
- | | |
- | v |
- | --------- |
- | \ 1.2 / |
- ----------------------\ /---------
- \ /
- \ /
- |
- |
- v
- ---------
- \ 1.1 /
- \ /
- \ /
- \ /
-
-.ec
-.cs 1
-.vs
-.fi
-.\}
-.if \np \{\
-.lf 232
-.PS 4.250i 3.812i
-.\" -2.0625 -4.25 1.75 0
-.\" 0.000i 4.250i 3.812i 0.000i
-.nr 00 \n(.u
-.nf
-.nr 0x 1
-\h'3.812i'
-.sp -1
-.lf 242
-\h'2.062i-(\w'Head'u/2u)'\v'0.125i-(0v/2u)+0v+0.22m'Head
-.sp -1
-\h'2.062i'\v'0.250i'\D'l0.000i 0.500i'
-.sp -1
-\h'2.087i'\v'0.650i'\D'l-0.025i 0.100i'
-.sp -1
-\h'2.062i'\v'0.750i'\D'l-0.025i -0.100i'
-.sp -1
-\h'1.688i'\v'1.250i'\D'l0.750i 0.000i'
-.sp -1
-\h'2.438i'\v'1.250i'\D'l0.000i -0.500i'
-.sp -1
-\h'2.438i'\v'0.750i'\D'l-0.750i 0.000i'
-.sp -1
-\h'1.688i'\v'0.750i'\D'l0.000i 0.500i'
-.sp -1
-.lf 244
-\h'2.062i-(\w'2.1'u/2u)'\v'1.000i-(0v/2u)+0v+0.22m'2.1
-.sp -1
-\h'2.062i'\v'1.250i'\D'l0.000i 0.500i'
-.sp -1
-\h'2.087i'\v'1.650i'\D'l-0.025i 0.100i'
-.sp -1
-\h'2.062i'\v'1.750i'\D'l-0.025i -0.100i'
-.sp -1
-.lf 246
-\h'2.062i-(\w'1.3'u/2u)'\v'2.000i-(1v/2u)+0v+0.22m'1.3
-.sp -1
-\h'2.062i'\v'2.250i'\D'l-0.375i -0.500i'
-.sp -1
-\h'1.688i'\v'1.750i'\D'l0.750i 0.000i'
-.sp -1
-\h'2.438i'\v'1.750i'\D'l-0.375i 0.500i'
-.sp -1
-\h'1.875i'\v'2.000i'\D'~-0.500i 0.000i 0.000i -0.500i'
-.sp -1
-\h'1.350i'\v'1.600i'\D'l0.025i -0.100i'
-.sp -1
-\h'1.375i'\v'1.500i'\D'l0.025i 0.100i'
-.sp -1
-.lf 249
-\h'1.375i-(\w'1.3.1.1'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.3.1.1
-.sp -1
-\h'1.375i'\v'1.000i'\D'l-0.375i 0.500i'
-.sp -1
-\h'1.000i'\v'1.500i'\D'l0.750i 0.000i'
-.sp -1
-\h'1.750i'\v'1.500i'\D'l-0.375i -0.500i'
-.sp -1
-\h'2.062i'\v'2.250i'\D'l0.000i 0.500i'
-.sp -1
-\h'2.087i'\v'2.650i'\D'l-0.025i 0.100i'
-.sp -1
-\h'2.062i'\v'2.750i'\D'l-0.025i -0.100i'
-.sp -1
-.lf 252
-\h'2.062i-(\w'1.2'u/2u)'\v'3.000i-(1v/2u)+0v+0.22m'1.2
-.sp -1
-\h'2.062i'\v'3.250i'\D'l-0.375i -0.500i'
-.sp -1
-\h'1.688i'\v'2.750i'\D'l0.750i 0.000i'
-.sp -1
-\h'2.438i'\v'2.750i'\D'l-0.375i 0.500i'
-.sp -1
-\h'1.875i'\v'3.000i'\D'~-0.500i 0.000i -0.500i 0.000i -0.500i 0.000i 0.000i -0.500i'
-.sp -1
-\h'0.350i'\v'2.600i'\D'l0.025i -0.100i'
-.sp -1
-\h'0.375i'\v'2.500i'\D'l0.025i 0.100i'
-.sp -1
-.lf 255
-\h'0.375i-(\w'1.2.1.1'u/2u)'\v'2.250i-(1v/2u)+1v+0.22m'1.2.1.1
-.sp -1
-\h'0.375i'\v'2.000i'\D'l-0.375i 0.500i'
-.sp -1
-\h'0.000i'\v'2.500i'\D'l0.750i 0.000i'
-.sp -1
-\h'0.750i'\v'2.500i'\D'l-0.375i -0.500i'
-.sp -1
-\h'0.375i'\v'2.000i'\D'l0.000i -0.500i'
-.sp -1
-\h'0.350i'\v'1.600i'\D'l0.025i -0.100i'
-.sp -1
-\h'0.375i'\v'1.500i'\D'l0.025i 0.100i'
-.sp -1
-.lf 257
-\h'0.375i-(\w'1.2.1.3'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.2.1.3
-.sp -1
-\h'0.375i'\v'1.000i'\D'l-0.375i 0.500i'
-.sp -1
-\h'0.000i'\v'1.500i'\D'l0.750i 0.000i'
-.sp -1
-\h'0.750i'\v'1.500i'\D'l-0.375i -0.500i'
-.sp -1
-\h'2.250i'\v'3.000i'\D'~0.500i 0.000i 0.000i -0.500i'
-.sp -1
-\h'2.725i'\v'2.600i'\D'l0.025i -0.100i'
-.sp -1
-\h'2.750i'\v'2.500i'\D'l0.025i 0.100i'
-.sp -1
-.lf 261
-\h'2.750i-(\w'1.2.2.1'u/2u)'\v'2.250i-(1v/2u)+1v+0.22m'1.2.2.1
-.sp -1
-\h'2.750i'\v'2.000i'\D'l-0.375i 0.500i'
-.sp -1
-\h'2.375i'\v'2.500i'\D'l0.750i 0.000i'
-.sp -1
-\h'3.125i'\v'2.500i'\D'l-0.375i -0.500i'
-.sp -1
-\h'2.938i'\v'2.250i'\D'~0.500i 0.000i 0.000i -0.500i 0.000i -0.500i'
-.sp -1
-\h'3.413i'\v'1.350i'\D'l0.025i -0.100i'
-.sp -1
-\h'3.438i'\v'1.250i'\D'l0.025i 0.100i'
-.sp -1
-.lf 264
-\h'3.438i-(\w'\s-21.2.2.1.1.1\s0'u/2u)'\v'1.000i-(1v/2u)+1v+0.22m'\s-21.2.2.1.1.1\s0
-.sp -1
-\h'3.438i'\v'0.750i'\D'l-0.375i 0.500i'
-.sp -1
-\h'3.062i'\v'1.250i'\D'l0.750i 0.000i'
-.sp -1
-\h'3.812i'\v'1.250i'\D'l-0.375i -0.500i'
-.sp -1
-\h'2.750i'\v'2.000i'\D'l0.000i -0.500i'
-.sp -1
-\h'2.725i'\v'1.600i'\D'l0.025i -0.100i'
-.sp -1
-\h'2.750i'\v'1.500i'\D'l0.025i 0.100i'
-.sp -1
-.lf 267
-\h'2.750i-(\w'1.2.2.2'u/2u)'\v'1.250i-(1v/2u)+1v+0.22m'1.2.2.2
-.sp -1
-\h'2.750i'\v'1.000i'\D'l-0.375i 0.500i'
-.sp -1
-\h'2.375i'\v'1.500i'\D'l0.750i 0.000i'
-.sp -1
-\h'3.125i'\v'1.500i'\D'l-0.375i -0.500i'
-.sp -1
-\h'2.062i'\v'3.250i'\D'l0.000i 0.500i'
-.sp -1
-\h'2.087i'\v'3.650i'\D'l-0.025i 0.100i'
-.sp -1
-\h'2.062i'\v'3.750i'\D'l-0.025i -0.100i'
-.sp -1
-.lf 270
-\h'2.062i-(\w'1.1'u/2u)'\v'4.000i-(1v/2u)+0v+0.22m'1.1
-.sp -1
-\h'2.062i'\v'4.250i'\D'l-0.375i -0.500i'
-.sp -1
-\h'1.688i'\v'3.750i'\D'l0.750i 0.000i'
-.sp -1
-\h'2.438i'\v'3.750i'\D'l-0.375i 0.500i'
-.sp -1
-.sp 4.250i+1
-.if \n(00 .fi
-.br
-.nr 0x 0
-.lf 271
-.PE
-.lf 272
-.\}
-.SH IDENTIFICATION
-.de VL
-\\$2
-..
-Author: Walter F. Tichy,
-Purdue University, West Lafayette, IN, 47907.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
-.SH SEE ALSO
-rcsintro(1), ci(1), co(1), ident(1), rcs(1), rcsclean(1), rcsdiff(1),
-rcsmerge(1), rlog(1)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
diff --git a/gnu/usr.bin/rcs/rcs/rcsintro.1 b/gnu/usr.bin/rcs/rcs/rcsintro.1
deleted file mode 100644
index edcd9ee..0000000
--- a/gnu/usr.bin/rcs/rcs/rcsintro.1
+++ /dev/null
@@ -1,302 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds r \&\s-1RCS\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.if !\n(.g \{\
-. if !\w|\*(lq| \{\
-. ds lq ``
-. if \w'\(lq' .ds lq "\(lq
-. \}
-. if !\w|\*(rq| \{\
-. ds rq ''
-. if \w'\(rq' .ds rq "\(rq
-. \}
-.\}
-.am SS
-.LP
-..
-.TH RCSINTRO 1 \*(Dt GNU
-.SH NAME
-rcsintro \- introduction to RCS commands
-.SH DESCRIPTION
-The Revision Control System (\*r) manages multiple revisions of files.
-\*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.
-.PP
-The basic user interface is extremely simple. The novice only needs
-to learn two commands:
-.BR ci (1)
-and
-.BR co (1).
-.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.
-.BR co ,
-short for \*(lqcheck out\*(rq, retrieves revisions from an \*r file.
-.SS "Functions of \*r"
-.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.
-.IP \(bu
-Maintain a complete history of changes.
-\*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.
-.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.
-.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.
-.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.
-.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.
-.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.
-.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.
-.SS "Getting Started with \*r"
-Suppose you have a file
-.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
-.IP
-.B "mkdir RCS"
-.LP
-Then invoke the check-in command
-.IP
-.B "ci f.c"
-.LP
-This command creates an \*r file in the
-.B RCS
-directory,
-stores
-.B f.c
-into it as revision 1.1, and
-deletes
-.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.
-.PP
-Files in the \*r directory are called \*r files;
-the others are called working files.
-To get back the working file
-.B f.c
-in the previous example, use the check-out
-command
-.IP
-.B "co f.c"
-.LP
-This command extracts the latest revision from the \*r file
-and writes
-it into
-.BR f.c .
-If you want to edit
-.BR f.c ,
-you must lock it as you check it out with the command
-.IP
-.B "co \-l f.c"
-.LP
-You can now edit
-.BR f.c .
-.PP
-Suppose after some editing you want to know what changes that you have made.
-The command
-.IP
-.B "rcsdiff f.c"
-.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
-.IP
-.B "ci f.c"
-.LP
-This increments the revision number properly.
-.PP
-If
-.B ci
-complains with the message
-.IP
-.BI "ci error: no lock set by " "your name"
-.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
-.IP
-.B "rcs \-l f.c"
-.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.
-.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.
-Even if a revision is locked, it can still be checked out for
-reading, compiling, etc. All that locking
-prevents is a
-.I "check-in"
-by anybody but the locker.
-.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
-.IP
-.BR "rcs \-U f.c" " and " "rcs \-L f.c"
-.LP
-If you don't want to clutter your working directory with \*r files, create
-a subdirectory called
-.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.
-(Actually, pairs of \*r and working files can be specified in three ways:
-(a) both are given, (b) only the working file is given, (c) only the
-\*r file is given. Both \*r and working files may have arbitrary path prefixes;
-\*r commands pair them up intelligently.)
-.PP
-To avoid the deletion of the working file during check-in (in case you want to
-continue editing or compiling), invoke
-.IP
-.BR "ci \-l f.c" " or " "ci \-u f.c"
-.LP
-These commands check in
-.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).
-.PP
-You can give
-.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
-.IP
-.BR "ci \-r2 f.c" " or " "ci \-r2.1 f.c"
-.LP
-assigns the number 2.1 to the new revision.
-From then on,
-.B ci
-will number the subsequent revisions
-with 2.2, 2.3, etc. The corresponding
-.B co
-commands
-.IP
-.BR "co \-r2 f.c" " and " "co \-r2.1 f.c"
-.PP
-retrieve the latest revision numbered
-.RI 2. x
-and the revision 2.1,
-respectively.
-.B co
-without a revision number selects
-the latest revision on the
-.IR trunk ,
-i.e. the highest
-revision with a number consisting of two fields. Numbers with more than two
-fields are needed for branches.
-For example, to start a branch at revision 1.3, invoke
-.IP
-.B "ci \-r1.3.1 f.c"
-.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
-.BR rcsfile (5).
-.SS "Automatic Identification"
-\*r can put special strings for identification into your source and object
-code. To obtain such identification, place the marker
-.IP
-.B "$\&Id$"
-.LP
-into your text, for instance inside a comment.
-\*r will replace this marker with a string of the form
-.IP
-.BI $\&Id: " filename revision date time author state " $
-.LP
-With such a marker on the first page of each module, you can
-always see with which revision you are working.
-\*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:
-.IP
-.ft 3
-static char rcsid[] = \&"$\&Id$\&";
-.ft
-.LP
-The command
-.B ident
-extracts such markers from any file, even object code
-and dumps.
-Thus,
-.B ident
-lets you find out
-which revisions of which modules were used in a given program.
-.PP
-You may also find it useful to put the marker
-.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
-.BR co (1)
-for
-details.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993 Paul Eggert.
-.SH "SEE ALSO"
-ci(1), co(1), ident(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.br
diff --git a/gnu/usr.bin/rcs/rcsclean/Makefile b/gnu/usr.bin/rcs/rcsclean/Makefile
deleted file mode 100644
index fe538a0..0000000
--- a/gnu/usr.bin/rcs/rcsclean/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG= rcsclean
-SRCS= rcsclean.c
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/rcsclean/rcsclean.1 b/gnu/usr.bin/rcs/rcsclean/rcsclean.1
deleted file mode 100644
index 3111915..0000000
--- a/gnu/usr.bin/rcs/rcsclean/rcsclean.1
+++ /dev/null
@@ -1,203 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds r \&\s-1RCS\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.TH RCSCLEAN 1 \*(Dt GNU
-.SH NAME
-rcsclean \- clean up working files
-.SH SYNOPSIS
-.B rcsclean
-.RI [ options "] [ " file " .\|.\|. ]"
-.SH DESCRIPTION
-.B rcsclean
-removes files that are not being worked on.
-.B "rcsclean \-u"
-also unlocks and removes files that are being worked on
-but have not changed.
-.PP
-For each
-.I file
-given,
-.B rcsclean
-compares the working file and a revision in the corresponding
-\*r file. If it finds a difference, it does nothing.
-Otherwise, it first unlocks the revision if the
-.B \-u
-option is given,
-and then removes the working file
-unless the working file is writable and the revision is locked.
-It logs its actions by outputting the corresponding
-.B "rcs \-u"
-and
-.B "rm \-f"
-commands on the standard output.
-.PP
-Files are paired as explained in
-.BR ci (1).
-If no
-.I file
-is given, all working files in the current directory are cleaned.
-Pathnames matching an \*r suffix denote \*r files;
-all others denote working files.
-.PP
-The number of the revision to which the working file is compared
-may be attached to any of the options
-.BR \-n ,
-.BR \-q ,
-.BR \-r ,
-or
-.BR \-u .
-If no revision number is specified, then if the
-.B \-u
-option is given and the caller has one revision locked,
-.B rcsclean
-uses that revision; otherwise
-.B rcsclean
-uses the latest revision on the default branch, normally the root.
-.PP
-.B rcsclean
-is useful for
-.B clean
-targets in makefiles.
-See also
-.BR rcsdiff (1),
-which prints out the differences,
-and
-.BR ci (1),
-which
-normally reverts to the previous revision
-if a file was not changed.
-.SH OPTIONS
-.TP
-.BI \-k subst
-Use
-.I subst
-style keyword substitution when retrieving the revision for comparison.
-See
-.BR co (1)
-for details.
-.TP
-.BR \-n [\f2rev\fP]
-Do not actually remove any files or unlock any revisions.
-Using this option will tell you what
-.B rcsclean
-would do without actually doing it.
-.TP
-.BR \-q [\f2rev\fP]
-Do not log the actions taken on standard output.
-.TP
-.BR \-r [\f2rev\fP]
-This option has no effect other than specifying the revision for comparison.
-.TP
-.B \-T
-Preserve the modification time on the \*r file
-even if the \*r file changes because a lock is removed.
-This option can suppress extensive recompilation caused by a
-.BR make (1)
-dependency of some other copy of the working file on the \*r file.
-Use this option with care; it can suppress recompilation even when it is needed,
-i.e. when the lock removal
-would mean a change to keyword strings in the other working file.
-.TP
-.BR \-u [\f2rev\fP]
-Unlock the revision if it is locked and no difference is found.
-.TP
-.BI \-V
-Print \*r's version number.
-.TP
-.BI \-V n
-Emulate \*r version
-.IR n .
-See
-.BR co (1)
-for details.
-.TP
-.BI \-x "suffixes"
-Use
-.I suffixes
-to characterize \*r files.
-See
-.BR ci (1)
-for details.
-.TP
-.BI \-z zone
-Use
-.I zone
-as the time zone for keyword substitution;
-see
-.BR co (1)
-for details.
-.SH EXAMPLES
-.LP
-.RS
-.ft 3
-rcsclean *.c *.h
-.ft
-.RE
-.LP
-removes all working files ending in
-.B .c
-or
-.B .h
-that were not changed
-since their checkout.
-.LP
-.RS
-.ft 3
-rcsclean
-.ft
-.RE
-.LP
-removes all working files in the current directory
-that were not changed since their checkout.
-.SH FILES
-.B rcsclean
-accesses files much as
-.BR ci (1)
-does.
-.SH ENVIRONMENT
-.TP
-.B \s-1RCSINIT\s0
-options prepended to the argument list, separated by spaces.
-A backslash escapes spaces within an option.
-The
-.B \s-1RCSINIT\s0
-options are prepended to the argument lists of most \*r commands.
-Useful
-.B \s-1RCSINIT\s0
-options include
-.BR \-q ,
-.BR \-V ,
-.BR \-x ,
-and
-.BR \-z .
-.SH DIAGNOSTICS
-The exit status is zero if and only if all operations were successful.
-Missing working files and \*r files are silently ignored.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993 Paul Eggert.
-.SH "SEE ALSO"
-ci(1), co(1), ident(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1), rlog(1),
-rcsfile(5)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.SH BUGS
-At least one
-.I file
-must be given in older Unix versions that
-do not provide the needed directory scanning operations.
-.br
diff --git a/gnu/usr.bin/rcs/rcsclean/rcsclean.c b/gnu/usr.bin/rcs/rcsclean/rcsclean.c
deleted file mode 100644
index 32c8e7d..0000000
--- a/gnu/usr.bin/rcs/rcsclean/rcsclean.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/* Clean up working files. */
-
-/* Copyright 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-#include "rcsbase.h"
-
-#if has_dirent
- static int get_directory P((char const*,char***));
-#endif
-
-static int unlock P((struct hshentry *));
-static void cleanup P((void));
-
-static RILE *workptr;
-static int exitstatus;
-
-mainProg(rcscleanId, "rcsclean", "$FreeBSD$")
-{
- static char const usage[] =
- "\nrcsclean: usage: rcsclean -ksubst -{nqru}[rev] -T -Vn -xsuff -zzone file ...";
-
- static struct buf revision;
-
- char *a, **newargv;
- char const *rev, *p;
- int dounlock, expmode, perform, unlocked, unlockflag, waslocked;
- int Ttimeflag;
- struct hshentries *deltas;
- struct hshentry *delta;
- struct stat workstat;
-
- setrid();
-
- expmode = -1;
- rev = 0;
- suffixes = X_DEFAULT;
- perform = true;
- unlockflag = false;
- Ttimeflag = false;
-
- argc = getRCSINIT(argc, argv, &newargv);
- argv = newargv;
- for (;;) {
- if (--argc < 1) {
-# if has_dirent
- argc = get_directory(".", &newargv);
- argv = newargv;
- break;
-# else
- faterror("no pathnames specified");
-# endif
- }
- a = *++argv;
- if (!*a || *a++ != '-')
- break;
- switch (*a++) {
- case 'k':
- if (0 <= expmode)
- redefined('k');
- if ((expmode = str2expmode(a)) < 0)
- goto unknown;
- break;
-
- case 'n':
- perform = false;
- goto handle_revision;
-
- case 'q':
- quietflag = true;
- /* fall into */
- case 'r':
- handle_revision:
- if (*a) {
- if (rev)
- warn("redefinition of revision number");
- rev = a;
- }
- break;
-
- case 'T':
- if (*a)
- goto unknown;
- Ttimeflag = true;
- break;
-
- case 'u':
- unlockflag = true;
- goto handle_revision;
-
- case 'V':
- setRCSversion(*argv);
- break;
-
- case 'x':
- suffixes = a;
- break;
-
- case 'z':
- zone_set(a);
- break;
-
- default:
- unknown:
- error("unknown option: %s%s", *argv, usage);
- }
- }
-
- dounlock = perform & unlockflag;
-
- if (nerror)
- cleanup();
- else
- for (; 0 < argc; cleanup(), ++argv, --argc) {
-
- ffree();
-
- if (!(
- 0 < pairnames(
- argc, argv,
- dounlock ? rcswriteopen : rcsreadopen,
- true, true
- ) &&
- (workptr = Iopen(workname, FOPEN_R_WORK, &workstat))
- ))
- continue;
-
- if (same_file(RCSstat, workstat, 0)) {
- rcserror("RCS file is the same as working file %s.",
- workname
- );
- continue;
- }
-
- gettree();
-
- p = 0;
- if (rev) {
- if (!fexpandsym(rev, &revision, workptr))
- continue;
- p = revision.string;
- } else if (Head)
- switch (unlockflag ? findlock(false,&delta) : 0) {
- default:
- continue;
- case 0:
- p = Dbranch ? Dbranch : "";
- break;
- case 1:
- p = delta->num;
- break;
- }
- delta = 0;
- deltas = 0; /* Keep lint happy. */
- if (p && !(delta = genrevs(p,(char*)0,(char*)0,(char*)0,&deltas)))
- continue;
-
- waslocked = delta && delta->lockedby;
- locker_expansion = unlock(delta);
- unlocked = locker_expansion & unlockflag;
- if (unlocked<waslocked && workstat.st_mode&(S_IWUSR|S_IWGRP|S_IWOTH))
- continue;
-
- if (unlocked && !checkaccesslist())
- continue;
-
- if (dorewrite(dounlock, unlocked) != 0)
- continue;
-
- if (0 <= expmode)
- Expand = expmode;
- else if (
- waslocked &&
- Expand == KEYVAL_EXPAND &&
- WORKMODE(RCSstat.st_mode,true) == workstat.st_mode
- )
- Expand = KEYVALLOCK_EXPAND;
-
- getdesc(false);
-
- if (
- !delta ? workstat.st_size!=0 :
- 0 < rcsfcmp(
- workptr, &workstat,
- buildrevision(deltas, delta, (FILE*)0, false),
- delta
- )
- )
- continue;
-
- if (quietflag < unlocked)
- aprintf(stdout, "rcs -u%s %s\n", delta->num, RCSname);
-
- if (perform & unlocked) {
- if_advise_access(deltas->first != delta, finptr, MADV_SEQUENTIAL);
- if (donerewrite(true,
- Ttimeflag ? RCSstat.st_mtime : (time_t)-1
- ) != 0)
- continue;
- }
-
- if (!quietflag)
- aprintf(stdout, "rm -f %s\n", workname);
- Izclose(&workptr);
- if (perform && un_link(workname) != 0)
- eerror(workname);
-
- }
-
- tempunlink();
- if (!quietflag)
- Ofclose(stdout);
- exitmain(exitstatus);
-}
-
- static void
-cleanup()
-{
- if (nerror) exitstatus = EXIT_FAILURE;
- Izclose(&finptr);
- Izclose(&workptr);
- Ozclose(&fcopy);
- ORCSclose();
- dirtempunlink();
-}
-
-#if RCS_lint
-# define exiterr rcscleanExit
-#endif
- void
-exiterr()
-{
- ORCSerror();
- dirtempunlink();
- tempunlink();
- _exit(EXIT_FAILURE);
-}
-
- static int
-unlock(delta)
- struct hshentry *delta;
-{
- register struct rcslock **al, *l;
-
- if (delta && delta->lockedby && strcmp(getcaller(),delta->lockedby)==0)
- for (al = &Locks; (l = *al); al = &l->nextlock)
- if (l->delta == delta) {
- *al = l->nextlock;
- delta->lockedby = 0;
- return true;
- }
- return false;
-}
-
-#if has_dirent
- static int
-get_directory(dirname, aargv)
- char const *dirname;
- char ***aargv;
-/*
- * Put a vector of all DIRNAME's directory entries names into *AARGV.
- * Ignore names of RCS files.
- * Yield the number of entries found. Terminate the vector with 0.
- * Allocate the storage for the vector and entry names.
- * Do not sort the names. Do not include '.' and '..'.
- */
-{
- int i, entries = 0, entries_max = 64;
- size_t chars = 0, chars_max = 1024;
- size_t *offset = tnalloc(size_t, entries_max);
- char *a = tnalloc(char, chars_max), **p;
- DIR *d;
- struct dirent *e;
-
- if (!(d = opendir(dirname)))
- efaterror(dirname);
- while ((errno = 0, e = readdir(d))) {
- char const *en = e->d_name;
- size_t s = strlen(en) + 1;
- if (en[0]=='.' && (!en[1] || (en[1]=='.' && !en[2])))
- continue;
- if (rcssuffix(en))
- continue;
- while (chars_max < s + chars)
- a = trealloc(char, a, chars_max<<=1);
- if (entries == entries_max)
- offset = trealloc(size_t, offset, entries_max<<=1);
- offset[entries++] = chars;
- VOID strcpy(a+chars, en);
- chars += s;
- }
-# if void_closedir
-# define close_directory(d) (closedir(d), 0)
-# else
-# define close_directory(d) closedir(d)
-# endif
- if (errno || close_directory(d) != 0)
- efaterror(dirname);
- if (chars)
- a = trealloc(char, a, chars);
- else
- tfree(a);
- *aargv = p = tnalloc(char*, entries+1);
- for (i=0; i<entries; i++)
- *p++ = a + offset[i];
- *p = 0;
- tfree(offset);
- return entries;
-}
-#endif
diff --git a/gnu/usr.bin/rcs/rcsdiff/Makefile b/gnu/usr.bin/rcs/rcsdiff/Makefile
deleted file mode 100644
index 45ce23f..0000000
--- a/gnu/usr.bin/rcs/rcsdiff/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG= rcsdiff
-SRCS= rcsdiff.c
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/rcsdiff/rcsdiff.1 b/gnu/usr.bin/rcs/rcsdiff/rcsdiff.1
deleted file mode 100644
index 74117c2..0000000
--- a/gnu/usr.bin/rcs/rcsdiff/rcsdiff.1
+++ /dev/null
@@ -1,158 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds r \&\s-1RCS\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.TH RCSDIFF 1 \*(Dt GNU
-.SH NAME
-rcsdiff \- compare RCS revisions
-.SH SYNOPSIS
-.B rcsdiff
-[
-.BI \-k subst
-] [
-.B \-q
-] [
-.BI \-r rev1
-[
-.BI \-r rev2
-] ] [
-.B \-T
-] [
-.RI "\f3\-V\fP[" n ]
-] [
-.BI \-x suffixes
-] [
-.BI \-z zone
-] [
-.I "diff options"
-]
-.I "file .\|.\|."
-.SH DESCRIPTION
-.B rcsdiff
-runs
-.BR diff (1)
-to compare two revisions of each \*r file given.
-.PP
-Pathnames matching an \*r suffix denote \*r files;
-all others denote working files.
-Names are paired as explained in
-.BR ci (1).
-.PP
-The option
-.B \-q
-suppresses diagnostic output.
-Zero, one, or two revisions may be specified with
-.BR \-r .
-The option
-.BI \-k subst
-affects keyword substitution when extracting
-revisions, as described in
-.BR co (1);
-for example,
-.B "\-kk\ \-r1.1\ \-r1.2"
-ignores differences in keyword values when comparing revisions
-.B 1.1
-and
-.BR 1.2 .
-To avoid excess output from locker name substitution,
-.B \-kkvl
-is assumed if (1) at most one revision option is given,
-(2) no
-.B \-k
-option is given, (3)
-.B \-kkv
-is the default keyword substitution, and
-(4) the working file's mode would be produced by
-.BR "co\ \-l".
-See
-.BR co (1)
-for details
-about
-.BR \-T ,
-.BR \-V ,
-.B \-x
-and
-.BR \-z .
-Otherwise, all options of
-.BR diff (1)
-that apply to regular files are accepted, with the same meaning as for
-.BR diff .
-.PP
-If both
-.I rev1
-and
-.I rev2
-are omitted,
-.B rcsdiff
-compares the latest revision on the
-default branch (by default the trunk)
-with the contents of the corresponding working file. This is useful
-for determining what you changed since the last checkin.
-.PP
-If
-.I rev1
-is given, but
-.I rev2
-is omitted,
-.B rcsdiff
-compares revision
-.I rev1
-of the \*r file with
-the contents of the corresponding working file.
-.PP
-If both
-.I rev1
-and
-.I rev2
-are given,
-.B rcsdiff
-compares revisions
-.I rev1
-and
-.I rev2
-of the \*r file.
-.PP
-Both
-.I rev1
-and
-.I rev2
-may be given numerically or symbolically.
-.SH EXAMPLE
-The command
-.LP
-.B " rcsdiff f.c"
-.LP
-compares the latest revision on the default branch of the \*r file
-to the contents of the working file
-.BR f.c .
-.SH ENVIRONMENT
-.TP
-.B \s-1RCSINIT\s0
-options prepended to the argument list, separated by spaces.
-See
-.BR ci (1)
-for details.
-.SH DIAGNOSTICS
-Exit status is 0 for no differences during any comparison,
-1 for some differences, 2 for trouble.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993 Paul Eggert.
-.SH "SEE ALSO"
-ci(1), co(1), diff(1), ident(1), rcs(1), rcsintro(1), rcsmerge(1), rlog(1)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.br
diff --git a/gnu/usr.bin/rcs/rcsdiff/rcsdiff.c b/gnu/usr.bin/rcs/rcsdiff/rcsdiff.c
deleted file mode 100644
index 7d3c0a3..0000000
--- a/gnu/usr.bin/rcs/rcsdiff/rcsdiff.c
+++ /dev/null
@@ -1,480 +0,0 @@
-/* Compare RCS revisions. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.19 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.18 1995/06/01 16:23:43 eggert
- * (main): Pass "--binary" if -kb and if --binary makes a difference.
- * Don't treat + options specially.
- *
- * Revision 5.17 1994/03/17 14:05:48 eggert
- * Specify subprocess input via file descriptor, not file name. Remove lint.
- *
- * Revision 5.16 1993/11/09 17:40:15 eggert
- * -V now prints version on stdout and exits. Don't print usage twice.
- *
- * Revision 5.15 1993/11/03 17:42:27 eggert
- * Add -z. Ignore -T. Pass -Vn to `co'. Add Name keyword.
- * Put revision numbers in -c output. Improve quality of diagnostics.
- *
- * Revision 5.14 1992/07/28 16:12:44 eggert
- * Add -V. Use co -M for better dates with traditional diff -c.
- *
- * Revision 5.13 1992/02/17 23:02:23 eggert
- * Output more readable context diff headers.
- * Suppress needless checkout and comparison of identical revisions.
- *
- * Revision 5.12 1992/01/24 18:44:19 eggert
- * Add GNU diff 1.15.2's new options. lint -> RCS_lint
- *
- * Revision 5.11 1992/01/06 02:42:34 eggert
- * Update usage string.
- *
- * Revision 5.10 1991/10/07 17:32:46 eggert
- * Remove lint.
- *
- * Revision 5.9 1991/08/19 03:13:55 eggert
- * Add RCSINIT, -r$. Tune.
- *
- * Revision 5.8 1991/04/21 11:58:21 eggert
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.7 1990/12/13 06:54:07 eggert
- * GNU diff 1.15 has -u.
- *
- * Revision 5.6 1990/11/01 05:03:39 eggert
- * Remove unneeded setid check.
- *
- * Revision 5.5 1990/10/04 06:30:19 eggert
- * Accumulate exit status across files.
- *
- * Revision 5.4 1990/09/27 01:31:43 eggert
- * Yield 1, not EXIT_FAILURE, when diffs are found.
- *
- * Revision 5.3 1990/09/11 02:41:11 eggert
- * Simplify -kkvl test.
- *
- * Revision 5.2 1990/09/04 17:07:19 eggert
- * Diff's argv was too small by 1.
- *
- * Revision 5.1 1990/08/29 07:13:55 eggert
- * Add -kkvl.
- *
- * Revision 5.0 1990/08/22 08:12:46 eggert
- * Add -k, -V. Don't use access(). Add setuid support.
- * Remove compile-time limits; use malloc instead.
- * Don't pass arguments with leading '+' to diff; GNU DIFF treats them as options.
- * Add GNU diff's flags. Make lock and temp files faster and safer.
- * Ansify and Posixate.
- *
- * Revision 4.6 89/05/01 15:12:27 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.5 88/08/09 19:12:41 eggert
- * Use execv(), not system(); yield exit status like diff(1)s; allow cc -R.
- *
- * Revision 4.4 87/12/18 11:37:46 narten
- * changes Jay Lepreau made in the 4.3 BSD version, to add support for
- * "-i", "-w", and "-t" flags and to permit flags to be bundled together,
- * merged in.
- *
- * Revision 4.3 87/10/18 10:31:42 narten
- * Updating version numbers. Changes relative to 1.1 actually
- * relative to 4.1
- *
- * Revision 1.3 87/09/24 13:59:21 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:15 jenkins
- * Port to suns
- *
- * Revision 4.1 83/05/03 22:13:19 wft
- * Added default branch, option -q, exit status like diff.
- * Added fterror() to replace faterror().
- *
- * Revision 3.6 83/01/15 17:52:40 wft
- * Expanded mainprogram to handle multiple RCS files.
- *
- * Revision 3.5 83/01/06 09:33:45 wft
- * Fixed passing of -c (context) option to diff.
- *
- * Revision 3.4 82/12/24 15:28:38 wft
- * Added call to catchsig().
- *
- * Revision 3.3 82/12/10 16:08:17 wft
- * Corrected checking of return code from diff; improved error msgs.
- *
- * Revision 3.2 82/12/04 13:20:09 wft
- * replaced getdelta() with gettree(). Changed diagnostics.
- *
- * Revision 3.1 82/11/28 19:25:04 wft
- * Initial revision.
- *
- */
-#include "rcsbase.h"
-
-#if DIFF_L
-static char const *setup_label P((struct buf*,char const*,char const[datesize]));
-#endif
-static void cleanup P((void));
-
-static int exitstatus;
-static RILE *workptr;
-static struct stat workstat;
-
-mainProg(rcsdiffId, "rcsdiff", "$FreeBSD$")
-{
- static char const cmdusage[] =
- "\nrcsdiff usage: rcsdiff -ksubst -q -rrev1 [-rrev2] -Vn -xsuff -zzone [diff options] file ...";
-
- int revnums; /* counter for revision numbers given */
- char const *rev1, *rev2; /* revision numbers from command line */
- char const *xrev1, *xrev2; /* expanded revision numbers */
- char const *expandarg, *lexpandarg, *suffixarg, *versionarg, *zonearg;
-#if DIFF_L
- static struct buf labelbuf[2];
- int file_labels;
- char const **diff_label1, **diff_label2;
- char date2[datesize];
-#endif
- char const *cov[10 + !DIFF_L];
- char const **diffv, **diffp, **diffpend; /* argv for subsidiary diff */
- char const **pp, *p, *diffvstr;
- struct buf commarg;
- struct buf numericrev; /* expanded revision number */
- struct hshentries *gendeltas; /* deltas to be generated */
- struct hshentry * target;
- char *a, *dcp, **newargv;
- int no_diff_means_no_output;
- register c;
-
- exitstatus = DIFF_SUCCESS;
-
- bufautobegin(&commarg);
- bufautobegin(&numericrev);
- revnums = 0;
- rev1 = rev2 = xrev2 = 0;
-#if DIFF_L
- file_labels = 0;
-#endif
- expandarg = suffixarg = versionarg = zonearg = 0;
- no_diff_means_no_output = true;
- suffixes = X_DEFAULT;
-
- /*
- * Room for runv extra + args [+ --binary] [+ 2 labels]
- * + 1 file + 1 trailing null.
- */
- diffv = tnalloc(char const*, 1 + argc + !!OPEN_O_BINARY + 2*DIFF_L + 2);
- diffp = diffv + 1;
- *diffp++ = DIFF;
-
- argc = getRCSINIT(argc, argv, &newargv);
- argv = newargv;
- while (a = *++argv, 0<--argc && *a++=='-') {
- dcp = a;
- while ((c = *a++)) switch (c) {
- case 'r':
- switch (++revnums) {
- case 1: rev1=a; break;
- case 2: rev2=a; break;
- default: error("too many revision numbers");
- }
- goto option_handled;
- case '-': case 'D':
- no_diff_means_no_output = false;
- /* fall into */
- case 'C': case 'F': case 'I': case 'L': case 'W':
-#if DIFF_L
- if (c == 'L' && file_labels++ == 2)
- faterror("too many -L options");
-#endif
- *dcp++ = c;
- if (*a)
- do *dcp++ = *a++;
- while (*a);
- else {
- if (!--argc)
- faterror("-%c needs following argument%s",
- c, cmdusage
- );
- *diffp++ = *argv++;
- }
- break;
- case 'y':
- no_diff_means_no_output = false;
- /* fall into */
- case 'B': case 'H':
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- case 'h': case 'i': case 'n': case 'p':
- case 't': case 'u': case 'w':
- *dcp++ = c;
- break;
- case 'q':
- quietflag=true;
- break;
- case 'x':
- suffixarg = *argv;
- suffixes = *argv + 2;
- goto option_handled;
- case 'z':
- zonearg = *argv;
- zone_set(*argv + 2);
- goto option_handled;
- case 'T':
- /* Ignore -T, so that RCSINIT can contain -T. */
- if (*a)
- goto unknown;
- break;
- case 'V':
- versionarg = *argv;
- setRCSversion(versionarg);
- goto option_handled;
- case 'k':
- expandarg = *argv;
- if (0 <= str2expmode(expandarg+2))
- goto option_handled;
- /* fall into */
- default:
- unknown:
- error("unknown option: %s%s", *argv, cmdusage);
- };
- option_handled:
- if (dcp != *argv+1) {
- *dcp = 0;
- *diffp++ = *argv;
- }
- } /* end of option processing */
-
- for (pp = diffv+2, c = 0; pp<diffp; )
- c += strlen(*pp++) + 1;
- diffvstr = a = tnalloc(char, c + 1);
- for (pp = diffv+2; pp<diffp; ) {
- p = *pp++;
- *a++ = ' ';
- while ((*a = *p++))
- a++;
- }
- *a = 0;
-
-#if DIFF_L
- diff_label1 = diff_label2 = 0;
- if (file_labels < 2) {
- if (!file_labels)
- diff_label1 = diffp++;
- diff_label2 = diffp++;
- }
-#endif
- diffpend = diffp;
-
- cov[1] = CO;
- cov[2] = "-q";
-# if !DIFF_L
- cov[3] = "-M";
-# endif
-
- /* Now handle all pathnames. */
- if (nerror)
- cleanup();
- else if (argc < 1)
- faterror("no input file%s", cmdusage);
- else
- for (; 0 < argc; cleanup(), ++argv, --argc) {
- ffree();
-
- if (pairnames(argc, argv, rcsreadopen, true, false) <= 0)
- continue;
- diagnose("===================================================================\nRCS file: %s\n",RCSname);
- if (!rev2) {
- /* Make sure work file is readable, and get its status. */
- if (!(workptr = Iopen(workname, FOPEN_R_WORK, &workstat))) {
- eerror(workname);
- continue;
- }
- }
-
-
- gettree(); /* reads in the delta tree */
-
- if (!Head) {
- rcserror("no revisions present");
- continue;
- }
- if (revnums==0 || !*rev1)
- rev1 = Dbranch ? Dbranch : Head->num;
-
- if (!fexpandsym(rev1, &numericrev, workptr)) continue;
- if (!(target=genrevs(numericrev.string,(char *)0,(char *)0,(char *)0,&gendeltas))) continue;
- xrev1=target->num;
-#if DIFF_L
- if (diff_label1)
- *diff_label1 = setup_label(&labelbuf[0], target->num, target->date);
-#endif
-
- lexpandarg = expandarg;
- if (revnums==2) {
- if (!fexpandsym(
- *rev2 ? rev2 : Dbranch ? Dbranch : Head->num,
- &numericrev,
- workptr
- ))
- continue;
- if (!(target=genrevs(numericrev.string,(char *)0,(char *)0,(char *)0,&gendeltas))) continue;
- xrev2=target->num;
- if (no_diff_means_no_output && xrev1 == xrev2)
- continue;
- } else if (
- target->lockedby
- && !lexpandarg
- && Expand == KEYVAL_EXPAND
- && WORKMODE(RCSstat.st_mode,true) == workstat.st_mode
- )
- lexpandarg = "-kkvl";
- Izclose(&workptr);
-#if DIFF_L
- if (diff_label2)
- if (revnums == 2)
- *diff_label2 = setup_label(&labelbuf[1], target->num, target->date);
- else {
- time2date(workstat.st_mtime, date2);
- *diff_label2 = setup_label(&labelbuf[1], (char*)0, date2);
- }
-#endif
-
- diagnose("retrieving revision %s\n", xrev1);
- bufscpy(&commarg, "-p");
- bufscat(&commarg, rev1); /* not xrev1, for $Name's sake */
-
- pp = &cov[3 + !DIFF_L];
- *pp++ = commarg.string;
- if (lexpandarg) *pp++ = lexpandarg;
- if (suffixarg) *pp++ = suffixarg;
- if (versionarg) *pp++ = versionarg;
- if (zonearg) *pp++ = zonearg;
- *pp++ = RCSname;
- *pp = 0;
-
- diffp = diffpend;
-# if OPEN_O_BINARY
- if (Expand == BINARY_EXPAND)
- *diffp++ = "--binary";
-# endif
- diffp[0] = maketemp(0);
- if (runv(-1, diffp[0], cov)) {
- rcserror("co failed");
- continue;
- }
- if (!rev2) {
- diffp[1] = workname;
- if (*workname == '-') {
- char *dp = ftnalloc(char, strlen(workname)+3);
- diffp[1] = dp;
- *dp++ = '.';
- *dp++ = SLASH;
- VOID strcpy(dp, workname);
- }
- } else {
- diagnose("retrieving revision %s\n",xrev2);
- bufscpy(&commarg, "-p");
- bufscat(&commarg, rev2); /* not xrev2, for $Name's sake */
- cov[3 + !DIFF_L] = commarg.string;
- diffp[1] = maketemp(1);
- if (runv(-1, diffp[1], cov)) {
- rcserror("co failed");
- continue;
- }
- }
- if (!rev2)
- diagnose("diff%s -r%s %s\n", diffvstr, xrev1, workname);
- else
- diagnose("diff%s -r%s -r%s\n", diffvstr, xrev1, xrev2);
-
- diffp[2] = 0;
- switch (runv(-1, (char*)0, diffv)) {
- case DIFF_SUCCESS:
- break;
- case DIFF_FAILURE:
- if (exitstatus == DIFF_SUCCESS)
- exitstatus = DIFF_FAILURE;
- break;
- default:
- workerror("diff failed");
- }
- }
-
- tempunlink();
- exitmain(exitstatus);
-}
-
- static void
-cleanup()
-{
- if (nerror) exitstatus = DIFF_TROUBLE;
- Izclose(&finptr);
- Izclose(&workptr);
-}
-
-#if RCS_lint
-# define exiterr rdiffExit
-#endif
- void
-exiterr()
-{
- tempunlink();
- _exit(DIFF_TROUBLE);
-}
-
-#if DIFF_L
- static char const *
-setup_label(b, num, date)
- struct buf *b;
- char const *num;
- char const date[datesize];
-{
- char *p;
- char datestr[datesize + zonelenmax];
- VOID date2str(date, datestr);
- bufalloc(b,
- strlen(workname)
- + sizeof datestr + 4
- + (num ? strlen(num) : 0)
- );
- p = b->string;
- if (num)
- VOID sprintf(p, "-L%s\t%s\t%s", workname, datestr, num);
- else
- VOID sprintf(p, "-L%s\t%s", workname, datestr);
- return p;
-}
-#endif
diff --git a/gnu/usr.bin/rcs/rcsfreeze/Makefile b/gnu/usr.bin/rcs/rcsfreeze/Makefile
deleted file mode 100644
index 1b249c7..0000000
--- a/gnu/usr.bin/rcs/rcsfreeze/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-# $FreeBSD$
-
-SCRIPTS= rcsfreeze.sh
-MAN= rcsfreeze.1
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.1 b/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.1
deleted file mode 100644
index 3f513c4..0000000
--- a/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.1
+++ /dev/null
@@ -1,68 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds r \s-1RCS\s0
-.TH RCSFREEZE 1 \*(Dt GNU
-.SH NAME
-rcsfreeze \- freeze a configuration of sources checked in under RCS
-.SH SYNOPSIS
-.B rcsfreeze
-.RI [ "name" ]
-.SH DESCRIPTION
-.B rcsfreeze
-assigns a symbolic revision
-number to a set of \*r files that form a valid configuration.
-.PP
-The idea is to run
-.B rcsfreeze
-each time a new version is checked
-in. A unique symbolic name (\c
-.BI C_ number,
-where
-.I number
-is increased each time
-.B rcsfreeze
-is run) is then assigned to the most
-recent revision of each \*r file of the main trunk.
-.PP
-An optional
-.I name
-argument to
-.B rcsfreeze
-gives a symbolic name to the configuration.
-The unique identifier is still generated
-and is listed in the log file but it will not appear as
-part of the symbolic revision name in the actual \*r files.
-.PP
-A log message is requested from the user for future reference.
-.PP
-The shell script works only on all \*r files at one time.
-All changed files must be checked in already.
-Run
-.IR rcsclean (1)
-first and see whether any sources remain in the current directory.
-.SH FILES
-.TP
-.B RCS/.rcsfreeze.ver
-version number
-.TP
-.B RCS/.rcsfreeze.log
-log messages, most recent first
-.SH AUTHOR
-Stephan v. Bechtolsheim
-.SH "SEE ALSO"
-co(1), rcs(1), rcsclean(1), rlog(1)
-.SH BUGS
-.B rcsfreeze
-does not check whether any sources are checked out and modified.
-.PP
-Although both source file names and RCS file names are accepted,
-they are not paired as usual with RCS commands.
-.PP
-Error checking is rudimentary.
-.PP
-.B rcsfreeze
-is just an optional example shell script, and should not be taken too seriously.
-See \s-1CVS\s0 for a more complete solution.
diff --git a/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.sh b/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.sh
deleted file mode 100644
index be79406..0000000
--- a/gnu/usr.bin/rcs/rcsfreeze/rcsfreeze.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#! /bin/sh
-
-# rcsfreeze - assign a symbolic revision number to a configuration of RCS files
-
-# $FreeBSD$
-
-# The idea is to run rcsfreeze each time a new version is checked
-# in. A unique symbolic revision number (C_[number], where number
-# is increased each time rcsfreeze is run) is then assigned to the most
-# recent revision of each RCS file of the main trunk.
-#
-# If the command is invoked with an argument, then this
-# argument is used as the symbolic name to freeze a configuration.
-# The unique identifier is still generated
-# and is listed in the log file but it will not appear as
-# part of the symbolic revision name in the actual RCS file.
-#
-# A log message is requested from the user which is saved for future
-# references.
-#
-# The shell script works only on all RCS files at one time.
-# It is important that all changed files are checked in (there are
-# no precautions against any error in this respect).
-# file names:
-# {RCS/}.rcsfreeze.ver version number
-# {RCS/}.rscfreeze.log log messages, most recent first
-
-PATH=/bin:/usr/bin:$PATH
-export PATH
-
-DATE=`LC_ALL=C date` || exit
-# Check whether we have an RCS subdirectory, so we can have the right
-# prefix for our paths.
-if test -d RCS
-then RCSDIR=RCS/ EXT=
-else RCSDIR= EXT=,v
-fi
-
-# Version number stuff, log message file
-VERSIONFILE=${RCSDIR}.rcsfreeze.ver
-LOGFILE=${RCSDIR}.rcsfreeze.log
-# Initialize, rcsfreeze never run before in the current directory
-test -r $VERSIONFILE || { echo 0 >$VERSIONFILE && >>$LOGFILE; } || exit
-
-# Get Version number, increase it, write back to file.
-VERSIONNUMBER=`cat $VERSIONFILE` &&
-VERSIONNUMBER=`expr $VERSIONNUMBER + 1` &&
-echo $VERSIONNUMBER >$VERSIONFILE || exit
-
-# Symbolic Revision Number
-SYMREV=C_$VERSIONNUMBER
-# Allow the user to give a meaningful symbolic name to the revision.
-SYMREVNAME=${1-$SYMREV}
-echo >&2 "rcsfreeze: symbolic revision number computed: \"${SYMREV}\"
-rcsfreeze: symbolic revision number used: \"${SYMREVNAME}\"
-rcsfreeze: the two differ only when rcsfreeze invoked with argument
-rcsfreeze: give log message, summarizing changes (end with EOF or single '.')" \
- || exit
-
-# Stamp the logfile. Because we order the logfile the most recent
-# first we will have to save everything right now in a temporary file.
-TMPLOG=/tmp/rcsfrz$$
-trap 'rm -f $TMPLOG; exit 1' 1 2 13 15
-# Now ask for a log message, continously add to the log file
-(
- echo "Version: $SYMREVNAME($SYMREV), Date: $DATE
------------" || exit
- while read MESS
- do
- case $MESS in
- .) break
- esac
- echo " $MESS" || exit
- done
- echo "-----------
-" &&
- cat $LOGFILE
-) >$TMPLOG &&
-
-# combine old and new logfiles
-cp $TMPLOG $LOGFILE &&
-rm -f $TMPLOG &&
-
-# Now the real work begins by assigning a symbolic revision number
-# to each rcs file. Take the most recent version on the default branch.
-
-# If there are any .*,v files, throw them in too.
-# But ignore RCS/.* files that do not end in ,v.
-DOTFILES=
-for DOTFILE in ${RCSDIR}.*,v
-do
- if test -f "$DOTFILE"
- then
- DOTFILES="${RCSDIR}.*,v"
- break
- fi
-done
-
-exec rcs -q -n$SYMREVNAME: ${RCSDIR}*$EXT $DOTFILES
diff --git a/gnu/usr.bin/rcs/rcsmerge/Makefile b/gnu/usr.bin/rcs/rcsmerge/Makefile
deleted file mode 100644
index 9fd8afa..0000000
--- a/gnu/usr.bin/rcs/rcsmerge/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG= rcsmerge
-SRCS= rcsmerge.c
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/rcsmerge/rcsmerge.1 b/gnu/usr.bin/rcs/rcsmerge/rcsmerge.1
deleted file mode 100644
index aff6f66..0000000
--- a/gnu/usr.bin/rcs/rcsmerge/rcsmerge.1
+++ /dev/null
@@ -1,189 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds r \&\s-1RCS\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.TH RCSMERGE 1 \*(Dt GNU
-.SH NAME
-rcsmerge \- merge RCS revisions
-.SH SYNOPSIS
-.B rcsmerge
-.RI [ options ] " file"
-.SH DESCRIPTION
-.B rcsmerge
-incorporates the changes between two revisions
-of an \*r file into the corresponding working file.
-.PP
-Pathnames matching an \*r suffix denote \*r files;
-all others denote working files.
-Names are paired as explained in
-.BR ci (1).
-.PP
-At least one revision must be specified with one of the options
-described below, usually
-.BR \-r .
-At most two revisions may be specified.
-If only one revision is specified, the latest
-revision on the default branch (normally the highest branch on the trunk)
-is assumed for the second revision.
-Revisions may be specified numerically or symbolically.
-.PP
-.B rcsmerge
-prints a warning if there are overlaps, and delimits
-the overlapping regions as explained in
-.BR merge (1).
-The command is useful for incorporating changes into a checked-out revision.
-.SH OPTIONS
-.TP
-.B \-A
-Output conflicts using the
-.B \-A
-style of
-.BR diff3 (1),
-if supported by
-.BR diff3 .
-This merges all changes leading from
-.I file2
-to
-.I file3
-into
-.IR file1 ,
-and generates the most verbose output.
-.TP
-\f3\-E\fP, \f3\-e\fP
-These options specify conflict styles that generate less information
-than
-.BR \-A .
-See
-.BR diff3 (1)
-for details.
-The default is
-.BR \-E .
-With
-.BR \-e ,
-.B rcsmerge
-does not warn about conflicts.
-.TP
-.BI \-k subst
-Use
-.I subst
-style keyword substitution.
-See
-.BR co (1)
-for details.
-For example,
-.B "\-kk\ \-r1.1\ \-r1.2"
-ignores differences in keyword values when merging the changes from
-.B 1.1
-to
-.BR 1.2 .
-It normally does not make sense to merge binary files as if they were text, so
-.B rcsmerge
-refuses to merge files if
-.B \-kb
-expansion is used.
-.TP
-.BR \-p [\f2rev\fP]
-Send the result to standard output instead of overwriting the working file.
-.TP
-.BR \-q [\f2rev\fP]
-Run quietly; do not print diagnostics.
-.TP
-.BR \-r [\f2rev\fP]
-Merge with respect to revision
-.IR rev .
-Here an empty
-.I rev
-stands for the latest revision on the default branch, normally the head.
-.TP
-.B \-T
-This option has no effect;
-it is present for compatibility with other \*r commands.
-.TP
-.BI \-V
-Print \*r's version number.
-.TP
-.BI \-V n
-Emulate \*r version
-.IR n .
-See
-.BR co (1)
-for details.
-.TP
-.BI \-x "suffixes"
-Use
-.I suffixes
-to characterize \*r files.
-See
-.BR ci (1)
-for details.
-.TP
-.BI \-z zone
-Use
-.I zone
-as the time zone for keyword substitution.
-See
-.BR co (1)
-for details.
-.SH EXAMPLES
-Suppose you have released revision 2.8 of
-.BR f.c .
-Assume
-furthermore that after you complete an unreleased revision 3.4, you receive
-updates to release 2.8 from someone else.
-To combine the updates to 2.8 and your changes between 2.8 and 3.4,
-put the updates to 2.8 into file f.c and execute
-.LP
-.B " rcsmerge \-p \-r2.8 \-r3.4 f.c >f.merged.c"
-.PP
-Then examine
-.BR f.merged.c .
-Alternatively, if you want to save the updates to 2.8 in the \*r file,
-check them in as revision 2.8.1.1 and execute
-.BR "co \-j":
-.LP
-.B " ci \-r2.8.1.1 f.c"
-.br
-.B " co \-r3.4 \-j2.8:2.8.1.1 f.c"
-.PP
-As another example, the following command undoes the changes
-between revision 2.4 and 2.8 in your currently checked out revision
-in
-.BR f.c .
-.LP
-.B " rcsmerge \-r2.8 \-r2.4 f.c"
-.PP
-Note the order of the arguments, and that
-.B f.c
-will be
-overwritten.
-.SH ENVIRONMENT
-.TP
-.B \s-1RCSINIT\s0
-options prepended to the argument list, separated by spaces.
-See
-.BR ci (1)
-for details.
-.SH DIAGNOSTICS
-Exit status is 0 for no overlaps, 1 for some overlaps, 2 for trouble.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
-.SH "SEE ALSO"
-ci(1), co(1), ident(1), merge(1), rcs(1), rcsdiff(1), rcsintro(1), rlog(1),
-rcsfile(5)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.br
diff --git a/gnu/usr.bin/rcs/rcsmerge/rcsmerge.c b/gnu/usr.bin/rcs/rcsmerge/rcsmerge.c
deleted file mode 100644
index e09dc24..0000000
--- a/gnu/usr.bin/rcs/rcsmerge/rcsmerge.c
+++ /dev/null
@@ -1,286 +0,0 @@
-/* Merge RCS revisions. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.15 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.14 1995/06/01 16:23:43 eggert
- * (main): Report an error if -kb, so don't worry about binary stdout.
- * Punctuate messages properly. Rewrite to avoid `goto end'.
- *
- * Revision 5.13 1994/03/17 14:05:48 eggert
- * Specify subprocess input via file descriptor, not file name. Remove lint.
- *
- * Revision 5.12 1993/11/09 17:40:15 eggert
- * -V now prints version on stdout and exits. Don't print usage twice.
- *
- * Revision 5.11 1993/11/03 17:42:27 eggert
- * Add -A, -E, -e, -z. Ignore -T. Allow up to three file labels.
- * Pass -Vn to `co'. Pass unexpanded revision name to `co', so that Name works.
- *
- * Revision 5.10 1992/07/28 16:12:44 eggert
- * Add -V.
- *
- * Revision 5.9 1992/01/24 18:44:19 eggert
- * lint -> RCS_lint
- *
- * Revision 5.8 1992/01/06 02:42:34 eggert
- * Update usage string.
- *
- * Revision 5.7 1991/11/20 17:58:09 eggert
- * Don't Iopen(f, "r+"); it's not portable.
- *
- * Revision 5.6 1991/08/19 03:13:55 eggert
- * Add -r$. Tune.
- *
- * Revision 5.5 1991/04/21 11:58:27 eggert
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.4 1991/02/25 07:12:43 eggert
- * Merging a revision to itself is no longer an error.
- *
- * Revision 5.3 1990/11/01 05:03:50 eggert
- * Remove unneeded setid check.
- *
- * Revision 5.2 1990/09/04 08:02:28 eggert
- * Check for I/O error when reading working file.
- *
- * Revision 5.1 1990/08/29 07:14:04 eggert
- * Add -q. Pass -L options to merge.
- *
- * Revision 5.0 1990/08/22 08:13:41 eggert
- * Propagate merge's exit status.
- * Remove compile-time limits; use malloc instead.
- * Make lock and temp files faster and safer. Ansify and Posixate. Add -V.
- * Don't use access(). Tune.
- *
- * Revision 4.5 89/05/01 15:13:16 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.4 88/08/09 19:13:13 eggert
- * Beware merging into a readonly file.
- * Beware merging a revision to itself (no change).
- * Use execv(), not system(); yield exit status like diff(1)'s.
- *
- * Revision 4.3 87/10/18 10:38:02 narten
- * Updating version numbers. Changes relative to version 1.1
- * actually relative to 4.1
- *
- * Revision 1.3 87/09/24 14:00:31 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:36 jenkins
- * Port to suns
- *
- * Revision 4.1 83/03/28 11:14:57 wft
- * Added handling of default branch.
- *
- * Revision 3.3 82/12/24 15:29:00 wft
- * Added call to catchsig().
- *
- * Revision 3.2 82/12/10 21:32:02 wft
- * Replaced getdelta() with gettree(); improved error messages.
- *
- * Revision 3.1 82/11/28 19:27:44 wft
- * Initial revision.
- *
- */
-#include "rcsbase.h"
-
-static char const co[] = CO;
-
-mainProg(rcsmergeId, "rcsmerge", "$FreeBSD$")
-{
- static char const cmdusage[] =
- "\nrcsmerge usage: rcsmerge -rrev1 [-rrev2] -ksubst -{pq}[rev] -Vn -xsuff -zzone file";
- static char const quietarg[] = "-q";
-
- register int i;
- char *a, **newargv;
- char const *arg[3];
- char const *rev[3], *xrev[3]; /*revision numbers*/
- char const *edarg, *expandarg, *suffixarg, *versionarg, *zonearg;
- int tostdout;
- int status;
- RILE *workptr;
- struct buf commarg;
- struct buf numericrev; /* holds expanded revision number */
- struct hshentries *gendeltas; /* deltas to be generated */
- struct hshentry * target;
-
- bufautobegin(&commarg);
- bufautobegin(&numericrev);
- edarg = rev[1] = rev[2] = 0;
- status = 0; /* Keep lint happy. */
- tostdout = false;
- expandarg = suffixarg = versionarg = zonearg = quietarg; /* no-op */
- suffixes = X_DEFAULT;
-
- argc = getRCSINIT(argc, argv, &newargv);
- argv = newargv;
- while (a = *++argv, 0<--argc && *a++=='-') {
- switch (*a++) {
- case 'p':
- tostdout=true;
- goto revno;
-
- case 'q':
- quietflag = true;
- revno:
- if (!*a)
- break;
- /* falls into -r */
- case 'r':
- if (!rev[1])
- rev[1] = a;
- else if (!rev[2])
- rev[2] = a;
- else
- error("too many revision numbers");
- break;
-
- case 'A': case 'E': case 'e':
- if (*a)
- goto unknown;
- edarg = *argv;
- break;
-
- case 'x':
- suffixarg = *argv;
- suffixes = a;
- break;
- case 'z':
- zonearg = *argv;
- zone_set(a);
- break;
- case 'T':
- /* Ignore -T, so that RCSINIT can contain -T. */
- if (*a)
- goto unknown;
- break;
- case 'V':
- versionarg = *argv;
- setRCSversion(versionarg);
- break;
-
- case 'k':
- expandarg = *argv;
- if (0 <= str2expmode(expandarg+2))
- break;
- /* fall into */
- default:
- unknown:
- error("unknown option: %s%s", *argv, cmdusage);
- };
- } /* end of option processing */
-
- if (!rev[1]) faterror("no base revision number given");
-
- /* Now handle all pathnames. */
-
- if (!nerror) {
- if (argc < 1)
- faterror("no input file%s", cmdusage);
- if (0 < pairnames(argc, argv, rcsreadopen, true, false)) {
-
- if (argc>2 || (argc==2 && argv[1]))
- warn("excess arguments ignored");
- if (Expand == BINARY_EXPAND)
- workerror("merging binary files");
- diagnose("RCS file: %s\n", RCSname);
- if (!(workptr = Iopen(workname, FOPEN_R_WORK, (struct stat*)0)))
- efaterror(workname);
-
- gettree(); /* reads in the delta tree */
-
- if (!Head) rcsfaterror("no revisions present");
-
- if (!*rev[1])
- rev[1] = Dbranch ? Dbranch : Head->num;
- if (fexpandsym(rev[1], &numericrev, workptr)
- && (target=genrevs(numericrev.string, (char *)0, (char *)0, (char*)0, &gendeltas))
- ) {
- xrev[1] = target->num;
- if (!rev[2] || !*rev[2])
- rev[2] = Dbranch ? Dbranch : Head->num;
- if (fexpandsym(rev[2], &numericrev, workptr)
- && (target=genrevs(numericrev.string, (char *)0, (char *)0, (char *)0, &gendeltas))
- ) {
- xrev[2] = target->num;
-
- if (strcmp(xrev[1],xrev[2]) == 0) {
- if (tostdout) {
- fastcopy(workptr, stdout);
- Ofclose(stdout);
- }
- } else {
- Izclose(&workptr);
-
- for (i=1; i<=2; i++) {
- diagnose("retrieving revision %s\n", xrev[i]);
- bufscpy(&commarg, "-p");
- bufscat(&commarg, rev[i]); /* not xrev[i], for $Name's sake */
- if (run(
- -1,
- /* Do not collide with merger.c maketemp(). */
- arg[i] = maketemp(i+2),
- co, quietarg, commarg.string,
- expandarg, suffixarg, versionarg, zonearg,
- RCSname, (char*)0
- ))
- rcsfaterror("co failed");
- }
- diagnose("Merging differences between %s and %s into %s%s\n",
- xrev[1], xrev[2], workname,
- tostdout?"; result to stdout":"");
-
- arg[0] = xrev[0] = workname;
- status = merge(tostdout, edarg, xrev, arg);
- }
- }
- }
-
- Izclose(&workptr);
- }
- }
- tempunlink();
- exitmain(nerror ? DIFF_TROUBLE : status);
-}
-
-#if RCS_lint
-# define exiterr rmergeExit
-#endif
- void
-exiterr()
-{
- tempunlink();
- _exit(DIFF_TROUBLE);
-}
diff --git a/gnu/usr.bin/rcs/rcstest b/gnu/usr.bin/rcs/rcstest
deleted file mode 100755
index 75165f1..0000000
--- a/gnu/usr.bin/rcs/rcstest
+++ /dev/null
@@ -1,454 +0,0 @@
-#! /bin/sh
-
-# Test RCS's functions.
-# The RCS commands are searched for in the PATH as usual;
-# to test the working directory's commands, prepend . to your PATH.
-
-# Test RCS by creating files RCS/a.* and RCS/a.c.
-# If all goes well, output nothing, and remove the temporary files.
-# Otherwise, send a message to standard output.
-# Exit status is 0 if OK, 1 if an RCS bug is found, and 2 if scaffolding fails.
-# With the -v option, output more debugging info.
-
-# If diff outputs `No differences encountered' when comparing identical files,
-# then rcstest may also output these noise lines; ignore them.
-
-# The current directory and ./RCS must be readable, writable, and searchable.
-
-# $FreeBSD$
-
-
-# Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
-# Distributed under license by the Free Software Foundation, Inc.
-#
-# This file is part of RCS.
-#
-# 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.
-#
-# 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.
-#
-# 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,
-# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# Report problems and direct all questions to:
-#
-# rcs-bugs@cs.purdue.edu
-
-# The Makefile overrides the following defaults.
-: ${ALL_CFLAGS=-Dhas_conf_h}
-: ${CC=cc}
-: ${DIFF=diff}
-# : ${LDFLAGS=} ${LIBS=} tickles old shell bug
-
-CL="$CC $ALL_CFLAGS $LDFLAGS -o a.out"
-L=$LIBS
-
-RCSINIT=-x
-export RCSINIT
-
-SLASH=/
-RCSfile=RCS${SLASH}a.c
-RCS_alt=RCS${SLASH}a.d
-lockfile=RCS${SLASH}a._
-
-case $1 in
--v) q=; set -x;;
-'') q=-q;;
-*) echo >&2 "$0: usage: $0 [-v]"; exit 2
-esac
-
-if test -d RCS
-then rmdir=:
-else rmdir=rmdir; mkdir RCS || exit
-fi
-
-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; }
-
-case "`$DIFF -c a.11 a.3x1`" in
-*!\ 1.1.1.1)
- diff="$DIFF -c";;
-*)
- echo "#warning: $DIFF -c does not work, so diagnostics may be cryptic"
- diff=$DIFF
-esac
-
-rcs -i -L -ta.11 $q a.c &&
-test -r $RCSfile || {
- echo "#rcs -i -L failed; perhaps RCS is not properly installed."
- exit 1
-}
-
-rlog a.c >/dev/null || { echo "#rlog failed on empty RCS file"; exit 1; }
-rm -f $RCSfile || exit 2
-
-cp a.11 a.c &&
-ci -ta.11 -mm $q a.c &&
-test -r $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
- co $l $q a.c &&
- test -f a.c || { echo '#co' $l did not create working file; exit 1; }
- $diff a.11 a.c || { echo '#ci' followed by co $l is not a no-op; exit 1; }
-done
-
-cp a.12 a.c &&
-ci -mm $q a.c &&
-co $q a.c &&
-$diff a.12 a.c || { echo "#ci+co failed"; exit 1; }
-
-rm -f a.c &&
-co -r1.1 $q a.c &&
-$diff a.11 a.c || { echo "#can't retrieve first revision"; exit 1; }
-
-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 &&
-$diff a.3x1 a.c || { echo "#branches failed"; exit 1; }
-
-rm -f a.c &&
-co -l $q a.c &&
-ci -f -mm $q a.c &&
-co -r1.3 $q a.c &&
-$diff a.12 a.c || { echo "#(co -l; ci -f) failed"; exit 1; }
-
-rm -f a.c &&
-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; }
-
-rm -f a.c &&
-co -l $q a.c &&
-echo 1.5 >a.c &&
-ci -u -mm $q a.c &&
-test -r 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; }
-
-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; }
-
-rm -f a.c &&
-cp a.11 a.c &&
-co -f $q a.c || { echo "#co -f failed"; exit 1; }
-$diff a.11 a.c >/dev/null && { echo "#co -f had no effect"; exit 1; }
-
-co -p1.1 $q a.c >a.t &&
-$diff a.11 a.t || { echo "#co -p failed"; exit 1; }
-
-for n in n N
-do
- rm -f a.c &&
- co -l $q a.c &&
- echo $n >a.$n &&
- cp a.$n a.c &&
- ci -${n}n -mm $q a.c &&
- co -rn $q a.c &&
- $diff a.$n a.c || { echo "#ci -$n failed"; exit 1; }
-done
-
-case $LOGNAME in
-?*) me=$LOGNAME;;
-*)
- case $USER in
- ?*) me=$USER;;
- *)
- me=`who am i` || exit 2
- me=`echo "$me" | sed -e 's/ .*//' -e 's/.*!//'`
- case $me in
- '') echo >&2 "$0: cannot deduce user name"; exit 2
- esac
- esac
-esac
-
-
-# Get the date of the previous revision in UTC.
-date=`rlog -r a.c | sed -n '/^date: /{ s///; s/;.*//; p; q; }'` || exit
-case $date in
-[0-9][0-9][0-9]*[0-9]/[0-1][0-9]/[0-3][0-9]\ [0-2][0-9]:[0-5][0-9]:[0-6][0-9]);;
-*) echo >&2 "$0: $date: bad rlog date output"; exit 1
-esac
-PWD=`pwd` && export PWD &&
-rm -f a.c &&
-co -l $q a.c &&
-sed 's/@/$/g' >a.kv <<EOF
-@Author: w @
-@Date: $date @
-@Header: $PWD$SLASH$RCSfile 2.1 $date w s @
-@Id: a.c 2.1 $date w s @
-@Locker: @
- * @Log: a.c @
- * Revision 2.1 $date w
- * m
- *
-@Name: Oz @
-@RCSfile: a.c @
-@Revision: 2.1 @
-@Source: $PWD$SLASH$RCSfile @
-@State: s @
-EOF
-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 s/Oz//g a.kv >a.e &&
-sed s/Oz/N/g a.kv >a.N &&
-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" -nOz -ss -ww -u2.1 -mm $q a.c &&
-$diff a.kv a.c || { echo "#keyword expansion failed"; exit 1; }
-co -pOz -ko $q a.c >a.oo &&
-$diff a.o a.oo || { echo "#co -p -ko failed"; exit 1; }
-cp a.kv a.o && cp a.o a.b || exit 2
-rcs -oOz $q a.c &&
-rcs -l $q a.c &&
-ci -k -u $q a.c &&
-$diff a.kv a.c || { echo "#ci -k failed"; exit 1; }
-sed -n 's/^[^$]*\$/$/p' a.kv >a.i &&
-ident a.c >a.i1 &&
-sed -e 1d -e 's/^[ ]*//' a.i1 >a.i2 &&
-$diff a.i a.i2 || { echo "#ident failed"; exit 1; }
-
-rcs -i $q a.c 2>/dev/null && { echo "#rcs -i permitted existing file"; exit 1; }
-
-rm -f a.c &&
-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; }
-
-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; }
-
-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; }
-
-rm -f a.c &&
-rcs -nN:1.1 $q a.c &&
-co -rN $q a.c &&
-$diff a.11 a.c || { echo "#rcs -n failed"; exit 1; }
-
-rm -f a.c &&
-rcs -NN:2.1 $q a.c &&
-co -rN $q a.c &&
-$diff a.N a.c || { echo "#rcs -N failed"; exit 1; }
-
-rm -f a.c &&
-co -l $q a.c &&
-echo ':::$''Log$' >a.c &&
-ci -u -mm $q a.c &&
-test " `sed '$!d' a.c`" = ' :::' || { echo "#comment leader failed"; exit 1; }
-
-rm -f a.c &&
-rcs -o2.2: $q a.c &&
-co $q a.c &&
-$diff a.e a.c || { echo "#rcs -o failed"; exit 1; }
-
-rcsdiff -r1.1 -rOz $q a.c >a.0
-case $? in
-1) ;;
-*) echo "#rcsdiff bad status"; exit 1
-esac
-$DIFF a.11 a.kv >a.1
-$diff a.0 a.1 || { echo "#rcsdiff failed"; exit 1; }
-
-rcs -l2.1 $q a.c || { echo "#rcs -l2.1 failed"; exit 1; }
-for i in b k kv kvl o v
-do
- rm -f a.c &&
- cp a.$i a.c &&
- rcsdiff -k$i -rOz $q a.c || { echo "#rcsdiff -k$i failed"; exit 1; }
-done
-co -p1.1 -ko $q a.c >a.t &&
-$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; }
-
-rm -f a.c &&
-rcsclean $q a.c &&
-rcsclean -u $q a.c || { echo "#rcsclean botched a nonexistent file"; exit 1; }
-
-rm -f a.c &&
-co $q a.c &&
-rcsclean -n $q a.c &&
-rcsclean -n -u $q a.c &&
-test -f a.c || { echo "#rcsclean -n removed a file"; exit 1; }
-
-rm -f a.c &&
-co $q a.c &&
-rcsclean $q a.c &&
-test ! -f a.c || { echo "#rcsclean missed an unlocked file"; exit 1; }
-
-rm -f a.c &&
-co -l $q a.c &&
-rcsclean $q a.c &&
-test -f a.c || { echo "#rcsclean removed a locked file"; exit 1; }
-rcsclean -u $q a.c &&
-test ! -f a.c || {
- echo "#rcsclean -u missed an unchanged locked file"; exit 1;
-}
-
-rm -f a.c &&
-co -l $q a.c &&
-echo change >>a.c &&
-rcsclean $q a.c &&
-rcsclean $q -u a.c &&
-test -f a.c || { echo "#rcsclean removed a changed file"; exit 1; }
-
-rm -f a.c &&
-co -l $q a.c &&
-cat >a.c <<'EOF'
-2.2
-a
-b
-c
-d
-EOF
-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'
-2.3
-a
-b1
-c
-d1
-EOF
-cat >a.1 <<'EOF'
-<<<<<<< a.c
-new
-=======
-2.3
->>>>>>> 2.3
-a
-b1
-c
-d1
-EOF
-rcsmerge -E -r2.2 -r2.3 $q a.c
-case $? in
-0)
- if $diff a.0 a.c >/dev/null
- then echo "#warning: diff3 -E does not work, " \
- "so merge and rcsmerge ignore overlaps and suppress overlap lines."
- else
- $diff a.1 a.c || { echo "#rcsmerge failed (status 0)"; exit 1; }
- echo "#warning: The diff3 lib program exit status ignores overlaps," \
- "so rcsmerge does not warn about overlap lines that it generates."
- fi
- ;;
-1)
- $diff a.1 a.c || { echo "#rcsmerge failed (status 1)"; exit 1; }
- ;;
-*)
- echo "#rcsmerge bad status"; exit 1
-esac
-
-# Avoid `tr' if possible; it's not portable, and it can't handle null bytes.
-# Our substitute exclusive-ORs with '\n';
-# this ensures null bytes on output, which is even better than `tr',
-# since some diffs think a file is binary only if it contains null bytes.
-cat >a.c <<'EOF'
-#include <stdio.h>
-int main() {
- int c;
- while ((c=getchar()) != EOF)
- putchar(c ^ '\n');
- return 0;
-}
-EOF
-tr=tr
-if (rm -f a.exe a.out && $CL a.c $L >&2) >/dev/null 2>&1
-then
- if test -s a.out
- then tr=./a.out
- elif test -s a.exe
- then tr=./a.exe
- fi
-fi
-{
- co -p $q a.c | $tr '\012' '\200' >a.24 &&
- cp a.24 a.c &&
- ciOut=`(ci -l -mm $q a.c 2>&1)` &&
- case $ciOut in
- ?*) echo >&2 "$ciOut"
- esac &&
- co -p $q a.c | $tr '\200' '\012' >a.c &&
- rcsdiff -r2.3 $q a.c >/dev/null &&
-
- echo 2.5 >a.c &&
- ci -l -mm $q a.c &&
- cp a.24 a.c &&
- rcsdiff -r2.4 $q a.c >/dev/null
-} || echo "#warning: Traditional diff is used, so RCS is limited to text files."
-
-rcs -u -o2.4: $q a.c || { echo "#rcs -u -o failed"; exit 1; }
-
-rcs -i -Aa.c -t- $q a.d || { echo "#rcs -i -A failed"; exit 1; }
-
-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 &&
-$diff - a.u <<EOF
-
-RCS file: $RCSfile
-Working file: a.c
-head: 2.3
-branch:
-locks: strict
-access list:
-symbolic names:
- N: 2.1
- Oz: 2.1
- n: 1.8
-keyword substitution: kv
-total revisions: 13; selected revisions: 1
-description:
-1.1
-----------------------------
-revision 2.1
-date: $date; author: w; state: s; lines: +14 -1
-=============================================================================
-EOF
-test $? = 0 || { echo "#rlog failed"; exit 1; }
-
-
-test ! -f $lockfile || { echo "#lock file not removed"; exit 1; }
-
-rm -f a.* $RCSfile $RCS_alt
-$rmdir RCS
diff --git a/gnu/usr.bin/rcs/rlog/Makefile b/gnu/usr.bin/rcs/rlog/Makefile
deleted file mode 100644
index bdbf68f..0000000
--- a/gnu/usr.bin/rcs/rlog/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-PROG= rlog
-SRCS= rlog.c
-CFLAGS+= -I${.CURDIR}/../lib
-LDADD= ${LIBRCS}
-DPADD= ${LIBRCS}
-
-.include "../../Makefile.inc"
-.include <bsd.prog.mk>
diff --git a/gnu/usr.bin/rcs/rlog/rlog.1 b/gnu/usr.bin/rcs/rlog/rlog.1
deleted file mode 100644
index 26bf08a..0000000
--- a/gnu/usr.bin/rcs/rlog/rlog.1
+++ /dev/null
@@ -1,318 +0,0 @@
-.de Id
-.ds Rv \\$3
-.ds Dt \\$4
-..
-.Id $FreeBSD$
-.ds i \&\s-1ISO\s0
-.ds r \&\s-1RCS\s0
-.ds u \&\s-1UTC\s0
-.if n .ds - \%--
-.if t .ds - \(em
-.TH RLOG 1 \*(Dt GNU
-.SH NAME
-rlog \- print log messages and other information about RCS files
-.SH SYNOPSIS
-.B rlog
-.RI [ " options " ] " file " .\|.\|.
-.SH DESCRIPTION
-.B rlog
-prints information about \*r files.
-.PP
-Pathnames matching an \*r suffix denote \*r files;
-all others denote working files.
-Names are paired as explained in
-.BR ci (1).
-.PP
-.B rlog
-prints the following information for each
-\*r file: \*r pathname, working pathname, head (i.e., the number
-of the latest revision on the trunk), default branch, access list, locks,
-symbolic names, suffix, total number of revisions,
-number of revisions selected for printing, and
-descriptive text. This is followed by entries for the selected revisions in
-reverse chronological order for each branch. For each revision,
-.B rlog
-prints revision number, author, date/time, state, number of
-lines added/deleted (with respect to the previous revision),
-locker of the revision (if any), and log message.
-All times are displayed in Coordinated Universal Time (\*u) by default;
-this can be overridden with
-.BR \-z .
-Without options,
-.B rlog
-prints complete information.
-The options below restrict this output.
-.nr n \w'\f3\-V\fP\f2n\fP'+2n-1/1n
-.ds n \nn
-.if \n(.g .if r an-tag-sep .ds n \w'\f3\-V\fP\f2n\fP'u+\n[an-tag-sep]u
-.TP \*n
-.B \-L
-Ignore \*r files that have no locks set.
-This is convenient in combination with
-.BR \-h ,
-.BR \-l ,
-and
-.BR \-R .
-.TP
-.B \-R
-Print only the name of the \*r file.
-This is convenient for translating a
-working pathname into an \*r pathname.
-.TP
-.BI \-v "[string]"
-Print only the working pathname and tip-revision.
-The optional string is prepended to the outputline.
-.TP
-.B \-h
-Print only the \*r pathname, working pathname, head,
-default branch, access list, locks,
-symbolic names, and suffix.
-.TP
-.B \-t
-Print the same as
-.BR \-h ,
-plus the descriptive text.
-.TP
-.B \-N
-Do not print the symbolic names.
-.TP
-.B \-b
-Print information about the revisions on the default branch, normally
-the highest branch on the trunk.
-.TP
-.BI \-d "dates"
-Print information about revisions with a checkin date/time in the ranges given by
-the semicolon-separated list of
-.IR dates .
-A range of the form
-.IB d1 < d2
-or
-.IB d2 > d1
-selects the revisions that were deposited between
-.I d1
-and
-.I d2
-exclusive.
-A range of the form
-.BI < d
-or
-.IB d >
-selects
-all revisions earlier than
-.IR d .
-A range of the form
-.IB d <
-or
-.BI > d
-selects
-all revisions dated later than
-.IR d .
-If
-.B <
-or
-.B >
-is followed by
-.B =
-then the ranges are inclusive, not exclusive.
-A range of the form
-.I d
-selects the single, latest revision dated
-.I d
-or earlier.
-The date/time strings
-.IR d ,
-.IR d1 ,
-and
-.I d2
-are in the free format explained in
-.BR co (1).
-Quoting is normally necessary, especially for
-.B <
-and
-.BR > .
-Note that the separator is
-a semicolon.
-.TP
-.BR \-l [\f2lockers\fP]
-Print information about locked revisions only.
-In addition, if the comma-separated list
-.I lockers
-of login names is given,
-ignore all locks other than those held by the
-.IR lockers .
-For example,
-.B "rlog\ \-L\ \-R\ \-lwft\ RCS/*"
-prints the name of \*r files locked by the user
-.BR wft .
-.TP
-.BR \-r [\f2revisions\fP]
-prints information about revisions given in the comma-separated list
-.I revisions
-of revisions and ranges.
-A range
-.IB rev1 : rev2
-means revisions
-.I rev1
-to
-.I rev2
-on the same branch,
-.BI : rev
-means revisions from the beginning of the branch up to and including
-.IR rev ,
-and
-.IB rev :
-means revisions starting with
-.I rev
-to the end of the branch containing
-.IR rev .
-An argument that is a branch means all
-revisions on that branch.
-A range of branches means all revisions
-on the branches in that range.
-A branch followed by a
-.B .\&
-means the latest revision in that branch.
-A bare
-.B \-r
-with no
-.I revisions
-means the latest revision on the default branch, normally the trunk.
-.TP
-.BI \-s states
-prints information about revisions whose state attributes match one of the
-states given in the comma-separated list
-.IR states .
-.TP
-.BR \-w [\f2logins\fP]
-prints information about revisions checked in by users with
-login names appearing in the comma-separated list
-.IR logins .
-If
-.I logins
-is omitted, the user's login is assumed.
-.TP
-.B \-T
-This option has no effect;
-it is present for compatibility with other \*r commands.
-.TP
-.BI \-V
-Print \*r's version number.
-.TP
-.BI \-V n
-Emulate \*r version
-.I n
-when generating logs.
-See
-.BR co (1)
-for more.
-.TP
-.BI \-x "suffixes"
-Use
-.I suffixes
-to characterize \*r files.
-See
-.BR ci (1)
-for details.
-.PP
-.B rlog
-prints the intersection of the revisions selected with
-the options
-.BR \-d ,
-.BR \-l ,
-.BR \-s ,
-and
-.BR \-w ,
-intersected
-with the union of the revisions selected by
-.B \-b
-and
-.BR \-r .
-.TP
-.BI \-z zone
-specifies the date output format,
-and specifies the default time zone for
-.I date
-in the
-.BI \-d dates
-option.
-The
-.I zone
-should be empty, a numeric \*u offset, or the special string
-.B LT
-for local time.
-The default is an empty
-.IR zone ,
-which uses the traditional \*r format of \*u without any time zone indication
-and with slashes separating the parts of the date;
-otherwise, times are output in \*i 8601 format with time zone indication.
-For example, if local time is January 11, 1990, 8pm Pacific Standard Time,
-eight hours west of \*u,
-then the time is output as follows:
-.RS
-.LP
-.RS
-.nf
-.ta \w'\f3\-z+05:30\fP 'u +\w'\f31990-01-11 09:30:00+05:30\fP 'u
-.ne 4
-\f2option\fP \f2time output\fP
-\f3\-z\fP \f31990/01/12 04:00:00\fP \f2(default)\fP
-\f3\-zLT\fP \f31990-01-11 20:00:00\-08\fP
-\f3\-z+05:30\fP \f31990-01-12 09:30:00+05:30\fP
-.ta 4n +4n +4n +4n
-.fi
-.RE
-.SH EXAMPLES
-.LP
-.nf
-.B " rlog \-L \-R RCS/*"
-.B " rlog \-L \-h RCS/*"
-.B " rlog \-L \-l RCS/*"
-.B " rlog RCS/*"
-.fi
-.LP
-The first command prints the names of all \*r files in the subdirectory
-.B RCS
-that have locks. The second command prints the headers of those files,
-and the third prints the headers plus the log messages of the locked revisions.
-The last command prints complete information.
-.SH ENVIRONMENT
-.TP
-.B \s-1RCSINIT\s0
-options prepended to the argument list, separated by spaces.
-See
-.BR ci (1)
-for details.
-.SH DIAGNOSTICS
-The exit status is zero if and only if all operations were successful.
-.SH IDENTIFICATION
-Author: Walter F. Tichy.
-.br
-Manual Page Revision: \*(Rv; Release Date: \*(Dt.
-.br
-Copyright \(co 1982, 1988, 1989 Walter F. Tichy.
-.br
-Copyright \(co 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert.
-.SH "SEE ALSO"
-ci(1), co(1), ident(1), rcs(1), rcsdiff(1), rcsintro(1), rcsmerge(1),
-rcsfile(5)
-.br
-Walter F. Tichy,
-\*r\*-A System for Version Control,
-.I "Software\*-Practice & Experience"
-.BR 15 ,
-7 (July 1985), 637-654.
-.SH BUGS
-The separator for revision ranges in the
-.B \-r
-option used to be
-.B \-
-instead of
-.BR : ,
-but this leads to confusion when symbolic names contain
-.BR \- .
-For backwards compatibility
-.B "rlog \-r"
-still supports the old
-.B \-
-separator, but it warns about this obsolete use.
-.br
diff --git a/gnu/usr.bin/rcs/rlog/rlog.c b/gnu/usr.bin/rcs/rlog/rlog.c
deleted file mode 100644
index f8872fe..0000000
--- a/gnu/usr.bin/rcs/rlog/rlog.c
+++ /dev/null
@@ -1,1290 +0,0 @@
-/* Print log messages and other information about RCS files. */
-
-/* Copyright 1982, 1988, 1989 Walter Tichy
- Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
- Distributed under license by the Free Software Foundation, Inc.
-
-This file is part of RCS.
-
-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.
-
-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.
-
-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,
-59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-Report problems and direct all questions to:
-
- rcs-bugs@cs.purdue.edu
-
-*/
-
-/*
- * Revision 5.18 1995/06/16 06:19:24 eggert
- * Update FSF address.
- *
- * Revision 5.17 1995/06/01 16:23:43 eggert
- * (struct rcslockers): Renamed from `struct lockers'.
- * (getnumericrev): Return error indication instead of ignoring errors.
- * (main): Check it. Don't use dateform.
- * (recentdate, extdate): cmpnum -> cmpdate
- *
- * Revision 5.16 1994/04/13 16:30:34 eggert
- * Fix bug; `rlog -lxxx' inverted the sense of -l.
- *
- * Revision 5.15 1994/03/17 14:05:48 eggert
- * -d'<DATE' now excludes DATE; the new syntax -d'<=DATE' includes it.
- * Emulate -V4's white space generation more precisely.
- * Work around SVR4 stdio performance bug. Remove lint.
- *
- * Revision 5.14 1993/11/09 17:40:15 eggert
- * -V now prints version on stdout and exits.
- *
- * Revision 5.13 1993/11/03 17:42:27 eggert
- * Add -N, -z. Ignore -T.
- *
- * Revision 5.12 1992/07/28 16:12:44 eggert
- * Don't miss B.0 when handling branch B. Diagnose missing `,' in -r.
- * Add -V. Avoid `unsigned'. Statement macro names now end in _.
- *
- * Revision 5.11 1992/01/24 18:44:19 eggert
- * Don't duplicate unexpected_EOF's function. lint -> RCS_lint
- *
- * Revision 5.10 1992/01/06 02:42:34 eggert
- * Update usage string.
- * while (E) ; -> while (E) continue;
- *
- * Revision 5.9 1991/09/17 19:07:40 eggert
- * Getscript() didn't uncache partial lines.
- *
- * Revision 5.8 1991/08/19 03:13:55 eggert
- * Revision separator is `:', not `-'.
- * Check for missing and duplicate logs. Tune.
- * Permit log messages that do not end in newline (including empty logs).
- *
- * Revision 5.7 1991/04/21 11:58:31 eggert
- * Add -x, RCSINIT, MS-DOS support.
- *
- * Revision 5.6 1991/02/26 17:07:17 eggert
- * Survive RCS files with missing logs.
- * strsave -> str_save (DG/UX name clash)
- *
- * Revision 5.5 1990/11/01 05:03:55 eggert
- * Permit arbitrary data in logs and comment leaders.
- *
- * Revision 5.4 1990/10/04 06:30:22 eggert
- * Accumulate exit status across files.
- *
- * Revision 5.3 1990/09/11 02:41:16 eggert
- * Plug memory leak.
- *
- * Revision 5.2 1990/09/04 08:02:33 eggert
- * Count RCS lines better.
- *
- * Revision 5.0 1990/08/22 08:13:48 eggert
- * Remove compile-time limits; use malloc instead. Add setuid support.
- * Switch to GMT.
- * Report dates in long form, to warn about dates past 1999/12/31.
- * Change "added/del" message to make room for the longer dates.
- * Don't generate trailing white space. Add -V. Ansify and Posixate.
- *
- * Revision 4.7 89/05/01 15:13:48 narten
- * changed copyright header to reflect current distribution rules
- *
- * Revision 4.6 88/08/09 19:13:28 eggert
- * Check for memory exhaustion; don't access freed storage.
- * Shrink stdio code size; remove lint.
- *
- * Revision 4.5 87/12/18 11:46:38 narten
- * more lint cleanups (Guy Harris)
- *
- * Revision 4.4 87/10/18 10:41:12 narten
- * Updating version numbers
- * Changes relative to 1.1 actually relative to 4.2
- *
- * Revision 1.3 87/09/24 14:01:10 narten
- * Sources now pass through lint (if you ignore printf/sprintf/fprintf
- * warnings)
- *
- * Revision 1.2 87/03/27 14:22:45 jenkins
- * Port to suns
- *
- * Revision 4.2 83/12/05 09:18:09 wft
- * changed rewriteflag to external.
- *
- * Revision 4.1 83/05/11 16:16:55 wft
- * Added -b, updated getnumericrev() accordingly.
- * Replaced getpwuid() with getcaller().
- *
- * Revision 3.7 83/05/11 14:24:13 wft
- * Added options -L and -R;
- * Fixed selection bug with -l on multiple files.
- * Fixed error on dates of the form -d'>date' (rewrote getdatepair()).
- *
- * Revision 3.6 82/12/24 15:57:53 wft
- * shortened output format.
- *
- * Revision 3.5 82/12/08 21:45:26 wft
- * removed call to checkaccesslist(); used DATEFORM to format all dates;
- * removed unused variables.
- *
- * Revision 3.4 82/12/04 13:26:25 wft
- * Replaced getdelta() with gettree(); removed updating of field lockedby.
- *
- * Revision 3.3 82/12/03 14:08:20 wft
- * Replaced getlogin with getpwuid(), %02d with %.2d, fancydate with PRINTDATE.
- * Fixed printing of nil, removed printing of Suffix,
- * added shortcut if no revisions are printed, disambiguated struct members.
- *
- * Revision 3.2 82/10/18 21:09:06 wft
- * call to curdir replaced with getfullRCSname(),
- * fixed call to getlogin(), cosmetic changes on output,
- * changed conflicting long identifiers.
- *
- * Revision 3.1 82/10/13 16:07:56 wft
- * fixed type of variables receiving from getc() (char -> int).
- */
-
-
-
-#include "rcsbase.h"
-
-struct rcslockers { /* lockers in locker option; stored */
- char const * login; /* lockerlist */
- struct rcslockers * lockerlink;
- } ;
-
-struct stateattri { /* states in state option; stored in */
- char const * status; /* statelist */
- struct stateattri * nextstate;
- } ;
-
-struct authors { /* login names in author option; */
- char const * login; /* stored in authorlist */
- struct authors * nextauthor;
- } ;
-
-struct Revpairs{ /* revision or branch range in -r */
- int numfld; /* option; stored in revlist */
- char const * strtrev;
- char const * endrev;
- struct Revpairs * rnext;
- } ;
-
-struct Datepairs{ /* date range in -d option; stored in */
- struct Datepairs *dnext;
- char strtdate[datesize]; /* duelst and datelist */
- char enddate[datesize];
- char ne_date; /* datelist only; distinguishes < from <= */
- };
-
-static char extractdelta P((struct hshentry const*));
-static int checkrevpair P((char const*,char const*));
-static int extdate P((struct hshentry*));
-static int getnumericrev P((void));
-static struct hshentry const *readdeltalog P((void));
-static void cleanup P((void));
-static void exttree P((struct hshentry*));
-static void getauthor P((char*));
-static void getdatepair P((char*));
-static void getlocker P((char*));
-static void getrevpairs P((char*));
-static void getscript P((struct hshentry*));
-static void getstate P((char*));
-static void putabranch P((struct hshentry const*));
-static void putadelta P((struct hshentry const*,struct hshentry const*,int));
-static void putforest P((struct branchhead const*));
-static void putree P((struct hshentry const*));
-static void putrunk P((void));
-static void recentdate P((struct hshentry const*,struct Datepairs*));
-static void trunclocks P((void));
-
-static char const *insDelFormat;
-static int branchflag; /*set on -b */
-static int exitstatus;
-static int lockflag;
-static struct Datepairs *datelist, *duelst;
-static struct Revpairs *revlist, *Revlst;
-static struct authors *authorlist;
-static struct rcslockers *lockerlist;
-static struct stateattri *statelist;
-
-
-mainProg(rlogId, "rlog", "$FreeBSD$")
-{
- static char const cmdusage[] =
- "\nrlog usage: rlog -{bhLNRt} -v[string] -ddates -l[lockers] -r[revs] -sstates -Vn -w[logins] -xsuff -zzone file ...";
-
- register FILE *out;
- char *a, **newargv;
- struct Datepairs *currdate;
- char const *accessListString, *accessFormat;
- char const *headFormat, *symbolFormat;
- struct access const *curaccess;
- struct assoc const *curassoc;
- struct hshentry const *delta;
- struct rcslock const *currlock;
- int descflag, selectflag;
- int onlylockflag; /* print only files with locks */
- int onlyRCSflag; /* print only RCS pathname */
- int pre5;
- int shownames;
- int revno;
- int versionlist;
- char *vstring;
-
- descflag = selectflag = shownames = true;
- versionlist = onlylockflag = onlyRCSflag = false;
- vstring=0;
- out = stdout;
- suffixes = X_DEFAULT;
-
- argc = getRCSINIT(argc, argv, &newargv);
- argv = newargv;
- while (a = *++argv, 0<--argc && *a++=='-') {
- switch (*a++) {
-
- case 'L':
- onlylockflag = true;
- break;
-
- case 'N':
- shownames = false;
- break;
-
- case 'R':
- onlyRCSflag =true;
- break;
-
- case 'l':
- lockflag = true;
- getlocker(a);
- break;
-
- case 'b':
- branchflag = true;
- break;
-
- case 'r':
- getrevpairs(a);
- break;
-
- case 'd':
- getdatepair(a);
- break;
-
- case 's':
- getstate(a);
- break;
-
- case 'w':
- getauthor(a);
- break;
-
- case 'h':
- descflag = false;
- break;
-
- case 't':
- selectflag = false;
- break;
-
- case 'q':
- /* This has no effect; it's here for consistency. */
- quietflag = true;
- break;
-
- case 'x':
- suffixes = a;
- break;
-
- case 'z':
- zone_set(a);
- break;
-
- case 'T':
- /* Ignore -T, so that RCSINIT can contain -T. */
- if (*a)
- goto unknown;
- break;
-
- case 'V':
- setRCSversion(*argv);
- break;
-
- case 'v':
- versionlist = true;
- vstring = a;
- break;
-
- default:
- unknown:
- error("unknown option: %s%s", *argv, cmdusage);
-
- };
- } /* end of option processing */
-
- if (! (descflag|selectflag)) {
- warn("-t overrides -h.");
- descflag = true;
- }
-
- pre5 = RCSversion < VERSION(5);
- if (pre5) {
- accessListString = "\naccess list: ";
- accessFormat = " %s";
- headFormat = "RCS file: %s; Working file: %s\nhead: %s%s\nbranch: %s%s\nlocks: ";
- insDelFormat = " lines added/del: %ld/%ld";
- symbolFormat = " %s: %s;";
- } else {
- accessListString = "\naccess list:";
- accessFormat = "\n\t%s";
- headFormat = "RCS file: %s\nWorking file: %s\nhead:%s%s\nbranch:%s%s\nlocks:%s";
- insDelFormat = " lines: +%ld -%ld";
- symbolFormat = "\n\t%s: %s";
- }
-
- /* Now handle all pathnames. */
- if (nerror)
- cleanup();
- else if (argc < 1)
- faterror("no input file%s", cmdusage);
- else
- for (; 0 < argc; cleanup(), ++argv, --argc) {
- ffree();
-
- if (pairnames(argc, argv, rcsreadopen, true, false) <= 0)
- continue;
-
- /*
- * RCSname contains the name of the RCS file,
- * and finptr the file descriptor;
- * workname contains the name of the working file.
- */
-
- /* Keep only those locks given by -l. */
- if (lockflag)
- trunclocks();
-
- /* do nothing if -L is given and there are no locks*/
- if (onlylockflag && !Locks)
- continue;
-
- if ( versionlist ) {
- gettree();
- aprintf(out, "%s%s %s\n", vstring, workname, tiprev());
- continue;
- }
-
- if ( onlyRCSflag ) {
- aprintf(out, "%s\n", RCSname);
- continue;
- }
-
- gettree();
-
- if (!getnumericrev())
- continue;
-
- /*
- * Output the first character with putc, not printf.
- * Otherwise, an SVR4 stdio bug buffers output inefficiently.
- */
- aputc_('\n', out)
-
- /* print RCS pathname, working pathname and optional
- administrative information */
- /* could use getfullRCSname() here, but that is very slow */
- aprintf(out, headFormat, RCSname, workname,
- Head ? " " : "", Head ? Head->num : "",
- Dbranch ? " " : "", Dbranch ? Dbranch : "",
- StrictLocks ? " strict" : ""
- );
- currlock = Locks;
- while( currlock ) {
- aprintf(out, symbolFormat, currlock->login,
- currlock->delta->num);
- currlock = currlock->nextlock;
- }
- if (StrictLocks && pre5)
- aputs(" ; strict" + (Locks?3:0), out);
-
- aputs(accessListString, out); /* print access list */
- curaccess = AccessList;
- while(curaccess) {
- aprintf(out, accessFormat, curaccess->login);
- curaccess = curaccess->nextaccess;
- }
-
- if (shownames) {
- aputs("\nsymbolic names:", out); /* print symbolic names */
- for (curassoc=Symbols; curassoc; curassoc=curassoc->nextassoc)
- aprintf(out, symbolFormat, curassoc->symbol, curassoc->num);
- }
- if (pre5) {
- aputs("\ncomment leader: \"", out);
- awrite(Comment.string, Comment.size, out);
- afputc('\"', out);
- }
- if (!pre5 || Expand != KEYVAL_EXPAND)
- aprintf(out, "\nkeyword substitution: %s",
- expand_names[Expand]
- );
-
- aprintf(out, "\ntotal revisions: %d", TotalDeltas);
-
- revno = 0;
-
- if (Head && selectflag & descflag) {
-
- exttree(Head);
-
- /* get most recently date of the dates pointed by duelst */
- currdate = duelst;
- while( currdate) {
- VOID strcpy(currdate->strtdate, "0.0.0.0.0.0");
- recentdate(Head, currdate);
- currdate = currdate->dnext;
- }
-
- revno = extdate(Head);
-
- aprintf(out, ";\tselected revisions: %d", revno);
- }
-
- afputc('\n',out);
- if (descflag) {
- aputs("description:\n", out);
- getdesc(true);
- }
- if (revno) {
- while (! (delta = readdeltalog())->selector || --revno)
- continue;
- if (delta->next && countnumflds(delta->num)==2)
- /* Read through delta->next to get its insertlns. */
- while (readdeltalog() != delta->next)
- continue;
- putrunk();
- putree(Head);
- }
- aputs("----------------------------\n", out);
- aputs("=============================================================================\n",out);
- }
- Ofclose(out);
- exitmain(exitstatus);
-}
-
- static void
-cleanup()
-{
- if (nerror) exitstatus = EXIT_FAILURE;
- Izclose(&finptr);
-}
-
-#if RCS_lint
-# define exiterr rlogExit
-#endif
- void
-exiterr()
-{
- _exit(EXIT_FAILURE);
-}
-
-
-
- static void
-putrunk()
-/* function: print revisions chosen, which are in trunk */
-
-{
- register struct hshentry const *ptr;
-
- for (ptr = Head; ptr; ptr = ptr->next)
- putadelta(ptr, ptr->next, true);
-}
-
-
-
- static void
-putree(root)
- struct hshentry const *root;
-/* function: print delta tree (not including trunk) in reverse
- order on each branch */
-
-{
- if (!root) return;
-
- putree(root->next);
-
- putforest(root->branches);
-}
-
-
-
-
- static void
-putforest(branchroot)
- struct branchhead const *branchroot;
-/* function: print branches that has the same direct ancestor */
-{
- if (!branchroot) return;
-
- putforest(branchroot->nextbranch);
-
- putabranch(branchroot->hsh);
- putree(branchroot->hsh);
-}
-
-
-
-
- static void
-putabranch(root)
- struct hshentry const *root;
-/* function : print one branch */
-
-{
- if (!root) return;
-
- putabranch(root->next);
-
- putadelta(root, root, false);
-}
-
-
-
-
-
- static void
-putadelta(node,editscript,trunk)
- register struct hshentry const *node, *editscript;
- int trunk;
-/* function: Print delta node if node->selector is set. */
-/* editscript indicates where the editscript is stored */
-/* trunk indicated whether this node is in trunk */
-{
- static char emptych[] = EMPTYLOG;
-
- register FILE *out;
- char const *s;
- size_t n;
- struct branchhead const *newbranch;
- struct buf branchnum;
- char datebuf[datesize + zonelenmax];
- int pre5 = RCSversion < VERSION(5);
-
- if (!node->selector)
- return;
-
- out = stdout;
- aprintf(out,
- "----------------------------\nrevision %s%s",
- node->num, pre5 ? " " : ""
- );
- if ( node->lockedby )
- aprintf(out, pre5+"\tlocked by: %s;", node->lockedby);
-
- aprintf(out, "\ndate: %s; author: %s; state: %s;",
- date2str(node->date, datebuf),
- node->author, node->state
- );
-
- if ( editscript )
- if(trunk)
- aprintf(out, insDelFormat,
- editscript->deletelns, editscript->insertlns);
- else
- aprintf(out, insDelFormat,
- editscript->insertlns, editscript->deletelns);
-
- newbranch = node->branches;
- if ( newbranch ) {
- bufautobegin(&branchnum);
- aputs("\nbranches:", out);
- while( newbranch ) {
- getbranchno(newbranch->hsh->num, &branchnum);
- aprintf(out, " %s;", branchnum.string);
- newbranch = newbranch->nextbranch;
- }
- bufautoend(&branchnum);
- }
-
- afputc('\n', out);
- s = node->log.string;
- if (!(n = node->log.size)) {
- s = emptych;
- n = sizeof(emptych)-1;
- }
- awrite(s, n, out);
- if (s[n-1] != '\n')
- afputc('\n', out);
-}
-
-
- static struct hshentry const *
-readdeltalog()
-/* Function : get the log message and skip the text of a deltatext node.
- * Return the delta found.
- * Assumes the current lexeme is not yet in nexttok; does not
- * advance nexttok.
- */
-{
- register struct hshentry * Delta;
- struct buf logbuf;
- struct cbuf cb;
-
- if (eoflex())
- fatserror("missing delta log");
- nextlex();
- if (!(Delta = getnum()))
- fatserror("delta number corrupted");
- getkeystring(Klog);
- if (Delta->log.string)
- fatserror("duplicate delta log");
- bufautobegin(&logbuf);
- cb = savestring(&logbuf);
- Delta->log = bufremember(&logbuf, cb.size);
-
- ignorephrases(Ktext);
- getkeystring(Ktext);
- Delta->insertlns = Delta->deletelns = 0;
- if ( Delta != Head)
- getscript(Delta);
- else
- readstring();
- return Delta;
-}
-
-
- static void
-getscript(Delta)
-struct hshentry * Delta;
-/* function: read edit script of Delta and count how many lines added */
-/* and deleted in the script */
-
-{
- int ed; /* editor command */
- declarecache;
- register RILE *fin;
- register int c;
- register long i;
- struct diffcmd dc;
-
- fin = finptr;
- setupcache(fin);
- initdiffcmd(&dc);
- while (0 <= (ed = getdiffcmd(fin,true,(FILE *)0,&dc)))
- if (!ed)
- Delta->deletelns += dc.nlines;
- else {
- /* skip scripted lines */
- i = dc.nlines;
- Delta->insertlns += i;
- cache(fin);
- do {
- for (;;) {
- cacheget_(c)
- switch (c) {
- default:
- continue;
- case SDELIM:
- cacheget_(c)
- if (c == SDELIM)
- continue;
- if (--i)
- unexpected_EOF();
- nextc = c;
- uncache(fin);
- return;
- case '\n':
- break;
- }
- break;
- }
- ++rcsline;
- } while (--i);
- uncache(fin);
- }
-}
-
-
-
-
-
-
-
- static void
-exttree(root)
-struct hshentry *root;
-/* function: select revisions , starting with root */
-
-{
- struct branchhead const *newbranch;
-
- if (!root) return;
-
- root->selector = extractdelta(root);
- root->log.string = 0;
- exttree(root->next);
-
- newbranch = root->branches;
- while( newbranch ) {
- exttree(newbranch->hsh);
- newbranch = newbranch->nextbranch;
- }
-}
-
-
-
-
- static void
-getlocker(argv)
-char * argv;
-/* function : get the login names of lockers from command line */
-/* and store in lockerlist. */
-
-{
- register char c;
- struct rcslockers *newlocker;
- argv--;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- if ( c == '\0') {
- lockerlist = 0;
- return;
- }
-
- while( c != '\0' ) {
- newlocker = talloc(struct rcslockers);
- newlocker->lockerlink = lockerlist;
- newlocker->login = argv;
- lockerlist = newlocker;
- while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';')
- continue;
- *argv = '\0';
- if ( c == '\0' ) return;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- }
-}
-
-
-
- static void
-getauthor(argv)
-char *argv;
-/* function: get the author's name from command line */
-/* and store in authorlist */
-
-{
- register c;
- struct authors * newauthor;
-
- argv--;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- if ( c == '\0' ) {
- authorlist = talloc(struct authors);
- authorlist->login = getusername(false);
- authorlist->nextauthor = 0;
- return;
- }
-
- while( c != '\0' ) {
- newauthor = talloc(struct authors);
- newauthor->nextauthor = authorlist;
- newauthor->login = argv;
- authorlist = newauthor;
- while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';')
- continue;
- * argv = '\0';
- if ( c == '\0') return;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- }
-}
-
-
-
-
- static void
-getstate(argv)
-char * argv;
-/* function : get the states of revisions from command line */
-/* and store in statelist */
-
-{
- register char c;
- struct stateattri *newstate;
-
- argv--;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- if ( c == '\0'){
- error("missing state attributes after -s options");
- return;
- }
-
- while( c != '\0' ) {
- newstate = talloc(struct stateattri);
- newstate->nextstate = statelist;
- newstate->status = argv;
- statelist = newstate;
- while ((c = *++argv) && c!=',' && c!=' ' && c!='\t' && c!='\n' && c!=';')
- continue;
- *argv = '\0';
- if ( c == '\0' ) return;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- }
-}
-
-
-
- static void
-trunclocks()
-/* Function: Truncate the list of locks to those that are held by the */
-/* id's on lockerlist. Do not truncate if lockerlist empty. */
-
-{
- struct rcslockers const *plocker;
- struct rcslock *p, **pp;
-
- if (!lockerlist) return;
-
- /* shorten Locks to those contained in lockerlist */
- for (pp = &Locks; (p = *pp); )
- for (plocker = lockerlist; ; )
- if (strcmp(plocker->login, p->login) == 0) {
- pp = &p->nextlock;
- break;
- } else if (!(plocker = plocker->lockerlink)) {
- *pp = p->nextlock;
- break;
- }
-}
-
-
-
- static void
-recentdate(root, pd)
- struct hshentry const *root;
- struct Datepairs *pd;
-/* function: Finds the delta that is closest to the cutoff date given by */
-/* pd among the revisions selected by exttree. */
-/* Successively narrows down the interval given by pd, */
-/* and sets the strtdate of pd to the date of the selected delta */
-{
- struct branchhead const *newbranch;
-
- if (!root) return;
- if (root->selector) {
- if ( cmpdate(root->date, pd->strtdate) >= 0 &&
- cmpdate(root->date, pd->enddate) <= 0)
- VOID strcpy(pd->strtdate, root->date);
- }
-
- recentdate(root->next, pd);
- newbranch = root->branches;
- while( newbranch) {
- recentdate(newbranch->hsh, pd);
- newbranch = newbranch->nextbranch;
- }
-}
-
-
-
-
-
-
- static int
-extdate(root)
-struct hshentry * root;
-/* function: select revisions which are in the date range specified */
-/* in duelst and datelist, start at root */
-/* Yield number of revisions selected, including those already selected. */
-{
- struct branchhead const *newbranch;
- struct Datepairs const *pdate;
- int revno, ne;
-
- if (!root)
- return 0;
-
- if ( datelist || duelst) {
- pdate = datelist;
- while( pdate ) {
- ne = pdate->ne_date;
- if (
- (!pdate->strtdate[0]
- || ne <= cmpdate(root->date, pdate->strtdate))
- &&
- (!pdate->enddate[0]
- || ne <= cmpdate(pdate->enddate, root->date))
- )
- break;
- pdate = pdate->dnext;
- }
- if (!pdate) {
- pdate = duelst;
- for (;;) {
- if (!pdate) {
- root->selector = false;
- break;
- }
- if (cmpdate(root->date, pdate->strtdate) == 0)
- break;
- pdate = pdate->dnext;
- }
- }
- }
- revno = root->selector + extdate(root->next);
-
- newbranch = root->branches;
- while( newbranch ) {
- revno += extdate(newbranch->hsh);
- newbranch = newbranch->nextbranch;
- }
- return revno;
-}
-
-
-
- static char
-extractdelta(pdelta)
- struct hshentry const *pdelta;
-/* function: compare information of pdelta to the authorlist, lockerlist,*/
-/* statelist, revlist and yield true if pdelta is selected. */
-
-{
- struct rcslock const *plock;
- struct stateattri const *pstate;
- struct authors const *pauthor;
- struct Revpairs const *prevision;
- int length;
-
- if ((pauthor = authorlist)) /* only certain authors wanted */
- while (strcmp(pauthor->login, pdelta->author) != 0)
- if (!(pauthor = pauthor->nextauthor))
- return false;
- if ((pstate = statelist)) /* only certain states wanted */
- while (strcmp(pstate->status, pdelta->state) != 0)
- if (!(pstate = pstate->nextstate))
- return false;
- if (lockflag) /* only locked revisions wanted */
- for (plock = Locks; ; plock = plock->nextlock)
- if (!plock)
- return false;
- else if (plock->delta == pdelta)
- break;
- if ((prevision = Revlst)) /* only certain revs or branches wanted */
- for (;;) {
- length = prevision->numfld;
- if (
- countnumflds(pdelta->num) == length+(length&1) &&
- 0 <= compartial(pdelta->num, prevision->strtrev, length) &&
- 0 <= compartial(prevision->endrev, pdelta->num, length)
- )
- break;
- if (!(prevision = prevision->rnext))
- return false;
- }
- return true;
-}
-
-
-
- static void
-getdatepair(argv)
- char * argv;
-/* function: get time range from command line and store in datelist if */
-/* a time range specified or in duelst if a time spot specified */
-
-{
- register char c;
- struct Datepairs * nextdate;
- char const * rawdate;
- int switchflag;
-
- argv--;
- while ((c = *++argv)==',' || c==' ' || c=='\t' || c=='\n' || c==';')
- continue;
- if ( c == '\0' ) {
- error("missing date/time after -d");
- return;
- }
-
- while( c != '\0' ) {
- switchflag = false;
- nextdate = talloc(struct Datepairs);
- if ( c == '<' ) { /* case: -d <date */
- c = *++argv;
- if (!(nextdate->ne_date = c!='='))
- c = *++argv;
- (nextdate->strtdate)[0] = '\0';
- } else if (c == '>') { /* case: -d'>date' */
- c = *++argv;
- if (!(nextdate->ne_date = c!='='))
- c = *++argv;
- (nextdate->enddate)[0] = '\0';
- switchflag = true;
- } else {
- rawdate = argv;
- while( c != '<' && c != '>' && c != ';' && c != '\0')
- c = *++argv;
- *argv = '\0';
- if ( c == '>' ) switchflag=true;
- str2date(rawdate,
- switchflag ? nextdate->enddate : nextdate->strtdate);
- if ( c == ';' || c == '\0') { /* case: -d date */
- VOID strcpy(nextdate->enddate,nextdate->strtdate);
- nextdate->dnext = duelst;
- duelst = nextdate;
- goto end;
- } else {
- /* case: -d date< or -d date>; see switchflag */
- int eq = argv[1]=='=';
- nextdate->ne_date = !eq;
- argv += eq;
- while ((c = *++argv) == ' ' || c=='\t' || c=='\n')
- continue;
- if ( c == ';' || c == '\0') {
- /* second date missing */
- if (switchflag)
- *nextdate->strtdate= '\0';
- else
- *nextdate->enddate= '\0';
- nextdate->dnext = datelist;
- datelist = nextdate;
- goto end;
- }
- }
- }
- rawdate = argv;
- while( c != '>' && c != '<' && c != ';' && c != '\0')
- c = *++argv;
- *argv = '\0';
- str2date(rawdate,
- switchflag ? nextdate->strtdate : nextdate->enddate);
- nextdate->dnext = datelist;
- datelist = nextdate;
- end:
- if (RCSversion < VERSION(5))
- nextdate->ne_date = 0;
- if ( c == '\0') return;
- while ((c = *++argv) == ';' || c == ' ' || c == '\t' || c =='\n')
- continue;
- }
-}
-
-
-
- static int
-getnumericrev()
-/* function: get the numeric name of revisions which stored in revlist */
-/* and then stored the numeric names in Revlst */
-/* if branchflag, also add default branch */
-
-{
- struct Revpairs * ptr, *pt;
- int n;
- struct buf s, e;
- char const *lrev;
- struct buf const *rstart, *rend;
-
- Revlst = 0;
- ptr = revlist;
- bufautobegin(&s);
- bufautobegin(&e);
- while( ptr ) {
- n = 0;
- rstart = &s;
- rend = &e;
-
- switch (ptr->numfld) {
-
- case 1: /* -rREV */
- if (!expandsym(ptr->strtrev, &s))
- goto freebufs;
- rend = &s;
- n = countnumflds(s.string);
- if (!n && (lrev = tiprev())) {
- bufscpy(&s, lrev);
- n = countnumflds(lrev);
- }
- break;
-
- case 2: /* -rREV: */
- if (!expandsym(ptr->strtrev, &s))
- goto freebufs;
- bufscpy(&e, s.string);
- n = countnumflds(s.string);
- (n<2 ? e.string : strrchr(e.string,'.'))[0] = 0;
- break;
-
- case 3: /* -r:REV */
- if (!expandsym(ptr->endrev, &e))
- goto freebufs;
- if ((n = countnumflds(e.string)) < 2)
- bufscpy(&s, ".0");
- else {
- bufscpy(&s, e.string);
- VOID strcpy(strrchr(s.string,'.'), ".0");
- }
- break;
-
- default: /* -rREV1:REV2 */
- if (!(
- expandsym(ptr->strtrev, &s)
- && expandsym(ptr->endrev, &e)
- && checkrevpair(s.string, e.string)
- ))
- goto freebufs;
- n = countnumflds(s.string);
- /* Swap if out of order. */
- if (compartial(s.string,e.string,n) > 0) {
- rstart = &e;
- rend = &s;
- }
- break;
- }
-
- if (n) {
- pt = ftalloc(struct Revpairs);
- pt->numfld = n;
- pt->strtrev = fstr_save(rstart->string);
- pt->endrev = fstr_save(rend->string);
- pt->rnext = Revlst;
- Revlst = pt;
- }
- ptr = ptr->rnext;
- }
- /* Now take care of branchflag */
- if (branchflag && (Dbranch||Head)) {
- pt = ftalloc(struct Revpairs);
- pt->strtrev = pt->endrev =
- Dbranch ? Dbranch : fstr_save(partialno(&s,Head->num,1));
- pt->rnext=Revlst; Revlst=pt;
- pt->numfld = countnumflds(pt->strtrev);
- }
-
- freebufs:
- bufautoend(&s);
- bufautoend(&e);
- return !ptr;
-}
-
-
-
- static int
-checkrevpair(num1,num2)
- char const *num1, *num2;
-/* function: check whether num1, num2 are legal pair,i.e.
- only the last field are different and have same number of
- fields( if length <= 2, may be different if first field) */
-
-{
- int length = countnumflds(num1);
-
- if (
- countnumflds(num2) != length
- || (2 < length && compartial(num1, num2, length-1) != 0)
- ) {
- rcserror("invalid branch or revision pair %s : %s", num1, num2);
- return false;
- }
-
- return true;
-}
-
-
-
- static void
-getrevpairs(argv)
-register char * argv;
-/* function: get revision or branch range from command line, and */
-/* store in revlist */
-
-{
- register char c;
- struct Revpairs * nextrevpair;
- int separator;
-
- c = *argv;
-
- /* Support old ambiguous '-' syntax; this will go away. */
- if (strchr(argv,':'))
- separator = ':';
- else {
- if (strchr(argv,'-') && VERSION(5) <= RCSversion)
- warn("`-' is obsolete in `-r%s'; use `:' instead", argv);
- separator = '-';
- }
-
- for (;;) {
- while (c==' ' || c=='\t' || c=='\n')
- c = *++argv;
- nextrevpair = talloc(struct Revpairs);
- nextrevpair->rnext = revlist;
- revlist = nextrevpair;
- nextrevpair->numfld = 1;
- nextrevpair->strtrev = argv;
- for (;; c = *++argv) {
- switch (c) {
- default:
- continue;
- case '\0': case ' ': case '\t': case '\n':
- case ',': case ';':
- break;
- case ':': case '-':
- if (c == separator)
- break;
- continue;
- }
- break;
- }
- *argv = '\0';
- while (c==' ' || c=='\t' || c=='\n')
- c = *++argv;
- if (c == separator) {
- while ((c = *++argv) == ' ' || c == '\t' || c =='\n')
- continue;
- nextrevpair->endrev = argv;
- for (;; c = *++argv) {
- switch (c) {
- default:
- continue;
- case '\0': case ' ': case '\t': case '\n':
- case ',': case ';':
- break;
- case ':': case '-':
- if (c == separator)
- break;
- continue;
- }
- break;
- }
- *argv = '\0';
- while (c==' ' || c=='\t' || c =='\n')
- c = *++argv;
- nextrevpair->numfld =
- !nextrevpair->endrev[0] ? 2 /* -rREV: */ :
- !nextrevpair->strtrev[0] ? 3 /* -r:REV */ :
- 4 /* -rREV1:REV2 */;
- }
- if (!c)
- break;
- else if (c==',' || c==';')
- c = *++argv;
- else
- error("missing `,' near `%c%s'", c, argv+1);
- }
-}
OpenPOWER on IntegriCloud