1*86d7f5d3SJohn Marino#! /bin/sh
2*86d7f5d3SJohn Marino
3*86d7f5d3SJohn Marino# Copyright (C) 1995-2005 The Free Software Foundation, Inc.
4*86d7f5d3SJohn Marino
5*86d7f5d3SJohn Marino# This program is free software; you can redistribute it and/or modify
6*86d7f5d3SJohn Marino# it under the terms of the GNU General Public License as published by
7*86d7f5d3SJohn Marino# the Free Software Foundation; either version 2, or (at your option)
8*86d7f5d3SJohn Marino# any later version.
9*86d7f5d3SJohn Marino#
10*86d7f5d3SJohn Marino# This program is distributed in the hope that it will be useful,
11*86d7f5d3SJohn Marino# but WITHOUT ANY WARRANTY; without even the implied warranty of
12*86d7f5d3SJohn Marino# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*86d7f5d3SJohn Marino# GNU General Public License for more details.
14*86d7f5d3SJohn Marino
15*86d7f5d3SJohn Marino# RCS to ChangeLog generator
16*86d7f5d3SJohn Marino
17*86d7f5d3SJohn Marino# Generate a change log prefix from RCS files (perhaps in the CVS repository)
18*86d7f5d3SJohn Marino# and the ChangeLog (if any).
19*86d7f5d3SJohn Marino# Output the new prefix to standard output.
20*86d7f5d3SJohn Marino# You can edit this prefix by hand, and then prepend it to ChangeLog.
21*86d7f5d3SJohn Marino
22*86d7f5d3SJohn Marino# Ignore log entries that start with `#'.
23*86d7f5d3SJohn Marino# Clump together log entries that start with `{topic} ',
24*86d7f5d3SJohn Marino# where `topic' contains neither white space nor `}'.
25*86d7f5d3SJohn Marino
26*86d7f5d3SJohn MarinoHelp='The default FILEs are the files registered under the working directory.
27*86d7f5d3SJohn MarinoOptions:
28*86d7f5d3SJohn Marino
29*86d7f5d3SJohn Marino  -c CHANGELOG  Output a change log prefix to CHANGELOG (default ChangeLog).
30*86d7f5d3SJohn Marino  -h HOSTNAME  Use HOSTNAME in change log entries (default current host).
31*86d7f5d3SJohn Marino  -i INDENT  Indent change log lines by INDENT spaces (default 8).
32*86d7f5d3SJohn Marino  -l LENGTH  Try to limit log lines to LENGTH characters (default 79).
33*86d7f5d3SJohn Marino  -L FILE  Use rlog-format FILE for source of logs.
34*86d7f5d3SJohn Marino  -R  If no FILEs are given and RCS is used, recurse through working directory.
35*86d7f5d3SJohn Marino  -r OPTION  Pass OPTION to subsidiary log command.
36*86d7f5d3SJohn Marino  -t TABWIDTH  Tab stops are every TABWIDTH characters (default 8).
37*86d7f5d3SJohn Marino  -u "LOGIN<tab>FULLNAME<tab>MAILADDR"  Assume LOGIN has FULLNAME and MAILADDR.
38*86d7f5d3SJohn Marino  -v  Append RCS revision to file names in log lines.
39*86d7f5d3SJohn Marino  --help  Output help.
40*86d7f5d3SJohn Marino  --version  Output version number.
41*86d7f5d3SJohn Marino
42*86d7f5d3SJohn MarinoReport bugs to <bug-gnu-emacs@gnu.org>.'
43*86d7f5d3SJohn Marino
44*86d7f5d3SJohn MarinoId='$Id: rcs2log,v 1.48 2001/09/05 23:07:46 eggert Exp $'
45*86d7f5d3SJohn Marino
46*86d7f5d3SJohn Marino# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001, 2003
47*86d7f5d3SJohn Marino#  Free Software Foundation, Inc.
48*86d7f5d3SJohn Marino
49*86d7f5d3SJohn Marino# This program is free software; you can redistribute it and/or modify
50*86d7f5d3SJohn Marino# it under the terms of the GNU General Public License as published by
51*86d7f5d3SJohn Marino# the Free Software Foundation; either version 2, or (at your option)
52*86d7f5d3SJohn Marino# any later version.
53*86d7f5d3SJohn Marino#
54*86d7f5d3SJohn Marino# This program is distributed in the hope that it will be useful,
55*86d7f5d3SJohn Marino# but WITHOUT ANY WARRANTY; without even the implied warranty of
56*86d7f5d3SJohn Marino# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
57*86d7f5d3SJohn Marino# GNU General Public License for more details.
58*86d7f5d3SJohn Marino#
59*86d7f5d3SJohn Marino# You should have received a copy of the GNU General Public License
60*86d7f5d3SJohn Marino# along with this program; see the file COPYING.  If not, write to the
61*86d7f5d3SJohn Marino# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
62*86d7f5d3SJohn Marino# Boston, MA 02111-1307, USA.
63*86d7f5d3SJohn Marino
64*86d7f5d3SJohn MarinoCopyright='Copyright 1992-2003 Free Software Foundation, Inc.
65*86d7f5d3SJohn MarinoThis program comes with NO WARRANTY, to the extent permitted by law.
66*86d7f5d3SJohn MarinoYou may redistribute copies of this program
67*86d7f5d3SJohn Marinounder the terms of the GNU General Public License.
68*86d7f5d3SJohn MarinoFor more information about these matters, see the files named COPYING.
69*86d7f5d3SJohn MarinoAuthor: Paul Eggert <eggert@twinsun.com>'
70*86d7f5d3SJohn Marino
71*86d7f5d3SJohn Marino# functions
72*86d7f5d3SJohn Marino@MKTEMP_SH_FUNCTION@
73*86d7f5d3SJohn Marino
74*86d7f5d3SJohn Marino# Use the traditional C locale.
75*86d7f5d3SJohn MarinoLANG=C
76*86d7f5d3SJohn MarinoLANGUAGE=C
77*86d7f5d3SJohn MarinoLC_ALL=C
78*86d7f5d3SJohn MarinoLC_COLLATE=C
79*86d7f5d3SJohn MarinoLC_CTYPE=C
80*86d7f5d3SJohn MarinoLC_MESSAGES=C
81*86d7f5d3SJohn MarinoLC_NUMERIC=C
82*86d7f5d3SJohn MarinoLC_TIME=C
83*86d7f5d3SJohn Marinoexport LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME
84*86d7f5d3SJohn Marino
85*86d7f5d3SJohn Marino# These variables each contain a single ASCII character.
86*86d7f5d3SJohn Marino# Unfortunately, there's no portable way of writing these characters
87*86d7f5d3SJohn Marino# in older Unix implementations, other than putting them directly into
88*86d7f5d3SJohn Marino# this text file.
89*86d7f5d3SJohn MarinoSOH='' # SOH, octal code 001
90*86d7f5d3SJohn Marinotab='	'
91*86d7f5d3SJohn Marinonl='
92*86d7f5d3SJohn Marino'
93*86d7f5d3SJohn Marino
94*86d7f5d3SJohn Marino# Parse options.
95*86d7f5d3SJohn Marino
96*86d7f5d3SJohn Marino# defaults
97*86d7f5d3SJohn Marino: ${MKTEMP="@MKTEMP@"}
98*86d7f5d3SJohn Marino: ${AWK=awk}
99*86d7f5d3SJohn Marino: ${TMPDIR=/tmp}
100*86d7f5d3SJohn Marino
101*86d7f5d3SJohn Marinochangelog=ChangeLog # change log file name
102*86d7f5d3SJohn Marinodatearg= # rlog date option
103*86d7f5d3SJohn Marinohostname= # name of local host (if empty, will deduce it later)
104*86d7f5d3SJohn Marinoindent=8 # indent of log line
105*86d7f5d3SJohn Marinolength=79 # suggested max width of log line
106*86d7f5d3SJohn Marinologins= # login names for people we know fullnames and mailaddrs of
107*86d7f5d3SJohn MarinologinFullnameMailaddrs= # login<tab>fullname<tab>mailaddr triplets
108*86d7f5d3SJohn MarinologTZ= # time zone for log dates (if empty, use local time)
109*86d7f5d3SJohn Marinorecursive= # t if we want recursive rlog
110*86d7f5d3SJohn Marinorevision= # t if we want revision numbers
111*86d7f5d3SJohn Marinorlog_options= # options to pass to rlog
112*86d7f5d3SJohn Marinorlogfile= # log file to read from
113*86d7f5d3SJohn Marinotabwidth=8 # width of horizontal tab
114*86d7f5d3SJohn Marino
115*86d7f5d3SJohn Marinowhile :
116*86d7f5d3SJohn Marinodo
117*86d7f5d3SJohn Marino	case $1 in
118*86d7f5d3SJohn Marino	-c)	changelog=${2?}; shift;;
119*86d7f5d3SJohn Marino	-i)	indent=${2?}; shift;;
120*86d7f5d3SJohn Marino	-h)	hostname=${2?}; shift;;
121*86d7f5d3SJohn Marino	-l)	length=${2?}; shift;;
122*86d7f5d3SJohn Marino	-L)	rlogfile=${2?}; shift;;
123*86d7f5d3SJohn Marino	-[nu])	# -n is obsolescent; it is replaced by -u.
124*86d7f5d3SJohn Marino		case $1 in
125*86d7f5d3SJohn Marino		-n)	case ${2?}${3?}${4?} in
126*86d7f5d3SJohn Marino			*"$tab"* | *"$nl"*)
127*86d7f5d3SJohn Marino				echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed"
128*86d7f5d3SJohn Marino				exit 1;;
129*86d7f5d3SJohn Marino			esac
130*86d7f5d3SJohn Marino			login=$2
131*86d7f5d3SJohn Marino			lfm=$2$tab$3$tab$4
132*86d7f5d3SJohn Marino			shift; shift; shift;;
133*86d7f5d3SJohn Marino		-u)
134*86d7f5d3SJohn Marino			# If $2 is not tab-separated, use colon for separator.
135*86d7f5d3SJohn Marino			case ${2?} in
136*86d7f5d3SJohn Marino			*"$nl"*)
137*86d7f5d3SJohn Marino				echo >&2 "$0: -u '$2': newlines not allowed"
138*86d7f5d3SJohn Marino				exit 1;;
139*86d7f5d3SJohn Marino			*"$tab"*)
140*86d7f5d3SJohn Marino				t=$tab;;
141*86d7f5d3SJohn Marino			*)
142*86d7f5d3SJohn Marino				t=':';;
143*86d7f5d3SJohn Marino			esac
144*86d7f5d3SJohn Marino			case $2 in
145*86d7f5d3SJohn Marino			*"$t"*"$t"*"$t"*)
146*86d7f5d3SJohn Marino				echo >&2 "$0: -u '$2': too many fields"
147*86d7f5d3SJohn Marino				exit 1;;
148*86d7f5d3SJohn Marino			*"$t"*"$t"*)
149*86d7f5d3SJohn Marino				uf="[^$t]*$t" # An unselected field, followed by a separator.
150*86d7f5d3SJohn Marino				sf="\\([^$t]*\\)" # The selected field.
151*86d7f5d3SJohn Marino				login=`expr "X$2" : "X$sf"`
152*86d7f5d3SJohn Marino				lfm="$login$tab"`
153*86d7f5d3SJohn Marino					expr "X$2" : "$uf$sf"
154*86d7f5d3SJohn Marino				  `"$tab"`
155*86d7f5d3SJohn Marino					expr "X$2" : "$uf$uf$sf"
156*86d7f5d3SJohn Marino				`;;
157*86d7f5d3SJohn Marino			*)
158*86d7f5d3SJohn Marino				echo >&2 "$0: -u '$2': not enough fields"
159*86d7f5d3SJohn Marino				exit 1;;
160*86d7f5d3SJohn Marino			esac
161*86d7f5d3SJohn Marino			shift;;
162*86d7f5d3SJohn Marino		esac
163*86d7f5d3SJohn Marino		case $logins in
164*86d7f5d3SJohn Marino		'') logins=$login;;
165*86d7f5d3SJohn Marino		?*) logins=$logins$nl$login;;
166*86d7f5d3SJohn Marino		esac
167*86d7f5d3SJohn Marino		case $loginFullnameMailaddrs in
168*86d7f5d3SJohn Marino		'') loginFullnameMailaddrs=$lfm;;
169*86d7f5d3SJohn Marino		?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$lfm;;
170*86d7f5d3SJohn Marino		esac;;
171*86d7f5d3SJohn Marino	-r)
172*86d7f5d3SJohn Marino		case $rlog_options in
173*86d7f5d3SJohn Marino		'') rlog_options=${2?};;
174*86d7f5d3SJohn Marino		?*) rlog_options=$rlog_options$nl${2?};;
175*86d7f5d3SJohn Marino		esac
176*86d7f5d3SJohn Marino		shift;;
177*86d7f5d3SJohn Marino	-R)	recursive=t;;
178*86d7f5d3SJohn Marino	-t)	tabwidth=${2?}; shift;;
179*86d7f5d3SJohn Marino	-v)	revision=t;;
180*86d7f5d3SJohn Marino	--version)
181*86d7f5d3SJohn Marino		set $Id
182*86d7f5d3SJohn Marino		rcs2logVersion=$3
183*86d7f5d3SJohn Marino		echo >&2 "rcs2log (GNU Emacs) $rcs2logVersion$nl$Copyright"
184*86d7f5d3SJohn Marino		exit 0;;
185*86d7f5d3SJohn Marino	-*)	echo >&2 "Usage: $0 [OPTION]... [FILE ...]$nl$Help"
186*86d7f5d3SJohn Marino		case $1 in
187*86d7f5d3SJohn Marino		--help) exit 0;;
188*86d7f5d3SJohn Marino		*) exit 1;;
189*86d7f5d3SJohn Marino		esac;;
190*86d7f5d3SJohn Marino	*)	break;;
191*86d7f5d3SJohn Marino	esac
192*86d7f5d3SJohn Marino	shift
193*86d7f5d3SJohn Marinodone
194*86d7f5d3SJohn Marino
195*86d7f5d3SJohn Marinomonth_data='
196*86d7f5d3SJohn Marino	m[0]="Jan"; m[1]="Feb"; m[2]="Mar"
197*86d7f5d3SJohn Marino	m[3]="Apr"; m[4]="May"; m[5]="Jun"
198*86d7f5d3SJohn Marino	m[6]="Jul"; m[7]="Aug"; m[8]="Sep"
199*86d7f5d3SJohn Marino	m[9]="Oct"; m[10]="Nov"; m[11]="Dec"
200*86d7f5d3SJohn Marino'
201*86d7f5d3SJohn Marino
202*86d7f5d3SJohn Marinologdir=`$MKTEMP -d $TMPDIR/rcs2log.XXXXXX`
203*86d7f5d3SJohn Marinotest -n "$logdir" || exit
204*86d7f5d3SJohn Marinollogout=$logdir/l
205*86d7f5d3SJohn Marinotrap exit 1 2 13 15
206*86d7f5d3SJohn Marinotrap "rm -fr $logdir 2>/dev/null" 0
207*86d7f5d3SJohn Marino
208*86d7f5d3SJohn Marino# If no rlog-format log file is given, generate one into $rlogfile.
209*86d7f5d3SJohn Marinocase $rlogfile in
210*86d7f5d3SJohn Marino'')
211*86d7f5d3SJohn Marino	rlogfile=$logdir/r
212*86d7f5d3SJohn Marino
213*86d7f5d3SJohn Marino	# If no rlog options are given,
214*86d7f5d3SJohn Marino	# log the revisions checked in since the first ChangeLog entry.
215*86d7f5d3SJohn Marino	# Since ChangeLog is only by date, some of these revisions may be duplicates of
216*86d7f5d3SJohn Marino	# what's already in ChangeLog; it's the user's responsibility to remove them.
217*86d7f5d3SJohn Marino	case $rlog_options in
218*86d7f5d3SJohn Marino	'')
219*86d7f5d3SJohn Marino		if test -s "$changelog"
220*86d7f5d3SJohn Marino		then
221*86d7f5d3SJohn Marino			e='
222*86d7f5d3SJohn Marino				/^[0-9]+-[0-9][0-9]-[0-9][0-9]/{
223*86d7f5d3SJohn Marino					# ISO 8601 date
224*86d7f5d3SJohn Marino					print $1
225*86d7f5d3SJohn Marino					exit
226*86d7f5d3SJohn Marino				}
227*86d7f5d3SJohn Marino				/^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{
228*86d7f5d3SJohn Marino					# old-fashioned date and time (Emacs 19.31 and earlier)
229*86d7f5d3SJohn Marino					'"$month_data"'
230*86d7f5d3SJohn Marino					year = $5
231*86d7f5d3SJohn Marino					for (i=0; i<=11; i++) if (m[i] == $2) break
232*86d7f5d3SJohn Marino					dd = $3
233*86d7f5d3SJohn Marino					printf "%d-%02d-%02d\n", year, i+1, dd
234*86d7f5d3SJohn Marino					exit
235*86d7f5d3SJohn Marino				}
236*86d7f5d3SJohn Marino			'
237*86d7f5d3SJohn Marino			d=`$AWK "$e" <"$changelog"` || exit
238*86d7f5d3SJohn Marino			case $d in
239*86d7f5d3SJohn Marino			?*) datearg="-d>$d";;
240*86d7f5d3SJohn Marino			esac
241*86d7f5d3SJohn Marino		fi;;
242*86d7f5d3SJohn Marino	esac
243*86d7f5d3SJohn Marino
244*86d7f5d3SJohn Marino	# Use TZ specified by ChangeLog local variable, if any.
245*86d7f5d3SJohn Marino	if test -s "$changelog"
246*86d7f5d3SJohn Marino	then
247*86d7f5d3SJohn Marino		extractTZ='
248*86d7f5d3SJohn Marino			/^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*"\([^"]*\)".*/{
249*86d7f5d3SJohn Marino				s//\1/; p; q
250*86d7f5d3SJohn Marino			}
251*86d7f5d3SJohn Marino			/^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*t.*/{
252*86d7f5d3SJohn Marino				s//UTC0/; p; q
253*86d7f5d3SJohn Marino			}
254*86d7f5d3SJohn Marino		'
255*86d7f5d3SJohn Marino		logTZ=`tail "$changelog" | sed -n "$extractTZ"`
256*86d7f5d3SJohn Marino		case $logTZ in
257*86d7f5d3SJohn Marino		?*) TZ=$logTZ; export TZ;;
258*86d7f5d3SJohn Marino		esac
259*86d7f5d3SJohn Marino	fi
260*86d7f5d3SJohn Marino
261*86d7f5d3SJohn Marino	# If CVS is in use, examine its repository, not the normal RCS files.
262*86d7f5d3SJohn Marino	if test ! -f CVS/Repository
263*86d7f5d3SJohn Marino	then
264*86d7f5d3SJohn Marino		rlog=rlog
265*86d7f5d3SJohn Marino		repository=
266*86d7f5d3SJohn Marino	else
267*86d7f5d3SJohn Marino		rlog='cvs -q log'
268*86d7f5d3SJohn Marino		repository=`sed 1q <CVS/Repository` || exit
269*86d7f5d3SJohn Marino		test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit
270*86d7f5d3SJohn Marino		case $CVSROOT in
271*86d7f5d3SJohn Marino		*:/*:/*)
272*86d7f5d3SJohn Marino			echo >&2 "$0: $CVSROOT: CVSROOT has multiple ':/'s"
273*86d7f5d3SJohn Marino			exit 1;;
274*86d7f5d3SJohn Marino		*:/*)
275*86d7f5d3SJohn Marino			# remote repository
276*86d7f5d3SJohn Marino			pository=`expr "X$repository" : '.*:\(/.*\)'`;;
277*86d7f5d3SJohn Marino		*)
278*86d7f5d3SJohn Marino			# local repository
279*86d7f5d3SJohn Marino			case $repository in
280*86d7f5d3SJohn Marino			/*) ;;
281*86d7f5d3SJohn Marino			*) repository=${CVSROOT?}/$repository;;
282*86d7f5d3SJohn Marino			esac
283*86d7f5d3SJohn Marino			if test ! -d "$repository"
284*86d7f5d3SJohn Marino			then
285*86d7f5d3SJohn Marino				echo >&2 "$0: $repository: bad repository (see CVS/Repository)"
286*86d7f5d3SJohn Marino				exit 1
287*86d7f5d3SJohn Marino			fi
288*86d7f5d3SJohn Marino			pository=$repository;;
289*86d7f5d3SJohn Marino		esac
290*86d7f5d3SJohn Marino
291*86d7f5d3SJohn Marino		# Ensure that $pository ends in exactly one slash.
292*86d7f5d3SJohn Marino		while :
293*86d7f5d3SJohn Marino		do
294*86d7f5d3SJohn Marino			case $pository in
295*86d7f5d3SJohn Marino			*//) pository=`expr "X$pository" : 'X\(.*\)/'`;;
296*86d7f5d3SJohn Marino			*/) break;;
297*86d7f5d3SJohn Marino			*) pository=$pository/; break;;
298*86d7f5d3SJohn Marino			esac
299*86d7f5d3SJohn Marino		done
300*86d7f5d3SJohn Marino
301*86d7f5d3SJohn Marino	fi
302*86d7f5d3SJohn Marino
303*86d7f5d3SJohn Marino	# Use $rlog's -zLT option, if $rlog supports it.
304*86d7f5d3SJohn Marino	case `$rlog -zLT 2>&1` in
305*86d7f5d3SJohn Marino	*' option'*) ;;
306*86d7f5d3SJohn Marino	*)
307*86d7f5d3SJohn Marino		case $rlog_options in
308*86d7f5d3SJohn Marino		'') rlog_options=-zLT;;
309*86d7f5d3SJohn Marino		?*) rlog_options=-zLT$nl$rlog_options;;
310*86d7f5d3SJohn Marino		esac;;
311*86d7f5d3SJohn Marino	esac
312*86d7f5d3SJohn Marino
313*86d7f5d3SJohn Marino	# With no arguments, examine all files under the RCS directory.
314*86d7f5d3SJohn Marino	case $# in
315*86d7f5d3SJohn Marino	0)
316*86d7f5d3SJohn Marino		case $repository in
317*86d7f5d3SJohn Marino		'')
318*86d7f5d3SJohn Marino			oldIFS=$IFS
319*86d7f5d3SJohn Marino			IFS=$nl
320*86d7f5d3SJohn Marino			case $recursive in
321*86d7f5d3SJohn Marino			t)
322*86d7f5d3SJohn Marino				RCSdirs=`find . -name RCS -type d -print`
323*86d7f5d3SJohn Marino				filesFromRCSfiles='s|,v$||; s|/RCS/|/|; s|^\./||'
324*86d7f5d3SJohn Marino				files=`
325*86d7f5d3SJohn Marino					{
326*86d7f5d3SJohn Marino						case $RCSdirs in
327*86d7f5d3SJohn Marino						?*) find $RCSdirs \
328*86d7f5d3SJohn Marino								-type f \
329*86d7f5d3SJohn Marino								! -name '*_' \
330*86d7f5d3SJohn Marino								! -name ',*,' \
331*86d7f5d3SJohn Marino								! -name '.*_' \
332*86d7f5d3SJohn Marino								! -name .rcsfreeze.log \
333*86d7f5d3SJohn Marino								! -name .rcsfreeze.ver \
334*86d7f5d3SJohn Marino								-print;;
335*86d7f5d3SJohn Marino						esac
336*86d7f5d3SJohn Marino						find . -name '*,v' -print
337*86d7f5d3SJohn Marino					} |
338*86d7f5d3SJohn Marino					sort -u |
339*86d7f5d3SJohn Marino					sed "$filesFromRCSfiles"
340*86d7f5d3SJohn Marino				`;;
341*86d7f5d3SJohn Marino			*)
342*86d7f5d3SJohn Marino				files=
343*86d7f5d3SJohn Marino				for file in RCS/.* RCS/* .*,v *,v
344*86d7f5d3SJohn Marino				do
345*86d7f5d3SJohn Marino					case $file in
346*86d7f5d3SJohn Marino					RCS/. | RCS/.. | RCS/,*, | RCS/*_) continue;;
347*86d7f5d3SJohn Marino					RCS/.rcsfreeze.log | RCS/.rcsfreeze.ver) continue;;
348*86d7f5d3SJohn Marino					RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue;;
349*86d7f5d3SJohn Marino					RCS/*,v | RCS/.*,v) ;;
350*86d7f5d3SJohn Marino					RCS/* | RCS/.*) test -f "$file" || continue;;
351*86d7f5d3SJohn Marino					esac
352*86d7f5d3SJohn Marino					case $files in
353*86d7f5d3SJohn Marino					'') files=$file;;
354*86d7f5d3SJohn Marino					?*) files=$files$nl$file;;
355*86d7f5d3SJohn Marino					esac
356*86d7f5d3SJohn Marino				done
357*86d7f5d3SJohn Marino				case $files in
358*86d7f5d3SJohn Marino				'') exit 0;;
359*86d7f5d3SJohn Marino				esac;;
360*86d7f5d3SJohn Marino			esac
361*86d7f5d3SJohn Marino			set x $files
362*86d7f5d3SJohn Marino			shift
363*86d7f5d3SJohn Marino			IFS=$oldIFS;;
364*86d7f5d3SJohn Marino		esac;;
365*86d7f5d3SJohn Marino	esac
366*86d7f5d3SJohn Marino
367*86d7f5d3SJohn Marino	case $datearg in
368*86d7f5d3SJohn Marino	?*) $rlog $rlog_options "$datearg" ${1+"$@"} >$rlogfile;;
369*86d7f5d3SJohn Marino	'') $rlog $rlog_options ${1+"$@"} >$rlogfile;;
370*86d7f5d3SJohn Marino	esac || exit;;
371*86d7f5d3SJohn Marinoesac
372*86d7f5d3SJohn Marino
373*86d7f5d3SJohn Marino
374*86d7f5d3SJohn Marino# Get the full name of each author the logs mention, and set initialize_fullname
375*86d7f5d3SJohn Marino# to awk code that initializes the `fullname' awk associative array.
376*86d7f5d3SJohn Marino# Warning: foreign authors (i.e. not known in the passwd file) are mishandled;
377*86d7f5d3SJohn Marino# you have to fix the resulting output by hand.
378*86d7f5d3SJohn Marino
379*86d7f5d3SJohn Marinoinitialize_fullname=
380*86d7f5d3SJohn Marinoinitialize_mailaddr=
381*86d7f5d3SJohn Marino
382*86d7f5d3SJohn Marinocase $loginFullnameMailaddrs in
383*86d7f5d3SJohn Marino?*)
384*86d7f5d3SJohn Marino	case $loginFullnameMailaddrs in
385*86d7f5d3SJohn Marino	*\"* | *\\*)
386*86d7f5d3SJohn Marino		sed 's/["\\]/\\&/g' >$llogout <<EOF || exit
387*86d7f5d3SJohn Marino$loginFullnameMailaddrs
388*86d7f5d3SJohn MarinoEOF
389*86d7f5d3SJohn Marino		loginFullnameMailaddrs=`cat $llogout`;;
390*86d7f5d3SJohn Marino	esac
391*86d7f5d3SJohn Marino
392*86d7f5d3SJohn Marino	oldIFS=$IFS
393*86d7f5d3SJohn Marino	IFS=$nl
394*86d7f5d3SJohn Marino	for loginFullnameMailaddr in $loginFullnameMailaddrs
395*86d7f5d3SJohn Marino	do
396*86d7f5d3SJohn Marino		IFS=$tab
397*86d7f5d3SJohn Marino		set x $loginFullnameMailaddr
398*86d7f5d3SJohn Marino		login=$2
399*86d7f5d3SJohn Marino		fullname=$3
400*86d7f5d3SJohn Marino		mailaddr=$4
401*86d7f5d3SJohn Marino		initialize_fullname="$initialize_fullname
402*86d7f5d3SJohn Marino			fullname[\"$login\"] = \"$fullname\""
403*86d7f5d3SJohn Marino		initialize_mailaddr="$initialize_mailaddr
404*86d7f5d3SJohn Marino			mailaddr[\"$login\"] = \"$mailaddr\""
405*86d7f5d3SJohn Marino	done
406*86d7f5d3SJohn Marino	IFS=$oldIFS;;
407*86d7f5d3SJohn Marinoesac
408*86d7f5d3SJohn Marino
409*86d7f5d3SJohn Marinocase $logins in
410*86d7f5d3SJohn Marino?*)
411*86d7f5d3SJohn Marino	sort -u -o $llogout <<EOF
412*86d7f5d3SJohn Marino$logins
413*86d7f5d3SJohn MarinoEOF
414*86d7f5d3SJohn Marino	;;
415*86d7f5d3SJohn Marino'')
416*86d7f5d3SJohn Marino	: ;;
417*86d7f5d3SJohn Marinoesac >$llogout || exit
418*86d7f5d3SJohn Marino
419*86d7f5d3SJohn Marinooutput_authors='/^date: / {
420*86d7f5d3SJohn Marino	if ($2 ~ /^[0-9]*[-\/][0-9][0-9][-\/][0-9][0-9]$/ && $3 ~ /^[0-9][0-9]:[0-9][0-9]:[0-9][0-9][-+0-9:]*;$/ && $4 == "author:" && $5 ~ /^[^;]*;$/) {
421*86d7f5d3SJohn Marino		print substr($5, 1, length($5)-1)
422*86d7f5d3SJohn Marino	}
423*86d7f5d3SJohn Marino}'
424*86d7f5d3SJohn Marinoauthors=`
425*86d7f5d3SJohn Marino	$AWK "$output_authors" <"$rlogfile" | sort -u | comm -23 - $llogout
426*86d7f5d3SJohn Marino`
427*86d7f5d3SJohn Marinocase $authors in
428*86d7f5d3SJohn Marino?*)
429*86d7f5d3SJohn Marino	cat >$llogout <<EOF || exit
430*86d7f5d3SJohn Marino$authors
431*86d7f5d3SJohn MarinoEOF
432*86d7f5d3SJohn Marino	initialize_author_script='s/["\\]/\\&/g; s/.*/author[\"&\"] = 1/'
433*86d7f5d3SJohn Marino	initialize_author=`sed -e "$initialize_author_script" <$llogout`
434*86d7f5d3SJohn Marino	awkscript='
435*86d7f5d3SJohn Marino		BEGIN {
436*86d7f5d3SJohn Marino			alphabet = "abcdefghijklmnopqrstuvwxyz"
437*86d7f5d3SJohn Marino			ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
438*86d7f5d3SJohn Marino			'"$initialize_author"'
439*86d7f5d3SJohn Marino		}
440*86d7f5d3SJohn Marino		{
441*86d7f5d3SJohn Marino			if (author[$1]) {
442*86d7f5d3SJohn Marino				fullname = $5
443*86d7f5d3SJohn Marino				if (fullname ~ /[0-9]+-[^(]*\([0-9]+\)$/) {
444*86d7f5d3SJohn Marino					# Remove the junk from fullnames like "0000-Admin(0000)".
445*86d7f5d3SJohn Marino					fullname = substr(fullname, index(fullname, "-") + 1)
446*86d7f5d3SJohn Marino					fullname = substr(fullname, 1, index(fullname, "(") - 1)
447*86d7f5d3SJohn Marino				}
448*86d7f5d3SJohn Marino				if (fullname ~ /,[^ ]/) {
449*86d7f5d3SJohn Marino					# Some sites put comma-separated junk after the fullname.
450*86d7f5d3SJohn Marino					# Remove it, but leave "Bill Gates, Jr" alone.
451*86d7f5d3SJohn Marino					fullname = substr(fullname, 1, index(fullname, ",") - 1)
452*86d7f5d3SJohn Marino				}
453*86d7f5d3SJohn Marino				abbr = index(fullname, "&")
454*86d7f5d3SJohn Marino				if (abbr) {
455*86d7f5d3SJohn Marino					a = substr($1, 1, 1)
456*86d7f5d3SJohn Marino					A = a
457*86d7f5d3SJohn Marino					i = index(alphabet, a)
458*86d7f5d3SJohn Marino					if (i) A = substr(ALPHABET, i, 1)
459*86d7f5d3SJohn Marino					fullname = substr(fullname, 1, abbr-1) A substr($1, 2) substr(fullname, abbr+1)
460*86d7f5d3SJohn Marino				}
461*86d7f5d3SJohn Marino
462*86d7f5d3SJohn Marino				# Quote quotes and backslashes properly in full names.
463*86d7f5d3SJohn Marino				# Do not use gsub; traditional awk lacks it.
464*86d7f5d3SJohn Marino				quoted = ""
465*86d7f5d3SJohn Marino				rest = fullname
466*86d7f5d3SJohn Marino				for (;;) {
467*86d7f5d3SJohn Marino					p = index(rest, "\\")
468*86d7f5d3SJohn Marino					q = index(rest, "\"")
469*86d7f5d3SJohn Marino					if (p) {
470*86d7f5d3SJohn Marino						if (q && q<p) p = q
471*86d7f5d3SJohn Marino					} else {
472*86d7f5d3SJohn Marino						if (!q) break
473*86d7f5d3SJohn Marino						p = q
474*86d7f5d3SJohn Marino					}
475*86d7f5d3SJohn Marino					quoted = quoted substr(rest, 1, p-1) "\\" substr(rest, p, 1)
476*86d7f5d3SJohn Marino					rest = substr(rest, p+1)
477*86d7f5d3SJohn Marino				}
478*86d7f5d3SJohn Marino
479*86d7f5d3SJohn Marino				printf "fullname[\"%s\"] = \"%s%s\"\n", $1, quoted, rest
480*86d7f5d3SJohn Marino				author[$1] = 0
481*86d7f5d3SJohn Marino			}
482*86d7f5d3SJohn Marino		}
483*86d7f5d3SJohn Marino	'
484*86d7f5d3SJohn Marino
485*86d7f5d3SJohn Marino	initialize_fullname=`
486*86d7f5d3SJohn Marino		{
487*86d7f5d3SJohn Marino			(getent passwd $authors) ||
488*86d7f5d3SJohn Marino			(
489*86d7f5d3SJohn Marino				cat /etc/passwd
490*86d7f5d3SJohn Marino				for author in $authors
491*86d7f5d3SJohn Marino				do NIS_PATH= nismatch $author passwd.org_dir
492*86d7f5d3SJohn Marino				done
493*86d7f5d3SJohn Marino				ypmatch $authors passwd
494*86d7f5d3SJohn Marino			)
495*86d7f5d3SJohn Marino		} 2>/dev/null |
496*86d7f5d3SJohn Marino		$AWK -F: "$awkscript"
497*86d7f5d3SJohn Marino	`$initialize_fullname;;
498*86d7f5d3SJohn Marinoesac
499*86d7f5d3SJohn Marino
500*86d7f5d3SJohn Marino
501*86d7f5d3SJohn Marino# Function to print a single log line.
502*86d7f5d3SJohn Marino# We don't use awk functions, to stay compatible with old awk versions.
503*86d7f5d3SJohn Marino# `Log' is the log message.
504*86d7f5d3SJohn Marino# `files' contains the affected files.
505*86d7f5d3SJohn Marinoprintlogline='{
506*86d7f5d3SJohn Marino
507*86d7f5d3SJohn Marino	# Following the GNU coding standards, rewrite
508*86d7f5d3SJohn Marino	#	* file: (function): comment
509*86d7f5d3SJohn Marino	# to
510*86d7f5d3SJohn Marino	#	* file (function): comment
511*86d7f5d3SJohn Marino	if (Log ~ /^\([^)]*\): /) {
512*86d7f5d3SJohn Marino		i = index(Log, ")")
513*86d7f5d3SJohn Marino		filefunc = substr(Log, 1, i)
514*86d7f5d3SJohn Marino		while ((j = index(filefunc, "\n"))) {
515*86d7f5d3SJohn Marino			files = files " " substr(filefunc, 1, j-1)
516*86d7f5d3SJohn Marino			filefunc = substr(filefunc, j+1)
517*86d7f5d3SJohn Marino		}
518*86d7f5d3SJohn Marino		files = files " " filefunc
519*86d7f5d3SJohn Marino		Log = substr(Log, i+3)
520*86d7f5d3SJohn Marino	}
521*86d7f5d3SJohn Marino
522*86d7f5d3SJohn Marino	# If "label: comment" is too long, break the line after the ":".
523*86d7f5d3SJohn Marino	sep = " "
524*86d7f5d3SJohn Marino	i = index(Log, "\n")
525*86d7f5d3SJohn Marino	if ('"$length"' <= '"$indent"' + 1 + length(files) + i) sep = "\n" indent_string
526*86d7f5d3SJohn Marino
527*86d7f5d3SJohn Marino	# Print the label.
528*86d7f5d3SJohn Marino	printf "%s*%s:", indent_string, files
529*86d7f5d3SJohn Marino
530*86d7f5d3SJohn Marino	# Print each line of the log.
531*86d7f5d3SJohn Marino	while (i) {
532*86d7f5d3SJohn Marino		logline = substr(Log, 1, i-1)
533*86d7f5d3SJohn Marino		if (logline ~ /[^'"$tab"' ]/) {
534*86d7f5d3SJohn Marino			printf "%s%s\n", sep, logline
535*86d7f5d3SJohn Marino		} else {
536*86d7f5d3SJohn Marino			print ""
537*86d7f5d3SJohn Marino		}
538*86d7f5d3SJohn Marino		sep = indent_string
539*86d7f5d3SJohn Marino		Log = substr(Log, i+1)
540*86d7f5d3SJohn Marino		i = index(Log, "\n")
541*86d7f5d3SJohn Marino	}
542*86d7f5d3SJohn Marino}'
543*86d7f5d3SJohn Marino
544*86d7f5d3SJohn Marino# Pattern to match the `revision' line of rlog output.
545*86d7f5d3SJohn Marinorlog_revision_pattern='^revision [0-9]+\.[0-9]+(\.[0-9]+\.[0-9]+)*(['"$tab"' ]+locked by: [^'"$tab"' $,.0-9:;@]*[^'"$tab"' $,:;@][^'"$tab"' $,.0-9:;@]*;)?['"$tab"' ]*$'
546*86d7f5d3SJohn Marino
547*86d7f5d3SJohn Marinocase $hostname in
548*86d7f5d3SJohn Marino'')
549*86d7f5d3SJohn Marino	hostname=`(
550*86d7f5d3SJohn Marino		hostname || uname -n || uuname -l || cat /etc/whoami
551*86d7f5d3SJohn Marino	) 2>/dev/null` || {
552*86d7f5d3SJohn Marino		echo >&2 "$0: cannot deduce hostname"
553*86d7f5d3SJohn Marino		exit 1
554*86d7f5d3SJohn Marino	}
555*86d7f5d3SJohn Marino
556*86d7f5d3SJohn Marino	case $hostname in
557*86d7f5d3SJohn Marino	*.*) ;;
558*86d7f5d3SJohn Marino	*)
559*86d7f5d3SJohn Marino		domainname=`(domainname) 2>/dev/null` &&
560*86d7f5d3SJohn Marino		case $domainname in
561*86d7f5d3SJohn Marino		*.*) hostname=$hostname.$domainname;;
562*86d7f5d3SJohn Marino		esac;;
563*86d7f5d3SJohn Marino	esac;;
564*86d7f5d3SJohn Marinoesac
565*86d7f5d3SJohn Marino
566*86d7f5d3SJohn Marino
567*86d7f5d3SJohn Marino# Process the rlog output, generating ChangeLog style entries.
568*86d7f5d3SJohn Marino
569*86d7f5d3SJohn Marino# First, reformat the rlog output so that each line contains one log entry.
570*86d7f5d3SJohn Marino# Transliterate \n to SOH so that multiline entries fit on a single line.
571*86d7f5d3SJohn Marino# Discard irrelevant rlog output.
572*86d7f5d3SJohn Marino$AWK '
573*86d7f5d3SJohn Marino	BEGIN {
574*86d7f5d3SJohn Marino		pository = "'"$pository"'"
575*86d7f5d3SJohn Marino		SOH="'"$SOH"'"
576*86d7f5d3SJohn Marino	}
577*86d7f5d3SJohn Marino	/^RCS file: / {
578*86d7f5d3SJohn Marino		if (pository != "") {
579*86d7f5d3SJohn Marino			filename = substr($0, 11)
580*86d7f5d3SJohn Marino			if (substr(filename, 1, length(pository)) == pository) {
581*86d7f5d3SJohn Marino				filename = substr(filename, length(pository) + 1)
582*86d7f5d3SJohn Marino			}
583*86d7f5d3SJohn Marino			if (filename ~ /,v$/) {
584*86d7f5d3SJohn Marino				filename = substr(filename, 1, length(filename) - 2)
585*86d7f5d3SJohn Marino			}
586*86d7f5d3SJohn Marino			if (filename ~ /(^|\/)Attic\/[^\/]*$/) {
587*86d7f5d3SJohn Marino				i = length(filename)
588*86d7f5d3SJohn Marino				while (substr(filename, i, 1) != "/") i--
589*86d7f5d3SJohn Marino				filename = substr(filename, 1, i - 6) substr(filename, i + 1)
590*86d7f5d3SJohn Marino			}
591*86d7f5d3SJohn Marino		}
592*86d7f5d3SJohn Marino		rev = "?"
593*86d7f5d3SJohn Marino	}
594*86d7f5d3SJohn Marino	/^Working file: / { if (repository == "") filename = substr($0, 15) }
595*86d7f5d3SJohn Marino	/'"$rlog_revision_pattern"'/, /^(-----------*|===========*)$/ {
596*86d7f5d3SJohn Marino		line = $0
597*86d7f5d3SJohn Marino		if (line ~ /'"$rlog_revision_pattern"'/) {
598*86d7f5d3SJohn Marino			rev = $2
599*86d7f5d3SJohn Marino			next
600*86d7f5d3SJohn Marino		}
601*86d7f5d3SJohn Marino		if (line ~ /^date: [0-9][- +\/0-9:]*;/) {
602*86d7f5d3SJohn Marino			date = $2
603*86d7f5d3SJohn Marino			if (date ~ /\//) {
604*86d7f5d3SJohn Marino				# This is a traditional RCS format date YYYY/MM/DD.
605*86d7f5d3SJohn Marino				# Replace "/"s with "-"s to get ISO format.
606*86d7f5d3SJohn Marino				newdate = ""
607*86d7f5d3SJohn Marino				while ((i = index(date, "/")) != 0) {
608*86d7f5d3SJohn Marino					newdate = newdate substr(date, 1, i-1) "-"
609*86d7f5d3SJohn Marino					date = substr(date, i+1)
610*86d7f5d3SJohn Marino				}
611*86d7f5d3SJohn Marino				date = newdate date
612*86d7f5d3SJohn Marino			}
613*86d7f5d3SJohn Marino			time = substr($3, 1, length($3) - 1)
614*86d7f5d3SJohn Marino			author = substr($5, 1, length($5)-1)
615*86d7f5d3SJohn Marino			printf "%s%s%s%s%s%s%s%s%s%s", filename, SOH, rev, SOH, date, SOH, time, SOH, author, SOH
616*86d7f5d3SJohn Marino			rev = "?"
617*86d7f5d3SJohn Marino			next
618*86d7f5d3SJohn Marino		}
619*86d7f5d3SJohn Marino		if (line ~ /^branches: /) { next }
620*86d7f5d3SJohn Marino		if (line ~ /^(-----------*|===========*)$/) { print ""; next }
621*86d7f5d3SJohn Marino		if (line == "Initial revision" || line ~ /^file .+ was initially added on branch .+\.$/) {
622*86d7f5d3SJohn Marino			line = "New file."
623*86d7f5d3SJohn Marino		}
624*86d7f5d3SJohn Marino		printf "%s%s", line, SOH
625*86d7f5d3SJohn Marino	}
626*86d7f5d3SJohn Marino' <"$rlogfile" |
627*86d7f5d3SJohn Marino
628*86d7f5d3SJohn Marino# Now each line is of the form
629*86d7f5d3SJohn Marino# FILENAME@REVISION@YYYY-MM-DD@HH:MM:SS[+-TIMEZONE]@AUTHOR@LOG
630*86d7f5d3SJohn Marino#	where @ stands for an SOH (octal code 001),
631*86d7f5d3SJohn Marino#	and each line of LOG is terminated by SOH instead of \n.
632*86d7f5d3SJohn Marino# Sort the log entries, first by date+time (in reverse order),
633*86d7f5d3SJohn Marino# then by author, then by log entry, and finally by file name and revision
634*86d7f5d3SJohn Marino# (just in case).
635*86d7f5d3SJohn Marinosort -t"$SOH" +2 -4r +4 +0 |
636*86d7f5d3SJohn Marino
637*86d7f5d3SJohn Marino# Finally, reformat the sorted log entries.
638*86d7f5d3SJohn Marino$AWK -F"$SOH" '
639*86d7f5d3SJohn Marino	BEGIN {
640*86d7f5d3SJohn Marino		logTZ = "'"$logTZ"'"
641*86d7f5d3SJohn Marino		revision = "'"$revision"'"
642*86d7f5d3SJohn Marino
643*86d7f5d3SJohn Marino		# Initialize the fullname and mailaddr associative arrays.
644*86d7f5d3SJohn Marino		'"$initialize_fullname"'
645*86d7f5d3SJohn Marino		'"$initialize_mailaddr"'
646*86d7f5d3SJohn Marino
647*86d7f5d3SJohn Marino		# Initialize indent string.
648*86d7f5d3SJohn Marino		indent_string = ""
649*86d7f5d3SJohn Marino		i = '"$indent"'
650*86d7f5d3SJohn Marino		if (0 < '"$tabwidth"')
651*86d7f5d3SJohn Marino			for (;  '"$tabwidth"' <= i;  i -= '"$tabwidth"')
652*86d7f5d3SJohn Marino				indent_string = indent_string "\t"
653*86d7f5d3SJohn Marino		while (1 <= i--)
654*86d7f5d3SJohn Marino			indent_string = indent_string " "
655*86d7f5d3SJohn Marino	}
656*86d7f5d3SJohn Marino
657*86d7f5d3SJohn Marino	{
658*86d7f5d3SJohn Marino		newlog = ""
659*86d7f5d3SJohn Marino		for (i = 6; i < NF; i++) newlog = newlog $i "\n"
660*86d7f5d3SJohn Marino
661*86d7f5d3SJohn Marino		# Ignore log entries prefixed by "#".
662*86d7f5d3SJohn Marino		if (newlog ~ /^#/) { next }
663*86d7f5d3SJohn Marino
664*86d7f5d3SJohn Marino		if (Log != newlog || date != $3 || author != $5) {
665*86d7f5d3SJohn Marino
666*86d7f5d3SJohn Marino			# The previous log and this log differ.
667*86d7f5d3SJohn Marino
668*86d7f5d3SJohn Marino			# Print the old log.
669*86d7f5d3SJohn Marino			if (date != "") '"$printlogline"'
670*86d7f5d3SJohn Marino
671*86d7f5d3SJohn Marino			# Logs that begin with "{clumpname} " should be grouped together,
672*86d7f5d3SJohn Marino			# and the clumpname should be removed.
673*86d7f5d3SJohn Marino			# Extract the new clumpname from the log header,
674*86d7f5d3SJohn Marino			# and use it to decide whether to output a blank line.
675*86d7f5d3SJohn Marino			newclumpname = ""
676*86d7f5d3SJohn Marino			sep = "\n"
677*86d7f5d3SJohn Marino			if (date == "") sep = ""
678*86d7f5d3SJohn Marino			if (newlog ~ /^\{[^'"$tab"' }]*}['"$tab"' ]/) {
679*86d7f5d3SJohn Marino				i = index(newlog, "}")
680*86d7f5d3SJohn Marino				newclumpname = substr(newlog, 1, i)
681*86d7f5d3SJohn Marino				while (substr(newlog, i+1) ~ /^['"$tab"' ]/) i++
682*86d7f5d3SJohn Marino				newlog = substr(newlog, i+1)
683*86d7f5d3SJohn Marino				if (clumpname == newclumpname) sep = ""
684*86d7f5d3SJohn Marino			}
685*86d7f5d3SJohn Marino			printf sep
686*86d7f5d3SJohn Marino			clumpname = newclumpname
687*86d7f5d3SJohn Marino
688*86d7f5d3SJohn Marino			# Get ready for the next log.
689*86d7f5d3SJohn Marino			Log = newlog
690*86d7f5d3SJohn Marino			if (files != "")
691*86d7f5d3SJohn Marino				for (i in filesknown)
692*86d7f5d3SJohn Marino					filesknown[i] = 0
693*86d7f5d3SJohn Marino			files = ""
694*86d7f5d3SJohn Marino		}
695*86d7f5d3SJohn Marino		if (date != $3  ||  author != $5) {
696*86d7f5d3SJohn Marino			# The previous date+author and this date+author differ.
697*86d7f5d3SJohn Marino			# Print the new one.
698*86d7f5d3SJohn Marino			date = $3
699*86d7f5d3SJohn Marino			time = $4
700*86d7f5d3SJohn Marino			author = $5
701*86d7f5d3SJohn Marino
702*86d7f5d3SJohn Marino			zone = ""
703*86d7f5d3SJohn Marino			if (logTZ && ((i = index(time, "-")) || (i = index(time, "+"))))
704*86d7f5d3SJohn Marino				zone = " " substr(time, i)
705*86d7f5d3SJohn Marino
706*86d7f5d3SJohn Marino			# Print "date[ timezone]  fullname  <email address>".
707*86d7f5d3SJohn Marino			# Get fullname and email address from associative arrays;
708*86d7f5d3SJohn Marino			# default to author and author@hostname if not in arrays.
709*86d7f5d3SJohn Marino			if (fullname[author])
710*86d7f5d3SJohn Marino				auth = fullname[author]
711*86d7f5d3SJohn Marino			else
712*86d7f5d3SJohn Marino				auth = author
713*86d7f5d3SJohn Marino			printf "%s%s  %s  ", date, zone, auth
714*86d7f5d3SJohn Marino			if (mailaddr[author])
715*86d7f5d3SJohn Marino				printf "<%s>\n\n", mailaddr[author]
716*86d7f5d3SJohn Marino			else
717*86d7f5d3SJohn Marino				printf "<%s@%s>\n\n", author, "'"$hostname"'"
718*86d7f5d3SJohn Marino		}
719*86d7f5d3SJohn Marino		if (! filesknown[$1]) {
720*86d7f5d3SJohn Marino			filesknown[$1] = 1
721*86d7f5d3SJohn Marino			if (files == "") files = " " $1
722*86d7f5d3SJohn Marino			else files = files ", " $1
723*86d7f5d3SJohn Marino			if (revision && $2 != "?") files = files " " $2
724*86d7f5d3SJohn Marino		}
725*86d7f5d3SJohn Marino	}
726*86d7f5d3SJohn Marino	END {
727*86d7f5d3SJohn Marino		# Print the last log.
728*86d7f5d3SJohn Marino		if (date != "") {
729*86d7f5d3SJohn Marino			'"$printlogline"'
730*86d7f5d3SJohn Marino			printf "\n"
731*86d7f5d3SJohn Marino		}
732*86d7f5d3SJohn Marino	}
733*86d7f5d3SJohn Marino' &&
734*86d7f5d3SJohn Marino
735*86d7f5d3SJohn Marino
736*86d7f5d3SJohn Marino# Exit successfully.
737*86d7f5d3SJohn Marino
738*86d7f5d3SJohn Marinoexec rm -fr $logdir
739*86d7f5d3SJohn Marino
740*86d7f5d3SJohn Marino# Local Variables:
741*86d7f5d3SJohn Marino# tab-width:4
742*86d7f5d3SJohn Marino# End:
743