#!/usr/bin/env bash
# cvs-to-rcs --- build complete rcs file archive from cvs checkout
# Author: Noah Friedman <friedman@splode.com>
# Created: 2006-08-28
# Public domain.

# $Id: cvs-to-rcs,v 1.3 2015/10/15 22:43:14 friedman Exp $

initialize()
{
    rm -f $base,v
    rcs -q -i -U $base,v < /dev/null
}

getrevs()
{
    sed -ne '/^revision /s///p' ${1-$logfile} |
        sort -t. -k1,1n -k2,2n -k3,3n -k4,4n -k5,5n -k6,6n
}

doci()
{
    getrevs |
        while read rev; do
            echo "* checkin: $rev"

            state= author= date= log= branches=
            eval "`getrevinfo $rev`"

            case $state in
                dead )
                    br=${rev%.*}
                    this=${rev##*.}
                    lastrev=$br.$((this - 1))
                    cp $lastrev $rev
                    ;;
            esac

            cp $rev $base

            ci -q -f -r$rev -s$state -w$author -d"$date" -m"$log" $base
        done
}

getrevinfo()
{
    sed -ne '/^revision '${1-1.1}'$/!d
      :v
      n
      /^date: *\([^;]*\); *author: *\([^;]*\); *state: *\([^;]*\);.*/{
        s//date="\1" author=\2 state=\3/
        h
        b v
      }

      /^branches: */{
        s//branches="/
        s/; */ /g
        s/$/"/
        H
        b v
      }

      s/^/log=/
      :l
      /^[-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=][-=]*/b e
      s/\(["`]\)/\\\1/g
      H
      n
      b l

      :e
      g
      s/\(\nlog=\)/\1"/
      s/$/"/
      p
      q'  $logfile
}

kv()
{
    echo kv=;
    sed -ne '/^keyword substitution: */s//kv=/p' $logfile
}

desc()
{
    echo desc=;
    sed -ne '
        /^description:/!d
        :l
        n
        /^----------------------------$/b e
        H
        b l
        :e
        g
        s/\(["`]\)/\\\1/g
        /^\n./!q
        s/^\n/desc="/
        s/$/"/
        p
    ' $logfile
}

tags()
{
    sed -ne '
      /^symbolic names:/!d
      :l
      n
      /^	/!q
      s///
      s/ *//g
      s/\.0\././
      p
      b l
    ' $logfile | tac
}

finalize()
{
    tags | while read tag; do
        echo "* tag: $tag"
        rcs -q -n$tag $base,v
    done

    eval "`kv`"
    case $kv in
        '' ) : ;;
        * )
            echo "* keyword substitution: $kv"
            rcs -q -k$kv $base,v ;;
    esac

    if grep '^locks: strict' $logfile > /dev/null ; then
        echo "* locks: strict"
        rcs -q -L $base,v
    fi

    eval "`desc`"
    case $desc in
        '' ) : ;;
        * )
            echo "* Description:"
            echo "$desc" | sed 's/^/	/'
            rcs -q -t-"$desc" $base,v
            ;;
    esac

    stamp=`rlog -N -r $base,v | sed -ne '/^date: \([^;]*\);.*/!d;s//\1/p'`
    touch -d "$stamp UTC" $base,v
}

######
#####

cvs()
{
    command cvs -z3 "$@"
}

cvs_init()
{
    mkdir .$base.d || exit 1
}

cvs_getlog()
{
    cvs log $base > .$base.d/$logfile
}

cvs_getrevs()
{
    getrevs .$base.d/$logfile |
        while read v; do
            cvs update -p -r$v $base > .$base.d/$v
        done
}

######
######

convert()
{
    base=${1-file.c}
    logfile=${2-cvs.log}

    if [ -d CVS ]; then
        cvs_init
        cvs_getlog
        cvs_getrevs
        ( cd .$base.d || exit 1

          initialize
          doci
          finalize

          case $CVS2RCS_DEBUG in
              '' ) mv $base,v ..
                   cd ..
                   rm -rf .$base.d ;;
          esac
        )
    else
        initialize
        doci
        finalize
    fi
}

main()
{
    for file in "$@"; do
        if [ -f "$file" ]; then
            (convert $file)
        else
            find $file \( -name CVS -prune \) -o -type d -print |
                while read d; do
                    ( cd $d
                      for f in .* *; do
                          test -f $f || continue
                          (convert $f)
                      done
                    )
                done
        fi
    done
}

main ${1+"$@"}

# eof
