1#! /bin/sh
2
3# Test RCS's functions.
4# The RCS commands are searched for in the PATH as usual;
5# to test the working directory's commands, prepend . to your PATH.
6
7# Test RCS by creating files RCS/a.* and RCS/a.c.
8# If all goes well, output nothing, and remove the temporary files.
9# Otherwise, send a message to standard output.
10# Exit status is 0 if OK, 1 if an RCS bug is found, and 2 if scaffolding fails.
11# With the -v option, output more debugging info.
12
13# If diff outputs `No differences encountered' when comparing identical files,
14# then rcstest may also output these noise lines; ignore them.
15
16# The current directory and ./RCS must be readable, writable, and searchable.
17
18#	$Id: rcstest 3476 2003-06-11 15:56:10Z darkwyrm $
19
20
21#    Copyright 1990, 1991, 1992, 1993, 1994, 1995 Paul Eggert
22#    Distributed under license by the Free Software Foundation, Inc.
23#
24# This file is part of RCS.
25#
26# RCS is free software; you can redistribute it and/or modify
27# it under the terms of the GNU General Public License as published by
28# the Free Software Foundation; either version 2, or (at your option)
29# any later version.
30#
31# RCS is distributed in the hope that it will be useful,
32# but WITHOUT ANY WARRANTY; without even the implied warranty of
33# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
34# GNU General Public License for more details.
35#
36# You should have received a copy of the GNU General Public License
37# along with RCS; see the file COPYING.
38# If not, write to the Free Software Foundation,
39# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
40#
41# Report problems and direct all questions to:
42#
43#     rcs-bugs@cs.purdue.edu
44
45# The Makefile overrides the following defaults.
46: ${ALL_CFLAGS=-Dhas_conf_h}
47: ${CC=cc}
48: ${DIFF=diff}
49# : ${LDFLAGS=} ${LIBS=} tickles old shell bug
50
51CL="$CC $ALL_CFLAGS $LDFLAGS -o a.out"
52L=$LIBS
53
54RCSINIT=-x
55export RCSINIT
56
57SLASH=/
58RCSfile=RCS${SLASH}a.c
59RCS_alt=RCS${SLASH}a.d
60lockfile=RCS${SLASH}a._
61
62case $1 in
63-v) q=; set -x;;
64'') q=-q;;
65*) echo >&2 "$0: usage: $0 [-v]"; exit 2
66esac
67
68if test -d RCS
69then rmdir=:
70else rmdir=rmdir; mkdir RCS || exit
71fi
72
73rm -f a.* $RCSfile $RCS_alt $lockfile &&
74echo 1.1 >a.11 &&
75echo 1.1.1.1 >a.3x1 &&
76echo 1.2 >a.12 || { echo "#initialization failed"; exit 2; }
77
78case "`$DIFF -c a.11 a.3x1`" in
79*!\ 1.1.1.1)
80	diff="$DIFF -c";;
81*)
82	echo "#warning: $DIFF -c does not work, so diagnostics may be cryptic"
83	diff=$DIFF
84esac
85
86rcs -i -L -ta.11 $q a.c &&
87test -r $RCSfile || {
88	echo "#rcs -i -L failed; perhaps RCS is not properly installed."
89	exit 1
90}
91
92rlog a.c >/dev/null || { echo "#rlog failed on empty RCS file"; exit 1; }
93rm -f $RCSfile || exit 2
94
95cp a.11 a.c &&
96ci -ta.11 -mm $q a.c &&
97test -r $RCSfile &&
98rcs -L $q a.c || { echo "#ci+rcs -L failed"; exit 1; }
99test ! -f a.c || { echo "#ci did not remove working file"; exit 1; }
100for l in '' '-l'
101do
102	co $l $q a.c &&
103	test -f a.c || { echo '#co' $l did not create working file; exit 1; }
104	$diff a.11 a.c || { echo '#ci' followed by co $l is not a no-op; exit 1; }
105done
106
107cp a.12 a.c &&
108ci -mm $q a.c &&
109co $q a.c &&
110$diff a.12 a.c || { echo "#ci+co failed"; exit 1; }
111
112rm -f a.c &&
113co -r1.1 $q a.c &&
114$diff a.11 a.c || { echo "#can't retrieve first revision"; exit 1; }
115
116rm -f a.c &&
117cp a.3x1 a.c &&
118ci -r1.1.1 -mm $q a.c &&
119co -r1.1.1.1 $q a.c &&
120$diff a.3x1 a.c || { echo "#branches failed"; exit 1; }
121
122rm -f a.c &&
123co -l $q a.c &&
124ci -f -mm $q a.c &&
125co -r1.3 $q a.c &&
126$diff a.12 a.c || { echo "#(co -l; ci -f) failed"; exit 1; }
127
128rm -f a.c &&
129co -l $q a.c &&
130echo 1.4 >a.c &&
131ci -l -mm $q a.c &&
132echo error >a.c &&
133ci -mm $q a.c || { echo "#ci -l failed"; exit 1; }
134
135rm -f a.c &&
136co -l $q a.c &&
137echo 1.5 >a.c &&
138ci -u -mm $q a.c &&
139test -r a.c || { echo "#ci -u didn't create a working file"; exit 1; }
140rm -f a.c &&
141echo error >a.c || exit 2
142ci -mm $q a.c 2>/dev/null && { echo "#ci -u didn't unlock the file"; exit 1; }
143
144rm -f a.c &&
145rcs -l $q a.c &&
146co -u $q a.c || { echo "#rcs -l + co -u failed"; exit 1; }
147rm -f a.c &&
148echo error >a.c || exit 2
149ci -mm $q a.c 2>/dev/null && { echo "#co -u didn't unlock the file"; exit 1; }
150
151rm -f a.c &&
152cp a.11 a.c &&
153co -f $q a.c || { echo "#co -f failed"; exit 1; }
154$diff a.11 a.c >/dev/null && { echo "#co -f had no effect"; exit 1; }
155
156co -p1.1 $q a.c >a.t &&
157$diff a.11 a.t || { echo "#co -p failed"; exit 1; }
158
159for n in n N
160do
161	rm -f a.c &&
162	co -l $q a.c &&
163	echo $n >a.$n &&
164	cp a.$n a.c &&
165	ci -${n}n -mm $q a.c &&
166	co -rn $q a.c &&
167	$diff a.$n a.c || { echo "#ci -$n failed"; exit 1; }
168done
169
170case $LOGNAME in
171?*) me=$LOGNAME;;
172*)
173	case $USER in
174	?*) me=$USER;;
175	*)
176		me=`who am i` || exit 2
177		me=`echo "$me" | sed -e 's/ .*//' -e 's/.*!//'`
178		case $me in
179		'') echo >&2 "$0: cannot deduce user name"; exit 2
180		esac
181	esac
182esac
183
184
185# Get the date of the previous revision in UTC.
186date=`rlog -r a.c | sed -n '/^date: /{ s///; s/;.*//; p; q; }'` || exit
187case $date in
188[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]);;
189*) echo >&2 "$0: $date: bad rlog date output"; exit 1
190esac
191PWD=`pwd` && export PWD &&
192rm -f a.c &&
193co -l $q a.c &&
194sed 's/@/$/g' >a.kv <<EOF
195@Author: w @
196@Date: $date @
197@Header: $PWD$SLASH$RCSfile 2.1 $date w s @
198@Id: a.c 2.1 $date w s @
199@Locker:  @
200 * @Log: a.c @
201 * Revision 2.1  $date  w
202 * m
203 *
204@Name: Oz @
205@RCSfile: a.c @
206@Revision: 2.1 @
207@Source: $PWD$SLASH$RCSfile @
208@State: s @
209EOF
210test $? = 0 &&
211sed 's/:.*\$/$/' a.kv >a.k &&
212sed -e 's/w s [$]/w s '"$me"' $/' -e 's/[$]Locker: /&'"$me/" a.kv >a.kvl &&
213sed s/Oz//g a.kv >a.e &&
214sed s/Oz/N/g a.kv >a.N &&
215sed -e '/\$/!d' -e 's/\$$/: old $/' a.k >a.o &&
216sed -e 's/\$[^ ]*: //' -e 's/ \$//' a.kv >a.v &&
217cp a.o a.c &&
218ci -d"$date" -nOz -ss -ww -u2.1 -mm $q a.c &&
219$diff a.kv a.c || { echo "#keyword expansion failed"; exit 1; }
220co -pOz -ko $q a.c >a.oo &&
221$diff a.o a.oo || { echo "#co -p -ko failed"; exit 1; }
222cp a.kv a.o && cp a.o a.b || exit 2
223rcs -oOz $q a.c &&
224rcs -l $q a.c &&
225ci -k -u $q a.c &&
226$diff a.kv a.c || { echo "#ci -k failed"; exit 1; }
227sed -n 's/^[^$]*\$/$/p' a.kv >a.i &&
228ident a.c >a.i1 &&
229sed -e 1d -e 's/^[	 ]*//' a.i1 >a.i2 &&
230$diff a.i a.i2 || { echo "#ident failed"; exit 1; }
231
232rcs -i $q a.c 2>/dev/null && { echo "#rcs -i permitted existing file"; exit 1; }
233
234rm -f a.c &&
235co -l $q a.c &&
236echo 2.2 >a.c &&
237ci -mm $q a.c &&
238echo 1.1.1.2 >a.c &&
239rcs -l1.1.1 $q a.c &&
240ci -r1.1.1.2 -mm $q a.c &&
241rcs -b1.1.1 $q a.c &&
242test " `co -p $q a.c`" = ' 1.1.1.2' || { echo "#rcs -b1.1.1 failed"; exit 1; }
243rcs -b $q a.c &&
244test " `co -p $q a.c`" = ' 2.2' || { echo "#rcs -b failed"; exit 1; }
245
246echo 2.3 >a.c || exit 2
247rcs -U $q a.c || { echo "#rcs -U failed"; exit 1; }
248ci -mm $q a.c || { echo "#rcs -U didn't unset strict locking"; exit 1; }
249rcs -L $q a.c || { echo "#rcs -L failed"; exit 1; }
250echo error >a.c || exit 2
251ci -mm $q a.c 2>/dev/null && { echo "#ci retest failed"; exit 1; }
252
253rm -f a.c &&
254log0=`rlog -h a.c` &&
255co -l $q a.c &&
256ci -mm $q a.c &&
257log1=`rlog -h a.c` &&
258test " $log0" = " $log1" || { echo "#unchanged ci didn't revert"; exit 1; }
259
260rm -f a.c &&
261rcs -nN:1.1 $q a.c &&
262co -rN $q a.c &&
263$diff a.11 a.c || { echo "#rcs -n failed"; exit 1; }
264
265rm -f a.c &&
266rcs -NN:2.1 $q a.c &&
267co -rN $q a.c &&
268$diff a.N a.c || { echo "#rcs -N failed"; exit 1; }
269
270rm -f a.c &&
271co -l $q a.c &&
272echo ':::$''Log$' >a.c &&
273ci -u -mm $q a.c &&
274test " `sed '$!d' a.c`" = ' :::' || { echo "#comment leader failed"; exit 1; }
275
276rm -f a.c &&
277rcs -o2.2: $q a.c &&
278co $q a.c &&
279$diff a.e a.c || { echo "#rcs -o failed"; exit 1; }
280
281rcsdiff -r1.1 -rOz $q a.c >a.0
282case $? in
2831) ;;
284*) echo "#rcsdiff bad status"; exit 1
285esac
286$DIFF a.11 a.kv >a.1
287$diff a.0 a.1 || { echo "#rcsdiff failed"; exit 1; }
288
289rcs -l2.1 $q a.c || { echo "#rcs -l2.1 failed"; exit 1; }
290for i in b k kv kvl o v
291do
292	rm -f a.c &&
293	cp a.$i a.c &&
294	rcsdiff -k$i -rOz $q a.c || { echo "#rcsdiff -k$i failed"; exit 1; }
295done
296co -p1.1 -ko $q a.c >a.t &&
297$diff a.11 a.t || { echo "#co -p1.1 -ko failed"; exit 1; }
298rcs -u2.1 $q a.c || { echo "#rcs -u2.1 failed"; exit 1; }
299
300rm -f a.c &&
301rcsclean $q a.c &&
302rcsclean -u $q a.c || { echo "#rcsclean botched a nonexistent file"; exit 1; }
303
304rm -f a.c &&
305co $q a.c &&
306rcsclean -n $q a.c &&
307rcsclean -n -u $q a.c &&
308test -f a.c || { echo "#rcsclean -n removed a file"; exit 1; }
309
310rm -f a.c &&
311co $q a.c &&
312rcsclean $q a.c &&
313test ! -f a.c || { echo "#rcsclean missed an unlocked file"; exit 1; }
314
315rm -f a.c &&
316co -l $q a.c &&
317rcsclean $q a.c &&
318test -f a.c || { echo "#rcsclean removed a locked file"; exit 1; }
319rcsclean -u $q a.c &&
320test ! -f a.c || {
321	echo "#rcsclean -u missed an unchanged locked file"; exit 1;
322}
323
324rm -f a.c &&
325co -l $q a.c &&
326echo change >>a.c &&
327rcsclean $q a.c &&
328rcsclean $q -u a.c &&
329test -f a.c || { echo "#rcsclean removed a changed file"; exit 1; }
330
331rm -f a.c &&
332co -l $q a.c &&
333cat >a.c <<'EOF'
3342.2
335a
336b
337c
338d
339EOF
340test $? = 0 &&
341ci -l -mm $q a.c &&
342co -p2.2 $q a.c | sed -e s/2.2/2.3/ -e s/b/b1/ >a.c &&
343ci -l -mm $q a.c &&
344co -p2.2 $q a.c | sed -e s/2.2/new/ -e s/d/d1/ >a.c || exit 2
345cat >a.0 <<'EOF'
3462.3
347a
348b1
349c
350d1
351EOF
352cat >a.1 <<'EOF'
353<<<<<<< a.c
354new
355=======
3562.3
357>>>>>>> 2.3
358a
359b1
360c
361d1
362EOF
363rcsmerge -E -r2.2 -r2.3 $q a.c
364case $? in
3650)
366	if $diff a.0 a.c >/dev/null
367	then echo "#warning: diff3 -E does not work, " \
368		"so merge and rcsmerge ignore overlaps and suppress overlap lines."
369	else
370		$diff a.1 a.c || { echo "#rcsmerge failed (status 0)"; exit 1; }
371		echo "#warning: The diff3 lib program exit status ignores overlaps," \
372			"so rcsmerge does not warn about overlap lines that it generates."
373	fi
374	;;
3751)
376	$diff a.1 a.c || { echo "#rcsmerge failed (status 1)"; exit 1; }
377	;;
378*)
379	echo "#rcsmerge bad status"; exit 1
380esac
381
382# Avoid `tr' if possible; it's not portable, and it can't handle null bytes.
383# Our substitute exclusive-ORs with '\n';
384# this ensures null bytes on output, which is even better than `tr',
385# since some diffs think a file is binary only if it contains null bytes.
386cat >a.c <<'EOF'
387#include <stdio.h>
388int main() {
389	int c;
390	while ((c=getchar()) != EOF)
391		putchar(c ^ '\n');
392	return 0;
393}
394EOF
395tr=tr
396if (rm -f a.exe a.out && $CL a.c $L >&2) >/dev/null 2>&1
397then
398	if test -s a.out
399	then tr=./a.out
400	elif test -s a.exe
401	then tr=./a.exe
402	fi
403fi
404{
405	co -p $q a.c | $tr '\012' '\200' >a.24 &&
406	cp a.24 a.c &&
407	ciOut=`(ci -l -mm $q a.c 2>&1)` &&
408	case $ciOut in
409	?*) echo >&2 "$ciOut"
410	esac &&
411	co -p $q a.c | $tr '\200' '\012' >a.c &&
412	rcsdiff -r2.3 $q a.c >/dev/null &&
413
414	echo 2.5 >a.c &&
415	ci -l -mm $q a.c &&
416	cp a.24 a.c &&
417	rcsdiff -r2.4 $q a.c >/dev/null
418} || echo "#warning: Traditional diff is used, so RCS is limited to text files."
419
420rcs -u -o2.4: $q a.c || { echo "#rcs -u -o failed"; exit 1; }
421
422rcs -i -Aa.c -t- $q a.d || { echo "#rcs -i -A failed"; exit 1; }
423
424rlog -r2.1 a.c >a.t &&
425grep '^checked in with -k' a.t >/dev/null &&
426sed '/^checked in with -k/d' a.t >a.u &&
427$diff - a.u <<EOF
428
429RCS file: $RCSfile
430Working file: a.c
431head: 2.3
432branch:
433locks: strict
434access list:
435symbolic names:
436	N: 2.1
437	Oz: 2.1
438	n: 1.8
439keyword substitution: kv
440total revisions: 13;	selected revisions: 1
441description:
4421.1
443----------------------------
444revision 2.1
445date: $date;  author: w;  state: s;  lines: +14 -1
446=============================================================================
447EOF
448test $? = 0 || { echo "#rlog failed"; exit 1; }
449
450
451test ! -f $lockfile || { echo "#lock file not removed"; exit 1; }
452
453rm -f a.* $RCSfile $RCS_alt
454$rmdir RCS
455