111891Speter#! /bin/sh
29Sjkh
39Sjkh# Test RCS's functions.
49Sjkh# The RCS commands are searched for in the PATH as usual;
59Sjkh# to test the working directory's commands, prepend . to your PATH.
69Sjkh
79Sjkh# Test RCS by creating files RCS/a.* and RCS/a.c.
89Sjkh# If all goes well, output nothing, and remove the temporary files.
99Sjkh# Otherwise, send a message to standard output.
109Sjkh# Exit status is 0 if OK, 1 if an RCS bug is found, and 2 if scaffolding fails.
119Sjkh# With the -v option, output more debugging info.
129Sjkh
139Sjkh# If diff outputs `No differences encountered' when comparing identical files,
149Sjkh# then rcstest may also output these noise lines; ignore them.
159Sjkh
169Sjkh# The current directory and ./RCS must be readable, writable, and searchable.
179Sjkh
1850472Speter# $FreeBSD: releng/10.2/gnu/usr.bin/rcs/rcstest 50472 1999-08-27 23:37:10Z peter $
199Sjkh
209Sjkh
2111891Speter#    Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
229Sjkh#    Distributed under license by the Free Software Foundation, Inc.
239Sjkh#
249Sjkh# This file is part of RCS.
259Sjkh#
269Sjkh# RCS is free software; you can redistribute it and/or modify
279Sjkh# it under the terms of the GNU General Public License as published by
289Sjkh# the Free Software Foundation; either version 2, or (at your option)
299Sjkh# any later version.
309Sjkh#
319Sjkh# RCS is distributed in the hope that it will be useful,
329Sjkh# but WITHOUT ANY WARRANTY; without even the implied warranty of
339Sjkh# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
349Sjkh# GNU General Public License for more details.
359Sjkh#
369Sjkh# You should have received a copy of the GNU General Public License
3711891Speter# along with RCS; see the file COPYING.
3811891Speter# If not, write to the Free Software Foundation,
3911891Speter# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
409Sjkh#
419Sjkh# Report problems and direct all questions to:
429Sjkh#
439Sjkh#     rcs-bugs@cs.purdue.edu
449Sjkh
4511891Speter# The Makefile overrides the following defaults.
4611891Speter: ${ALL_CFLAGS=-Dhas_conf_h}
4711891Speter: ${CC=cc}
4811891Speter: ${DIFF=diff}
4911891Speter# : ${LDFLAGS=} ${LIBS=} tickles old shell bug
5011891Speter
5111891SpeterCL="$CC $ALL_CFLAGS $LDFLAGS -o a.out"
5211891SpeterL=$LIBS
5311891Speter
549SjkhRCSINIT=-x
559Sjkhexport RCSINIT
569Sjkh
579SjkhSLASH=/
589SjkhRCSfile=RCS${SLASH}a.c
599SjkhRCS_alt=RCS${SLASH}a.d
609Sjkhlockfile=RCS${SLASH}a._
619Sjkh
629Sjkhcase $1 in
639Sjkh-v) q=; set -x;;
649Sjkh'') q=-q;;
659Sjkh*) echo >&2 "$0: usage: $0 [-v]"; exit 2
669Sjkhesac
679Sjkh
6811891Speterif test -d RCS
6911891Speterthen rmdir=:
7011891Speterelse rmdir=rmdir; mkdir RCS || exit
7111891Speterfi
729Sjkh
739Sjkhrm -f a.* $RCSfile $RCS_alt $lockfile &&
749Sjkhecho 1.1 >a.11 &&
759Sjkhecho 1.1.1.1 >a.3x1 &&
769Sjkhecho 1.2 >a.12 || { echo "#initialization failed"; exit 2; }
779Sjkh
7811891Spetercase "`$DIFF -c a.11 a.3x1`" in
7911891Speter*!\ 1.1.1.1)
8011891Speter	diff="$DIFF -c";;
819Sjkh*)
8211891Speter	echo "#warning: $DIFF -c does not work, so diagnostics may be cryptic"
8311891Speter	diff=$DIFF
849Sjkhesac
859Sjkh
869Sjkhrcs -i -L -ta.11 $q a.c &&
8711891Spetertest -r $RCSfile || {
889Sjkh	echo "#rcs -i -L failed; perhaps RCS is not properly installed."
899Sjkh	exit 1
909Sjkh}
919Sjkh
929Sjkhrlog a.c >/dev/null || { echo "#rlog failed on empty RCS file"; exit 1; }
939Sjkhrm -f $RCSfile || exit 2
949Sjkh
959Sjkhcp a.11 a.c &&
969Sjkhci -ta.11 -mm $q a.c &&
9711891Spetertest -r $RCSfile &&
989Sjkhrcs -L $q a.c || { echo "#ci+rcs -L failed"; exit 1; }
999Sjkhtest ! -f a.c || { echo "#ci did not remove working file"; exit 1; }
1009Sjkhfor l in '' '-l'
1019Sjkhdo
1029Sjkh	co $l $q a.c &&
1039Sjkh	test -f a.c || { echo '#co' $l did not create working file; exit 1; }
1049Sjkh	$diff a.11 a.c || { echo '#ci' followed by co $l is not a no-op; exit 1; }
1059Sjkhdone
1069Sjkh
1079Sjkhcp a.12 a.c &&
1089Sjkhci -mm $q a.c &&
1099Sjkhco $q a.c &&
1109Sjkh$diff a.12 a.c || { echo "#ci+co failed"; exit 1; }
1119Sjkh
11211891Speterrm -f a.c &&
1139Sjkhco -r1.1 $q a.c &&
1149Sjkh$diff a.11 a.c || { echo "#can't retrieve first revision"; exit 1; }
1159Sjkh
1169Sjkhrm -f a.c &&
1179Sjkhcp a.3x1 a.c &&
1189Sjkhci -r1.1.1 -mm $q a.c &&
1199Sjkhco -r1.1.1.1 $q a.c &&
1209Sjkh$diff a.3x1 a.c || { echo "#branches failed"; exit 1; }
1219Sjkh
12211891Speterrm -f a.c &&
1239Sjkhco -l $q a.c &&
1249Sjkhci -f -mm $q a.c &&
1259Sjkhco -r1.3 $q a.c &&
1269Sjkh$diff a.12 a.c || { echo "#(co -l; ci -f) failed"; exit 1; }
1279Sjkh
12811891Speterrm -f a.c &&
1299Sjkhco -l $q a.c &&
1309Sjkhecho 1.4 >a.c &&
1319Sjkhci -l -mm $q a.c &&
1329Sjkhecho error >a.c &&
1339Sjkhci -mm $q a.c || { echo "#ci -l failed"; exit 1; }
1349Sjkh
13511891Speterrm -f a.c &&
1369Sjkhco -l $q a.c &&
1379Sjkhecho 1.5 >a.c &&
1389Sjkhci -u -mm $q a.c &&
13911891Spetertest -r a.c || { echo "#ci -u didn't create a working file"; exit 1; }
1409Sjkhrm -f a.c &&
1419Sjkhecho error >a.c || exit 2
1429Sjkhci -mm $q a.c 2>/dev/null && { echo "#ci -u didn't unlock the file"; exit 1; }
1439Sjkh
1449Sjkhrm -f a.c &&
1459Sjkhrcs -l $q a.c &&
1469Sjkhco -u $q a.c || { echo "#rcs -l + co -u failed"; exit 1; }
1479Sjkhrm -f a.c &&
1489Sjkhecho error >a.c || exit 2
1499Sjkhci -mm $q a.c 2>/dev/null && { echo "#co -u didn't unlock the file"; exit 1; }
1509Sjkh
1519Sjkhrm -f a.c &&
1529Sjkhcp a.11 a.c &&
1539Sjkhco -f $q a.c || { echo "#co -f failed"; exit 1; }
1549Sjkh$diff a.11 a.c >/dev/null && { echo "#co -f had no effect"; exit 1; }
1559Sjkh
1569Sjkhco -p1.1 $q a.c >a.t &&
1579Sjkh$diff a.11 a.t || { echo "#co -p failed"; exit 1; }
1589Sjkh
1599Sjkhfor n in n N
1609Sjkhdo
1619Sjkh	rm -f a.c &&
1629Sjkh	co -l $q a.c &&
1639Sjkh	echo $n >a.$n &&
1649Sjkh	cp a.$n a.c &&
1659Sjkh	ci -${n}n -mm $q a.c &&
1669Sjkh	co -rn $q a.c &&
1679Sjkh	$diff a.$n a.c || { echo "#ci -$n failed"; exit 1; }
1689Sjkhdone
1699Sjkh
1709Sjkhcase $LOGNAME in
1719Sjkh?*) me=$LOGNAME;;
1729Sjkh*)
1739Sjkh	case $USER in
1749Sjkh	?*) me=$USER;;
1759Sjkh	*)
1769Sjkh		me=`who am i` || exit 2
1779Sjkh		me=`echo "$me" | sed -e 's/ .*//' -e 's/.*!//'`
1789Sjkh		case $me in
1799Sjkh		'') echo >&2 "$0: cannot deduce user name"; exit 2
1809Sjkh		esac
1819Sjkh	esac
1829Sjkhesac
18311891Speter
18411891Speter
18511891Speter# Get the date of the previous revision in UTC.
18611891Speterdate=`rlog -r a.c | sed -n '/^date: /{ s///; s/;.*//; p; q; }'` || exit
18711891Spetercase $date in
18811891Speter[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]);;
18911891Speter*) echo >&2 "$0: $date: bad rlog date output"; exit 1
1909Sjkhesac
19111891SpeterPWD=`pwd` && export PWD &&
19211891Speterrm -f a.c &&
1939Sjkhco -l $q a.c &&
1949Sjkhsed 's/@/$/g' >a.kv <<EOF
1959Sjkh@Author: w @
19611891Speter@Date: $date @
19711891Speter@Header: $PWD$SLASH$RCSfile 2.1 $date w s @
19811891Speter@Id: a.c 2.1 $date w s @
1999Sjkh@Locker:  @
20011891Speter * @Log: a.c @
20111891Speter * Revision 2.1  $date  w
2029Sjkh * m
2039Sjkh *
20411891Speter@Name: Oz @
2059Sjkh@RCSfile: a.c @
2069Sjkh@Revision: 2.1 @
2079Sjkh@Source: $PWD$SLASH$RCSfile @
2089Sjkh@State: s @
2099SjkhEOF
2109Sjkhtest $? = 0 &&
2119Sjkhsed 's/:.*\$/$/' a.kv >a.k &&
2129Sjkhsed -e 's/w s [$]/w s '"$me"' $/' -e 's/[$]Locker: /&'"$me/" a.kv >a.kvl &&
21311891Spetersed s/Oz//g a.kv >a.e &&
21411891Spetersed s/Oz/N/g a.kv >a.N &&
21511891Spetersed -e '/\$/!d' -e 's/\$$/: old $/' a.k >a.o &&
2169Sjkhsed -e 's/\$[^ ]*: //' -e 's/ \$//' a.kv >a.v &&
2179Sjkhcp a.o a.c &&
21811891Speterci -d"$date" -nOz -ss -ww -u2.1 -mm $q a.c &&
2199Sjkh$diff a.kv a.c || { echo "#keyword expansion failed"; exit 1; }
22011891Speterco -pOz -ko $q a.c >a.oo &&
2219Sjkh$diff a.o a.oo || { echo "#co -p -ko failed"; exit 1; }
22211891Spetercp a.kv a.o && cp a.o a.b || exit 2
22311891Speterrcs -oOz $q a.c &&
2249Sjkhrcs -l $q a.c &&
2259Sjkhci -k -u $q a.c &&
2269Sjkh$diff a.kv a.c || { echo "#ci -k failed"; exit 1; }
22711891Spetersed -n 's/^[^$]*\$/$/p' a.kv >a.i &&
2289Sjkhident a.c >a.i1 &&
2299Sjkhsed -e 1d -e 's/^[	 ]*//' a.i1 >a.i2 &&
2309Sjkh$diff a.i a.i2 || { echo "#ident failed"; exit 1; }
2319Sjkh
2329Sjkhrcs -i $q a.c 2>/dev/null && { echo "#rcs -i permitted existing file"; exit 1; }
2339Sjkh
23411891Speterrm -f a.c &&
2359Sjkhco -l $q a.c &&
2369Sjkhecho 2.2 >a.c &&
2379Sjkhci -mm $q a.c &&
2389Sjkhecho 1.1.1.2 >a.c &&
2399Sjkhrcs -l1.1.1 $q a.c &&
2409Sjkhci -r1.1.1.2 -mm $q a.c &&
2419Sjkhrcs -b1.1.1 $q a.c &&
2429Sjkhtest " `co -p $q a.c`" = ' 1.1.1.2' || { echo "#rcs -b1.1.1 failed"; exit 1; }
2439Sjkhrcs -b $q a.c &&
2449Sjkhtest " `co -p $q a.c`" = ' 2.2' || { echo "#rcs -b failed"; exit 1; }
2459Sjkh
2469Sjkhecho 2.3 >a.c || exit 2
2479Sjkhrcs -U $q a.c || { echo "#rcs -U failed"; exit 1; }
2489Sjkhci -mm $q a.c || { echo "#rcs -U didn't unset strict locking"; exit 1; }
2499Sjkhrcs -L $q a.c || { echo "#rcs -L failed"; exit 1; }
2509Sjkhecho error >a.c || exit 2
2519Sjkhci -mm $q a.c 2>/dev/null && { echo "#ci retest failed"; exit 1; }
2529Sjkh
2539Sjkhrm -f a.c &&
2549Sjkhlog0=`rlog -h a.c` &&
2559Sjkhco -l $q a.c &&
2569Sjkhci -mm $q a.c &&
2579Sjkhlog1=`rlog -h a.c` &&
2589Sjkhtest " $log0" = " $log1" || { echo "#unchanged ci didn't revert"; exit 1; }
2599Sjkh
2609Sjkhrm -f a.c &&
2619Sjkhrcs -nN:1.1 $q a.c &&
2629Sjkhco -rN $q a.c &&
2639Sjkh$diff a.11 a.c || { echo "#rcs -n failed"; exit 1; }
2649Sjkh
26511891Speterrm -f a.c &&
2669Sjkhrcs -NN:2.1 $q a.c &&
2679Sjkhco -rN $q a.c &&
26811891Speter$diff a.N a.c || { echo "#rcs -N failed"; exit 1; }
2699Sjkh
27011891Speterrm -f a.c &&
2719Sjkhco -l $q a.c &&
27211891Speterecho ':::$''Log$' >a.c &&
2739Sjkhci -u -mm $q a.c &&
27411891Spetertest " `sed '$!d' a.c`" = ' :::' || { echo "#comment leader failed"; exit 1; }
2759Sjkh
27611891Speterrm -f a.c &&
2779Sjkhrcs -o2.2: $q a.c &&
2789Sjkhco $q a.c &&
27911891Speter$diff a.e a.c || { echo "#rcs -o failed"; exit 1; }
2809Sjkh
28111891Speterrcsdiff -r1.1 -rOz $q a.c >a.0
2829Sjkhcase $? in
2839Sjkh1) ;;
2849Sjkh*) echo "#rcsdiff bad status"; exit 1
2859Sjkhesac
28611891Speter$DIFF a.11 a.kv >a.1
2879Sjkh$diff a.0 a.1 || { echo "#rcsdiff failed"; exit 1; }
2889Sjkh
2899Sjkhrcs -l2.1 $q a.c || { echo "#rcs -l2.1 failed"; exit 1; }
29011891Speterfor i in b k kv kvl o v
2919Sjkhdo
2929Sjkh	rm -f a.c &&
2939Sjkh	cp a.$i a.c &&
29411891Speter	rcsdiff -k$i -rOz $q a.c || { echo "#rcsdiff -k$i failed"; exit 1; }
2959Sjkhdone
2969Sjkhco -p1.1 -ko $q a.c >a.t &&
2979Sjkh$diff a.11 a.t || { echo "#co -p1.1 -ko failed"; exit 1; }
2989Sjkhrcs -u2.1 $q a.c || { echo "#rcs -u2.1 failed"; exit 1; }
2999Sjkh
3009Sjkhrm -f a.c &&
30111891Speterrcsclean $q a.c &&
30211891Speterrcsclean -u $q a.c || { echo "#rcsclean botched a nonexistent file"; exit 1; }
30311891Speter
30411891Speterrm -f a.c &&
30511891Speterco $q a.c &&
30611891Speterrcsclean -n $q a.c &&
30711891Speterrcsclean -n -u $q a.c &&
30811891Spetertest -f a.c || { echo "#rcsclean -n removed a file"; exit 1; }
30911891Speter
31011891Speterrm -f a.c &&
31111891Speterco $q a.c &&
31211891Speterrcsclean $q a.c &&
31311891Spetertest ! -f a.c || { echo "#rcsclean missed an unlocked file"; exit 1; }
31411891Speter
31511891Speterrm -f a.c &&
3169Sjkhco -l $q a.c &&
31711891Speterrcsclean $q a.c &&
31811891Spetertest -f a.c || { echo "#rcsclean removed a locked file"; exit 1; }
31911891Speterrcsclean -u $q a.c &&
32011891Spetertest ! -f a.c || {
32111891Speter	echo "#rcsclean -u missed an unchanged locked file"; exit 1;
32211891Speter}
32311891Speter
32411891Speterrm -f a.c &&
32511891Speterco -l $q a.c &&
32611891Speterecho change >>a.c &&
32711891Speterrcsclean $q a.c &&
32811891Speterrcsclean $q -u a.c &&
32911891Spetertest -f a.c || { echo "#rcsclean removed a changed file"; exit 1; }
33011891Speter
33111891Speterrm -f a.c &&
33211891Speterco -l $q a.c &&
3339Sjkhcat >a.c <<'EOF'
3349Sjkh2.2
3359Sjkha
3369Sjkhb
3379Sjkhc
3389Sjkhd
3399SjkhEOF
3409Sjkhtest $? = 0 &&
3419Sjkhci -l -mm $q a.c &&
3429Sjkhco -p2.2 $q a.c | sed -e s/2.2/2.3/ -e s/b/b1/ >a.c &&
3439Sjkhci -l -mm $q a.c &&
3449Sjkhco -p2.2 $q a.c | sed -e s/2.2/new/ -e s/d/d1/ >a.c || exit 2
3459Sjkhcat >a.0 <<'EOF'
3469Sjkh2.3
3479Sjkha
3489Sjkhb1
3499Sjkhc
3509Sjkhd1
3519SjkhEOF
3529Sjkhcat >a.1 <<'EOF'
3539Sjkh<<<<<<< a.c
3549Sjkhnew
3559Sjkh=======
3569Sjkh2.3
3579Sjkh>>>>>>> 2.3
3589Sjkha
3599Sjkhb1
3609Sjkhc
3619Sjkhd1
3629SjkhEOF
36311891Speterrcsmerge -E -r2.2 -r2.3 $q a.c
3649Sjkhcase $? in
3659Sjkh0)
3669Sjkh	if $diff a.0 a.c >/dev/null
3679Sjkh	then echo "#warning: diff3 -E does not work, " \
3689Sjkh		"so merge and rcsmerge ignore overlaps and suppress overlap lines."
3699Sjkh	else
3709Sjkh		$diff a.1 a.c || { echo "#rcsmerge failed (status 0)"; exit 1; }
3719Sjkh		echo "#warning: The diff3 lib program exit status ignores overlaps," \
3729Sjkh			"so rcsmerge does not warn about overlap lines that it generates."
3739Sjkh	fi
3749Sjkh	;;
3759Sjkh1)
3769Sjkh	$diff a.1 a.c || { echo "#rcsmerge failed (status 1)"; exit 1; }
3779Sjkh	;;
3789Sjkh*)
3799Sjkh	echo "#rcsmerge bad status"; exit 1
3809Sjkhesac
3819Sjkh
38211891Speter# Avoid `tr' if possible; it's not portable, and it can't handle null bytes.
38311891Speter# Our substitute exclusive-ORs with '\n';
38411891Speter# this ensures null bytes on output, which is even better than `tr',
38511891Speter# since some diffs think a file is binary only if it contains null bytes.
38611891Spetercat >a.c <<'EOF'
38711891Speter#include <stdio.h>
38811891Speterint main() {
38911891Speter	int c;
39011891Speter	while ((c=getchar()) != EOF)
39111891Speter		putchar(c ^ '\n');
39211891Speter	return 0;
39311891Speter}
39411891SpeterEOF
39511891Spetertr=tr
39611891Speterif (rm -f a.exe a.out && $CL a.c $L >&2) >/dev/null 2>&1
39711891Speterthen
39811891Speter	if test -s a.out
39911891Speter	then tr=./a.out
40011891Speter	elif test -s a.exe
40111891Speter	then tr=./a.exe
40211891Speter	fi
40311891Speterfi
4049Sjkh{
40511891Speter	co -p $q a.c | $tr '\012' '\200' >a.24 &&
4069Sjkh	cp a.24 a.c &&
4079Sjkh	ciOut=`(ci -l -mm $q a.c 2>&1)` &&
4089Sjkh	case $ciOut in
4099Sjkh	?*) echo >&2 "$ciOut"
4109Sjkh	esac &&
41111891Speter	co -p $q a.c | $tr '\200' '\012' >a.c &&
4129Sjkh	rcsdiff -r2.3 $q a.c >/dev/null &&
4139Sjkh
4149Sjkh	echo 2.5 >a.c &&
4159Sjkh	ci -l -mm $q a.c &&
4169Sjkh	cp a.24 a.c &&
4179Sjkh	rcsdiff -r2.4 $q a.c >/dev/null
4189Sjkh} || echo "#warning: Traditional diff is used, so RCS is limited to text files."
4199Sjkh
4209Sjkhrcs -u -o2.4: $q a.c || { echo "#rcs -u -o failed"; exit 1; }
4219Sjkh
4229Sjkhrcs -i -Aa.c -t- $q a.d || { echo "#rcs -i -A failed"; exit 1; }
4239Sjkh
4249Sjkhrlog -r2.1 a.c >a.t &&
4259Sjkhgrep '^checked in with -k' a.t >/dev/null &&
4269Sjkhsed '/^checked in with -k/d' a.t >a.u &&
4279Sjkh$diff - a.u <<EOF
4289Sjkh
4299SjkhRCS file: $RCSfile
4309SjkhWorking file: a.c
4319Sjkhhead: 2.3
4329Sjkhbranch:
4339Sjkhlocks: strict
4349Sjkhaccess list:
4359Sjkhsymbolic names:
4369Sjkh	N: 2.1
43711891Speter	Oz: 2.1
4389Sjkh	n: 1.8
4399Sjkhkeyword substitution: kv
4409Sjkhtotal revisions: 13;	selected revisions: 1
4419Sjkhdescription:
4429Sjkh1.1
4439Sjkh----------------------------
4449Sjkhrevision 2.1
44511891Speterdate: $date;  author: w;  state: s;  lines: +14 -1
4469Sjkh=============================================================================
4479SjkhEOF
4489Sjkhtest $? = 0 || { echo "#rlog failed"; exit 1; }
4499Sjkh
4509Sjkh
4519Sjkhtest ! -f $lockfile || { echo "#lock file not removed"; exit 1; }
4529Sjkh
45311891Speterrm -f a.* $RCSfile $RCS_alt
45411891Speter$rmdir RCS
455