#!/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. # $Id: rcstest,v 1.1 1995/10/18 08:40:59 deraadt Exp $ # Copyright 1990, 1991, 1992, 1993, 1994 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, 675 Mass Ave, Cambridge, MA 02139, USA. # # Report problems and direct all questions to: # # rcs-bugs@cs.purdue.edu # The Makefile overrides the following defaults. : ${CC=cc} : ${CFLAGS=-O} : ${DIFF=diff} # : ${LDFLAGS=} ${LDLIBS=} tickles old shell bug CL="$CC $CFLAGS $LDFLAGS" L=$LDLIBS 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 <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 || 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 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 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 <