More of previous.
[bpt/emacs.git] / lib-src / rcs2log
index e9474f6..099d4a3 100755 (executable)
@@ -2,7 +2,8 @@
 
 # RCS to ChangeLog generator
 
-# Generate a change log prefix from RCS files and the ChangeLog (if any).
+# Generate a change log prefix from RCS files (perhaps in the CVS repository)
+# and the ChangeLog (if any).
 # Output the new prefix to standard output.
 # You can edit this prefix by hand, and then prepend it to ChangeLog.
 
 # Clump together log entries that start with `{topic} ',
 # where `topic' contains neither white space nor `}'.
 
-# Author: Paul Eggert <eggert@twinsun.com>
+Help='The default FILEs are the files registered under the working directory.
+Options:
+
+  -c CHANGELOG  Output a change log prefix to CHANGELOG (default ChangeLog).
+  -h HOSTNAME  Use HOSTNAME in change log entries (default current host).
+  -i INDENT  Indent change log lines by INDENT spaces (default 8).
+  -l LENGTH  Try to limit log lines to LENGTH characters (default 79).
+  -R  If no FILEs are given and RCS is used, recurse through working directory.
+  -r OPTION  Pass OPTION to subsidiary log command.
+  -t TABWIDTH  Tab stops are every TABWIDTH characters (default 8).
+  -u "LOGIN<tab>FULLNAME<tab>MAILADDR"  Assume LOGIN has FULLNAME and MAILADDR.
+  -v  Append RCS revision to file names in log lines.
+  --help  Output help.
+  --version  Output version number.
+
+Report bugs to <bug-gnu-emacs@prep.ai.mit.edu>.'
 
-# $Id: rcs2log,v 1.28 1996/07/20 18:08:03 kwzh Exp erik $
+Id='$Id: rcs2log,v 1.41 1997/05/13 22:44:08 eggert Exp eggert $'
 
-# Copyright 1992, 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
+# Copyright 1992, 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with GNU Emacs; see the file COPYING.  If not, write to the
+# along with this program; see the file COPYING.  If not, write to the
 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 # Boston, MA 02111-1307, USA.
 
+Copyright='Copyright 1997 Free Software Foundation, Inc.
+This program comes with NO WARRANTY, to the extent permitted by law.
+You may redistribute copies of this program
+under the terms of the GNU General Public License.
+For more information about these matters, see the files named COPYING.
+Author: Paul Eggert <eggert@twinsun.com>'
+
 tab='  '
 nl='
 '
@@ -67,7 +90,10 @@ do
                                echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed"
                                exit 1
                        esac
-                       loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
+                       case $loginFullnameMailaddrs in
+                       '') loginFullnameMailaddrs=$2$tab$3$tab$4;;
+                       ?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
+                       esac
                        shift; shift; shift;;
                -u)
                        # If $2 is not tab-separated, use colon for separator.
@@ -90,21 +116,36 @@ do
                                echo >&2 "$0: -u '$2': not enough fields"
                                exit 1
                        esac
-                       loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
+                       case $loginFullnameMailaddrs in
+                       '') loginFullnameMailaddrs=$2;;
+                       ?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
+                       esac
                        shift
                esac
-               logins=$logins$nl$login
+               case $logins in
+               '') logins=$login;;
+               ?*) logins=$logins$nl$login
+               esac
                ;;
-       -r)     rlog_options=$rlog_options$nl${2?}; shift;;
+       -r)
+               case $rlog_options in
+               '') rlog_options=${2?};;
+               ?*) rlog_options=$rlog_options$nl${2?}
+               esac
+               shift;;
        -R)     recursive=t;;
        -t)     tabwidth=${2?}; shift;;
        -v)     revision=t;;
-       -*)     echo >&2 "$0: usage: $0 [options] [file ...]
-Options:
-       [-c changelog] [-h hostname] [-i indent] [-l length] [-R]
-       [-r rlog_option] [-t tabwidth] [-v]
-       [-u 'login<TAB>fullname<TAB>mailaddr']..."
-               exit 1;;
+       --version)
+               set $Id
+               rcs2logVersion=$3
+               echo >&2 "rcs2log (GNU Emacs) $rcs2logVersion$nl$Copyright"
+               exit 0;;
+       -*)     echo >&2 "Usage: $0 [OPTION]... [FILE ...]$nl$Help"
+               case $1 in
+               --help) exit 0;;
+               *) exit 1
+               esac;;
        *)      break
        esac
        shift
@@ -126,7 +167,6 @@ month_data='
 # what's already in ChangeLog; it's the user's responsibility to remove them.
 case $rlog_options in
 '')
-       date=1970
        if test -s "$changelog"
        then
                e='
@@ -147,16 +187,9 @@ case $rlog_options in
                '
                d=`$AWK "$e" <"$changelog"` || exit
                case $d in
-               ?*) date=$d
+               ?*) datearg="-d>$d"
                esac
        fi
-       datearg="-d>$date"
-esac
-
-# Use rlog's -zLT option, if rlog supports it.
-case `rlog -zLT 2>&1` in
-*'unknown option'*) ;;
-*) rlog_options=-zLT$nl$rlog_options
 esac
 
 # Use TZ specified by ChangeLog local variable, if any.
@@ -182,7 +215,7 @@ then
        rlog=rlog
        repository=
 else
-       rlog='cvs log'
+       rlog='cvs -q log'
        repository=`sed 1q <CVS/Repository` || exit
        test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit
        case $CVSROOT in
@@ -203,6 +236,16 @@ else
        esac
 fi
 
+# Use $rlog's -zLT option, if $rlog supports it.
+case `$rlog -zLT 2>&1` in
+*' option'*) ;;
+*)
+       case $rlog_options in
+       '') rlog_options=-zLT;;
+       ?*) rlog_options=-zLT$nl$rlog_options
+       esac
+esac
+
 # With no arguments, examine all files under the RCS directory.
 case $# in
 0)
@@ -217,7 +260,14 @@ case $# in
                        files=`
                                {
                                        case $RCSdirs in
-                                       ?*) find $RCSdirs -type f -print
+                                       ?*) find $RCSdirs \
+                                                       -type f \
+                                                       ! -name '*_' \
+                                                       ! -name ',*,' \
+                                                       ! -name '.*_' \
+                                                       ! -name .rcsfreeze.log \
+                                                       ! -name .rcsfreeze.ver \
+                                                       -print
                                        esac
                                        find . -name '*,v' -print
                                } |
@@ -229,10 +279,16 @@ case $# in
                        for file in RCS/.* RCS/* .*,v *,v
                        do
                                case $file in
-                               RCS/. | RCS/..) continue;;
-                               RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue
+                               RCS/. | RCS/.. | RCS/,*, | RCS/*_) continue;;
+                               RCS/.rcsfreeze.log | RCS/.rcsfreeze.ver) continue;;
+                               RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue;;
+                               RCS/*,v | RCS/.*,v) ;;
+                               RCS/* | RCS/.*) test -f "$file" || continue
+                               esac
+                               case $files in
+                               '') files=$file;;
+                               ?*) files=$files$nl$file
                                esac
-                               files=$files$nl$file
                        done
                        case $files in
                        '') exit 0
@@ -372,7 +428,7 @@ EOF
                (
                        cat /etc/passwd
                        for author in $authors
-                       do nismatch $author passwd.org_dir
+                       do NIS_PATH= nismatch $author passwd.org_dir
                        done
                        ypmatch $authors passwd
                ) 2>/dev/null |
@@ -383,7 +439,7 @@ esac
 
 # Function to print a single log line.
 # We don't use awk functions, to stay compatible with old awk versions.
-# `Log' is the log message (with \n replaced by \r).
+# `Log' is the log message (with \n replaced by \001).
 # `files' contains the affected files.
 printlogline='{
 
@@ -399,13 +455,13 @@ printlogline='{
 
        # If "label: comment" is too long, break the line after the ":".
        sep = " "
-       if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, CR)) sep = "\n" indent_string
+       if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, SOH)) sep = "\n" indent_string
 
        # Print the label.
        printf "%s*%s:", indent_string, files
 
-       # Print each line of the log, transliterating \r to \n.
-       while ((i = index(Log, CR)) != 0) {
+       # Print each line of the log, transliterating \001 to \n.
+       while ((i = index(Log, SOH)) != 0) {
                logline = substr(Log, 1, i-1)
                if (logline ~ /[^'"$tab"' ]/) {
                        printf "%s%s\n", sep, logline
@@ -443,7 +499,7 @@ esac
 # Process the rlog output, generating ChangeLog style entries.
 
 # First, reformat the rlog output so that each line contains one log entry.
-# Transliterate \n to \r so that multiline entries fit on a single line.
+# Transliterate \n to \001 so that multiline entries fit on a single line.
 # Discard irrelevant rlog output.
 $AWK <$rlogout '
        BEGIN { repository = "'"$repository"'" }
@@ -456,16 +512,22 @@ $AWK <$rlogout '
                        if (filename ~ /,v$/) {
                                filename = substr(filename, 1, length(filename) - 2)
                        }
+                       if (filename ~ /(^|\/)Attic\/[^\/]*$/) {
+                               i = length(filename)
+                               while (substr(filename, i, 1) != "/") i--
+                               filename = substr(filename, 1, i - 6) substr(filename, i + 1)
+                       }
                }
                rev = "?"
        }
        /^Working file:/ { if (repository == "") filename = $3 }
        /'"$rlog_revision_pattern"'/, /^(-----------*|===========*)$/ {
-               if ($0 ~ /'"$rlog_revision_pattern"'/) {
+               line = $0
+               if (line ~ /'"$rlog_revision_pattern"'/) {
                        rev = $2
                        next
                }
-               if ($0 ~ /^date: [0-9][- +\/0-9:]*;/) {
+               if (line ~ /^date: [0-9][- +\/0-9:]*;/) {
                        date = $2
                        if (date ~ /\//) {
                                # This is a traditional RCS format date YYYY/MM/DD.
@@ -479,20 +541,23 @@ $AWK <$rlogout '
                        }
                        time = substr($3, 1, length($3) - 1)
                        author = substr($5, 1, length($5)-1)
-                       printf "%s %s %s %s %s %c", filename, rev, date, time, author, 13
+                       printf "%s %s %s %s %s %c", filename, rev, date, time, author, 1
                        rev = "?"
                        next
                }
-               if ($0 ~ /^branches: /) { next }
-               if ($0 ~ /^(-----------*|===========*)$/) { print ""; next }
-               printf "%s%c", $0, 13
+               if (line ~ /^branches: /) { next }
+               if (line ~ /^(-----------*|===========*)$/) { print ""; next }
+               if (line == "Initial revision" || line ~ /^file .+ was initially added on branch .+\.$/) {
+                       line = "New file."
+               }
+               printf "%s%c", line, 1
        }
 ' |
 
 # Now each line is of the form
-# FILENAME REVISION YYYY-MM-DD HH:MM:SS[+-TIMEZONE] AUTHOR \rLOG
-#      where \r stands for a carriage return,
-#      and each line of the log is terminated by \r instead of \n.
+# FILENAME REVISION YYYY-MM-DD HH:MM:SS[+-TIMEZONE] AUTHOR \001LOG
+#      where \001 stands for a carriage return,
+#      and each line of the log is terminated by \001 instead of \n.
 # Sort the log entries, first by date+time (in reverse order),
 # then by author, then by log entry, and finally by file name and revision
 # (just in case).
@@ -504,9 +569,9 @@ $AWK '
                logTZ = "'"$logTZ"'"
                revision = "'"$revision"'"
 
-               # Some awk variants do not understand "\r" or "\013", so we have to
-               # put a carriage return directly in the file.
-               CR="\r" # <-- There is a single CR between the " chars here.
+               # Some awk variants do not understand "\001", so we have to
+               # put the char directly in the file.
+               SOH="\ 1" # <-- There is a single SOH (octal code 001) here.
 
                # Initialize the fullname and mailaddr associative arrays.
                '"$initialize_fullname"'
@@ -523,7 +588,7 @@ $AWK '
        }
 
        {
-               newlog = substr($0, 1 + index($0, CR))
+               newlog = substr($0, 1 + index($0, SOH))
 
                # Ignore log entries prefixed by "#".
                if (newlog ~ /^#/) { next }