aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorPaul Eggert2001-09-05 23:07:46 +0000
committerPaul Eggert2001-09-05 23:07:46 +0000
commit1bd57c395666fb60cfca4a256d735a276174cf39 (patch)
treeec7baaa2be2609de4148e428635a0cff16810cee /lib-src
parent3b74127de1a11177e910cab532fabb7d491dd157 (diff)
downloademacs-1bd57c395666fb60cfca4a256d735a276174cf39.tar.gz
emacs-1bd57c395666fb60cfca4a256d735a276174cf39.zip
(Help, mainline code): Add new option -L FILE.
(Copyright): Update year. (LANG, LANGUAGE, LC_ALL, LC_COLLATE, LC_CTYPE, LC_MESSAGES, LC_NUMERIC, LC_TIME): New shell vars, to make sure we live in the C locale. (mainline code): Handle nonstandard -u option differently, by transforming it to standard form. Check for "Working file: ", not "Working file:". Allow file names with spaces. (SOH, rlogfile): New shell vars. (rlogout): Remove. Its old functionality is mostly migrated to rlogfile. Append ';;' to the last arm of every case statement, for portability to ancient broken BSD shells. (logins): Fix bug; was not being computed at all, lowering performance. (pository): New var. This fixes some bugs where repositories are remote, or have trailing slashes. (authors): $llogout is never an empty shell var, so don't worry about that possibility. (printlogline, mainline code): Fix bug with SOH's being put into the output.
Diffstat (limited to 'lib-src')
-rwxr-xr-xlib-src/rcs2log445
1 files changed, 245 insertions, 200 deletions
diff --git a/lib-src/rcs2log b/lib-src/rcs2log
index f1bd89dc715..eabd369a9d6 100755
--- a/lib-src/rcs2log
+++ b/lib-src/rcs2log
@@ -18,6 +18,7 @@ Options:
18 -h HOSTNAME Use HOSTNAME in change log entries (default current host). 18 -h HOSTNAME Use HOSTNAME in change log entries (default current host).
19 -i INDENT Indent change log lines by INDENT spaces (default 8). 19 -i INDENT Indent change log lines by INDENT spaces (default 8).
20 -l LENGTH Try to limit log lines to LENGTH characters (default 79). 20 -l LENGTH Try to limit log lines to LENGTH characters (default 79).
21 -L FILE Use rlog-format FILE for source of logs.
21 -R If no FILEs are given and RCS is used, recurse through working directory. 22 -R If no FILEs are given and RCS is used, recurse through working directory.
22 -r OPTION Pass OPTION to subsidiary log command. 23 -r OPTION Pass OPTION to subsidiary log command.
23 -t TABWIDTH Tab stops are every TABWIDTH characters (default 8). 24 -t TABWIDTH Tab stops are every TABWIDTH characters (default 8).
@@ -28,9 +29,9 @@ Options:
28 29
29Report bugs to <bug-gnu-emacs@gnu.org>.' 30Report bugs to <bug-gnu-emacs@gnu.org>.'
30 31
31Id='$Id: rcs2log,v 1.46 2001/01/03 12:04:06 gerd Exp $' 32Id='$Id: rcs2log,v 1.47 2001/07/20 09:05:26 gerd Exp eggert $'
32 33
33# Copyright 1992, 93, 94, 95, 96, 97, 1998, 2001 34# Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 2001
34# Free Software Foundation, Inc. 35# Free Software Foundation, Inc.
35 36
36# This program is free software; you can redistribute it and/or modify 37# This program is free software; you can redistribute it and/or modify
@@ -48,13 +49,29 @@ Id='$Id: rcs2log,v 1.46 2001/01/03 12:04:06 gerd Exp $'
48# Free Software Foundation, Inc., 59 Temple Place - Suite 330, 49# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
49# Boston, MA 02111-1307, USA. 50# Boston, MA 02111-1307, USA.
50 51
51Copyright='Copyright 1998 Free Software Foundation, Inc. 52Copyright='Copyright 2001 Free Software Foundation, Inc.
52This program comes with NO WARRANTY, to the extent permitted by law. 53This program comes with NO WARRANTY, to the extent permitted by law.
53You may redistribute copies of this program 54You may redistribute copies of this program
54under the terms of the GNU General Public License. 55under the terms of the GNU General Public License.
55For more information about these matters, see the files named COPYING. 56For more information about these matters, see the files named COPYING.
56Author: Paul Eggert <eggert@twinsun.com>' 57Author: Paul Eggert <eggert@twinsun.com>'
57 58
59# Use the traditional C locale.
60LANG=C
61LANGUAGE=C
62LC_ALL=C
63LC_COLLATE=C
64LC_CTYPE=C
65LC_MESSAGES=C
66LC_NUMERIC=C
67LC_TIME=C
68export LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE LC_MESSAGES LC_NUMERIC LC_TIME
69
70# These variables each contain a single ASCII character.
71# Unfortunately, there's no portable way of writing these characters
72# in older Unix implementations, other than putting them directly into
73# this text file.
74SOH='' # SOH, octal code 001
58tab=' ' 75tab=' '
59nl=' 76nl='
60' 77'
@@ -75,6 +92,7 @@ logTZ= # time zone for log dates (if empty, use local time)
75recursive= # t if we want recursive rlog 92recursive= # t if we want recursive rlog
76revision= # t if we want revision numbers 93revision= # t if we want revision numbers
77rlog_options= # options to pass to rlog 94rlog_options= # options to pass to rlog
95rlogfile= # log file to read from
78tabwidth=8 # width of horizontal tab 96tabwidth=8 # width of horizontal tab
79 97
80while : 98while :
@@ -84,17 +102,16 @@ do
84 -i) indent=${2?}; shift;; 102 -i) indent=${2?}; shift;;
85 -h) hostname=${2?}; shift;; 103 -h) hostname=${2?}; shift;;
86 -l) length=${2?}; shift;; 104 -l) length=${2?}; shift;;
105 -L) rlogfile=${2?}; shift;;
87 -[nu]) # -n is obsolescent; it is replaced by -u. 106 -[nu]) # -n is obsolescent; it is replaced by -u.
88 case $1 in 107 case $1 in
89 -n) case ${2?}${3?}${4?} in 108 -n) case ${2?}${3?}${4?} in
90 *"$tab"* | *"$nl"*) 109 *"$tab"* | *"$nl"*)
91 echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed" 110 echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed"
92 exit 1 111 exit 1;;
93 esac
94 case $loginFullnameMailaddrs in
95 '') loginFullnameMailaddrs=$2$tab$3$tab$4;;
96 ?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
97 esac 112 esac
113 login=$2
114 lfm=$2$tab$3$tab$4
98 shift; shift; shift;; 115 shift; shift; shift;;
99 -u) 116 -u)
100 # If $2 is not tab-separated, use colon for separator. 117 # If $2 is not tab-separated, use colon for separator.
@@ -105,33 +122,39 @@ do
105 *"$tab"*) 122 *"$tab"*)
106 t=$tab;; 123 t=$tab;;
107 *) 124 *)
108 t=: 125 t=':';;
109 esac 126 esac
110 case $2 in 127 case $2 in
111 *"$t"*"$t"*"$t"*) 128 *"$t"*"$t"*"$t"*)
112 echo >&2 "$0: -u '$2': too many fields" 129 echo >&2 "$0: -u '$2': too many fields"
113 exit 1;; 130 exit 1;;
114 *"$t"*"$t"*) 131 *"$t"*"$t"*)
115 ;; 132 uf="[^$t]*$t" # An unselected field, followed by a separator.
133 sf="\\([^$t]*\\)" # The selected field.
134 login=`expr "X$2" : "X$sf"`
135 lfm="$login$tab"`
136 expr "X$2" : "$uf$sf"
137 `"$tab"`
138 expr "X$2" : "$uf$uf$sf"
139 `;;
116 *) 140 *)
117 echo >&2 "$0: -u '$2': not enough fields" 141 echo >&2 "$0: -u '$2': not enough fields"
118 exit 1 142 exit 1;;
119 esac
120 case $loginFullnameMailaddrs in
121 '') loginFullnameMailaddrs=$2;;
122 ?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
123 esac 143 esac
124 shift 144 shift;;
125 esac 145 esac
126 case $logins in 146 case $logins in
127 '') logins=$login;; 147 '') logins=$login;;
128 ?*) logins=$logins$nl$login 148 ?*) logins=$logins$nl$login;;
129 esac 149 esac
130 ;; 150 case $loginFullnameMailaddrs in
151 '') loginFullnameMailaddrs=$lfm;;
152 ?*) loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$lfm;;
153 esac;;
131 -r) 154 -r)
132 case $rlog_options in 155 case $rlog_options in
133 '') rlog_options=${2?};; 156 '') rlog_options=${2?};;
134 ?*) rlog_options=$rlog_options$nl${2?} 157 ?*) rlog_options=$rlog_options$nl${2?};;
135 esac 158 esac
136 shift;; 159 shift;;
137 -R) recursive=t;; 160 -R) recursive=t;;
@@ -145,9 +168,9 @@ do
145 -*) echo >&2 "Usage: $0 [OPTION]... [FILE ...]$nl$Help" 168 -*) echo >&2 "Usage: $0 [OPTION]... [FILE ...]$nl$Help"
146 case $1 in 169 case $1 in
147 --help) exit 0;; 170 --help) exit 0;;
148 *) exit 1 171 *) exit 1;;
149 esac;; 172 esac;;
150 *) break 173 *) break;;
151 esac 174 esac
152 shift 175 shift
153done 176done
@@ -159,159 +182,176 @@ month_data='
159 m[9]="Oct"; m[10]="Nov"; m[11]="Dec" 182 m[9]="Oct"; m[10]="Nov"; m[11]="Dec"
160' 183'
161 184
185logdir=$TMPDIR/rcs2log$$
186llogout=$logdir/l
187trap exit 1 2 13 15
188trap "rm -fr $logdir 2>/dev/null" 0
189(umask 077 && exec mkdir $logdir) || exit
162 190
163# Put rlog output into $rlogout. 191# If no rlog-format log file is given, generate one into $rlogfile.
164 192case $rlogfile in
165# If no rlog options are given,
166# log the revisions checked in since the first ChangeLog entry.
167# Since ChangeLog is only by date, some of these revisions may be duplicates of
168# what's already in ChangeLog; it's the user's responsibility to remove them.
169case $rlog_options in
170'') 193'')
194 rlogfile=$logdir/r
195
196 # If no rlog options are given,
197 # log the revisions checked in since the first ChangeLog entry.
198 # Since ChangeLog is only by date, some of these revisions may be duplicates of
199 # what's already in ChangeLog; it's the user's responsibility to remove them.
200 case $rlog_options in
201 '')
202 if test -s "$changelog"
203 then
204 e='
205 /^[0-9]+-[0-9][0-9]-[0-9][0-9]/{
206 # ISO 8601 date
207 print $1
208 exit
209 }
210 /^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{
211 # old-fashioned date and time (Emacs 19.31 and earlier)
212 '"$month_data"'
213 year = $5
214 for (i=0; i<=11; i++) if (m[i] == $2) break
215 dd = $3
216 printf "%d-%02d-%02d\n", year, i+1, dd
217 exit
218 }
219 '
220 d=`$AWK "$e" <"$changelog"` || exit
221 case $d in
222 ?*) datearg="-d>$d";;
223 esac
224 fi;;
225 esac
226
227 # Use TZ specified by ChangeLog local variable, if any.
171 if test -s "$changelog" 228 if test -s "$changelog"
172 then 229 then
173 e=' 230 extractTZ='
174 /^[0-9]+-[0-9][0-9]-[0-9][0-9]/{ 231 /^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*"\([^"]*\)".*/{
175 # ISO 8601 date 232 s//\1/; p; q
176 print $1
177 exit
178 } 233 }
179 /^... ... [ 0-9][0-9] [ 0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]+ /{ 234 /^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*t.*/{
180 # old-fashioned date and time (Emacs 19.31 and earlier) 235 s//UTC0/; p; q
181 '"$month_data"'
182 year = $5
183 for (i=0; i<=11; i++) if (m[i] == $2) break
184 dd = $3
185 printf "%d-%02d-%02d\n", year, i+1, dd
186 exit
187 } 236 }
188 ' 237 '
189 d=`$AWK "$e" <"$changelog"` || exit 238 logTZ=`tail "$changelog" | sed -n "$extractTZ"`
190 case $d in 239 case $logTZ in
191 ?*) datearg="-d>$d" 240 ?*) TZ=$logTZ; export TZ;;
192 esac 241 esac
193 fi 242 fi
194esac
195 243
196# Use TZ specified by ChangeLog local variable, if any. 244 # If CVS is in use, examine its repository, not the normal RCS files.
197if test -s "$changelog" 245 if test ! -f CVS/Repository
198then 246 then
199 extractTZ=' 247 rlog=rlog
200 /^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*"\([^"]*\)".*/{ 248 repository=
201 s//\1/; p; q 249 else
202 } 250 rlog='cvs -q log'
203 /^.*change-log-time-zone-rule['"$tab"' ]*:['"$tab"' ]*t.*/{ 251 repository=`sed 1q <CVS/Repository` || exit
204 s//UTC0/; p; q 252 test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit
205 } 253 case $CVSROOT in
206 ' 254 *:/*:/*)
207 logTZ=`tail "$changelog" | sed -n "$extractTZ"` 255 echo >&2 "$0: $CVSROOT: CVSROOT has multiple ':/'s"
208 case $logTZ in 256 exit 1;;
209 ?*) TZ=$logTZ; export TZ 257 *:/*)
210 esac 258 # remote repository
211fi 259 pository=`expr "X$repository" : '.*:\(/.*\)'`;;
212 260 *)
213# If CVS is in use, examine its repository, not the normal RCS files. 261 # local repository
214if test ! -f CVS/Repository 262 case $repository in
215then 263 /*) ;;
216 rlog=rlog 264 *) repository=${CVSROOT?}/$repository;;
217 repository= 265 esac
218else 266 if test ! -d "$repository"
219 rlog='cvs -q log' 267 then
220 repository=`sed 1q <CVS/Repository` || exit 268 echo >&2 "$0: $repository: bad repository (see CVS/Repository)"
221 test ! -f CVS/Root || CVSROOT=`cat <CVS/Root` || exit 269 exit 1
222 case $CVSROOT in 270 fi
223 *:/*) 271 pository=$repository;;
224 # remote repository
225 ;;
226 *)
227 # local repository
228 case $repository in
229 /*) ;;
230 *) repository=${CVSROOT?}/$repository
231 esac 272 esac
232 if test ! -d "$repository"
233 then
234 echo >&2 "$0: $repository: bad repository (see CVS/Repository)"
235 exit 1
236 fi
237 esac
238fi
239 273
240# Use $rlog's -zLT option, if $rlog supports it. 274 # Ensure that $pository ends in exactly one slash.
241case `$rlog -zLT 2>&1` in 275 while :
242*' option'*) ;; 276 do
243*) 277 case $pository in
244 case $rlog_options in 278 *//) pository=`expr "X$pository" : 'X\(.*\)/'`;;
245 '') rlog_options=-zLT;; 279 */) break;;
246 ?*) rlog_options=-zLT$nl$rlog_options 280 *) pository=$pository/; break;;
281 esac
282 done
283
284 fi
285
286 # Use $rlog's -zLT option, if $rlog supports it.
287 case `$rlog -zLT 2>&1` in
288 *' option'*) ;;
289 *)
290 case $rlog_options in
291 '') rlog_options=-zLT;;
292 ?*) rlog_options=-zLT$nl$rlog_options;;
293 esac;;
247 esac 294 esac
248esac
249 295
250# With no arguments, examine all files under the RCS directory. 296 # With no arguments, examine all files under the RCS directory.
251case $# in 297 case $# in
2520) 298 0)
253 case $repository in 299 case $repository in
254 '') 300 '')
255 oldIFS=$IFS 301 oldIFS=$IFS
256 IFS=$nl 302 IFS=$nl
257 case $recursive in 303 case $recursive in
258 t) 304 t)
259 RCSdirs=`find . -name RCS -type d -print` 305 RCSdirs=`find . -name RCS -type d -print`
260 filesFromRCSfiles='s|,v$||; s|/RCS/|/|; s|^\./||' 306 filesFromRCSfiles='s|,v$||; s|/RCS/|/|; s|^\./||'
261 files=` 307 files=`
262 { 308 {
263 case $RCSdirs in 309 case $RCSdirs in
264 ?*) find $RCSdirs \ 310 ?*) find $RCSdirs \
265 -type f \ 311 -type f \
266 ! -name '*_' \ 312 ! -name '*_' \
267 ! -name ',*,' \ 313 ! -name ',*,' \
268 ! -name '.*_' \ 314 ! -name '.*_' \
269 ! -name .rcsfreeze.log \ 315 ! -name .rcsfreeze.log \
270 ! -name .rcsfreeze.ver \ 316 ! -name .rcsfreeze.ver \
271 -print 317 -print;;
318 esac
319 find . -name '*,v' -print
320 } |
321 sort -u |
322 sed "$filesFromRCSfiles"
323 `;;
324 *)
325 files=
326 for file in RCS/.* RCS/* .*,v *,v
327 do
328 case $file in
329 RCS/. | RCS/.. | RCS/,*, | RCS/*_) continue;;
330 RCS/.rcsfreeze.log | RCS/.rcsfreeze.ver) continue;;
331 RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue;;
332 RCS/*,v | RCS/.*,v) ;;
333 RCS/* | RCS/.*) test -f "$file" || continue;;
272 esac 334 esac
273 find . -name '*,v' -print 335 case $files in
274 } | 336 '') files=$file;;
275 sort -u | 337 ?*) files=$files$nl$file;;
276 sed "$filesFromRCSfiles" 338 esac
277 `;; 339 done
278 *)
279 files=
280 for file in RCS/.* RCS/* .*,v *,v
281 do
282 case $file in
283 RCS/. | RCS/.. | RCS/,*, | RCS/*_) continue;;
284 RCS/.rcsfreeze.log | RCS/.rcsfreeze.ver) continue;;
285 RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue;;
286 RCS/*,v | RCS/.*,v) ;;
287 RCS/* | RCS/.*) test -f "$file" || continue
288 esac
289 case $files in 340 case $files in
290 '') files=$file;; 341 '') exit 0;;
291 ?*) files=$files$nl$file 342 esac;;
292 esac
293 done
294 case $files in
295 '') exit 0
296 esac 343 esac
297 esac 344 set x $files
298 set x $files 345 shift
299 shift 346 IFS=$oldIFS;;
300 IFS=$oldIFS 347 esac;;
301 esac 348 esac
302esac
303
304logdir=$TMPDIR/rcs2log$$
305llogout=$logdir/l
306rlogout=$logdir/r
307trap exit 1 2 13 15
308trap "rm -fr $logdir 2>/dev/null" 0
309(umask 077 && exec mkdir $logdir) || exit
310 349
311case $datearg in 350 case $datearg in
312?*) $rlog $rlog_options "$datearg" ${1+"$@"} >$rlogout;; 351 ?*) $rlog $rlog_options "$datearg" ${1+"$@"} >$rlogfile;;
313'') $rlog $rlog_options ${1+"$@"} >$rlogout 352 '') $rlog $rlog_options ${1+"$@"} >$rlogfile;;
314esac || exit 353 esac || exit;;
354esac
315 355
316 356
317# Get the full name of each author the logs mention, and set initialize_fullname 357# Get the full name of each author the logs mention, and set initialize_fullname
@@ -329,17 +369,14 @@ case $loginFullnameMailaddrs in
329 sed 's/["\\]/\\&/g' >$llogout <<EOF || exit 369 sed 's/["\\]/\\&/g' >$llogout <<EOF || exit
330$loginFullnameMailaddrs 370$loginFullnameMailaddrs
331EOF 371EOF
332 loginFullnameMailaddrs=`cat $llogout` 372 loginFullnameMailaddrs=`cat $llogout`;;
333 esac 373 esac
334 374
335 oldIFS=$IFS 375 oldIFS=$IFS
336 IFS=$nl 376 IFS=$nl
337 for loginFullnameMailaddr in $loginFullnameMailaddrs 377 for loginFullnameMailaddr in $loginFullnameMailaddrs
338 do 378 do
339 case $loginFullnameMailaddr in 379 IFS=$tab
340 *"$tab"*) IFS=$tab;;
341 *) IFS=:
342 esac
343 set x $loginFullnameMailaddr 380 set x $loginFullnameMailaddr
344 login=$2 381 login=$2
345 fullname=$3 382 fullname=$3
@@ -349,25 +386,26 @@ EOF
349 initialize_mailaddr="$initialize_mailaddr 386 initialize_mailaddr="$initialize_mailaddr
350 mailaddr[\"$login\"] = \"$mailaddr\"" 387 mailaddr[\"$login\"] = \"$mailaddr\""
351 done 388 done
352 IFS=$oldIFS 389 IFS=$oldIFS;;
353esac 390esac
354 391
355case $llogout in 392case $logins in
356?*) sort -u -o $llogout <<EOF || exit 393?*)
394 sort -u -o $llogout <<EOF
357$logins 395$logins
358EOF 396EOF
359esac 397 ;;
398'')
399 : ;;
400esac >$llogout || exit
401
360output_authors='/^date: / { 402output_authors='/^date: / {
361 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 ~ /^[^;]*;$/) { 403 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 ~ /^[^;]*;$/) {
362 print substr($5, 1, length($5)-1) 404 print substr($5, 1, length($5)-1)
363 } 405 }
364}' 406}'
365authors=` 407authors=`
366 $AWK "$output_authors" <$rlogout | 408 $AWK "$output_authors" <"$rlogfile" | sort -u | comm -23 - $llogout
367 case $llogout in
368 '') sort -u;;
369 ?*) sort -u | comm -23 - $llogout
370 esac
371` 409`
372case $authors in 410case $authors in
373?*) 411?*)
@@ -439,13 +477,13 @@ EOF
439 ) 477 )
440 } 2>/dev/null | 478 } 2>/dev/null |
441 $AWK -F: "$awkscript" 479 $AWK -F: "$awkscript"
442 `$initialize_fullname 480 `$initialize_fullname;;
443esac 481esac
444 482
445 483
446# Function to print a single log line. 484# Function to print a single log line.
447# We don't use awk functions, to stay compatible with old awk versions. 485# We don't use awk functions, to stay compatible with old awk versions.
448# `Log' is the log message (with \n replaced by \001). 486# `Log' is the log message.
449# `files' contains the affected files. 487# `files' contains the affected files.
450printlogline='{ 488printlogline='{
451 489
@@ -455,19 +493,25 @@ printlogline='{
455 # * file (function): comment 493 # * file (function): comment
456 if (Log ~ /^\([^)]*\): /) { 494 if (Log ~ /^\([^)]*\): /) {
457 i = index(Log, ")") 495 i = index(Log, ")")
458 files = files " " substr(Log, 1, i) 496 filefunc = substr(Log, 1, i)
497 while ((j = index(filefunc, "\n"))) {
498 files = files " " substr(filefunc, 1, j-1)
499 filefunc = substr(filefunc, j+1)
500 }
501 files = files " " filefunc
459 Log = substr(Log, i+3) 502 Log = substr(Log, i+3)
460 } 503 }
461 504
462 # If "label: comment" is too long, break the line after the ":". 505 # If "label: comment" is too long, break the line after the ":".
463 sep = " " 506 sep = " "
464 if ('"$length"' <= '"$indent"' + 1 + length(files) + index(Log, SOH)) sep = "\n" indent_string 507 i = index(Log, "\n")
508 if ('"$length"' <= '"$indent"' + 1 + length(files) + i) sep = "\n" indent_string
465 509
466 # Print the label. 510 # Print the label.
467 printf "%s*%s:", indent_string, files 511 printf "%s*%s:", indent_string, files
468 512
469 # Print each line of the log, transliterating \001 to \n. 513 # Print each line of the log.
470 while ((i = index(Log, SOH)) != 0) { 514 while (i) {
471 logline = substr(Log, 1, i-1) 515 logline = substr(Log, 1, i-1)
472 if (logline ~ /[^'"$tab"' ]/) { 516 if (logline ~ /[^'"$tab"' ]/) {
473 printf "%s%s\n", sep, logline 517 printf "%s%s\n", sep, logline
@@ -476,6 +520,7 @@ printlogline='{
476 } 520 }
477 sep = indent_string 521 sep = indent_string
478 Log = substr(Log, i+1) 522 Log = substr(Log, i+1)
523 i = index(Log, "\n")
479 } 524 }
480}' 525}'
481 526
@@ -496,24 +541,27 @@ case $hostname in
496 *) 541 *)
497 domainname=`(domainname) 2>/dev/null` && 542 domainname=`(domainname) 2>/dev/null` &&
498 case $domainname in 543 case $domainname in
499 *.*) hostname=$hostname.$domainname 544 *.*) hostname=$hostname.$domainname;;
500 esac 545 esac;;
501 esac 546 esac;;
502esac 547esac
503 548
504 549
505# Process the rlog output, generating ChangeLog style entries. 550# Process the rlog output, generating ChangeLog style entries.
506 551
507# First, reformat the rlog output so that each line contains one log entry. 552# First, reformat the rlog output so that each line contains one log entry.
508# Transliterate \n to \001 so that multiline entries fit on a single line. 553# Transliterate \n to SOH so that multiline entries fit on a single line.
509# Discard irrelevant rlog output. 554# Discard irrelevant rlog output.
510$AWK <$rlogout ' 555$AWK '
511 BEGIN { repository = "'"$repository"'" } 556 BEGIN {
512 /^RCS file:/ { 557 pository = "'"$pository"'"
513 if (repository != "") { 558 SOH="'"$SOH"'"
514 filename = $3 559 }
515 if (substr(filename, 1, length(repository) + 1) == repository "/") { 560 /^RCS file: / {
516 filename = substr(filename, length(repository) + 2) 561 if (pository != "") {
562 filename = substr($0, 11)
563 if (substr(filename, 1, length(pository)) == pository) {
564 filename = substr(filename, length(pository) + 1)
517 } 565 }
518 if (filename ~ /,v$/) { 566 if (filename ~ /,v$/) {
519 filename = substr(filename, 1, length(filename) - 2) 567 filename = substr(filename, 1, length(filename) - 2)
@@ -526,7 +574,7 @@ $AWK <$rlogout '
526 } 574 }
527 rev = "?" 575 rev = "?"
528 } 576 }
529 /^Working file:/ { if (repository == "") filename = $3 } 577 /^Working file: / { if (repository == "") filename = substr($0, 15) }
530 /'"$rlog_revision_pattern"'/, /^(-----------*|===========*)$/ { 578 /'"$rlog_revision_pattern"'/, /^(-----------*|===========*)$/ {
531 line = $0 579 line = $0
532 if (line ~ /'"$rlog_revision_pattern"'/) { 580 if (line ~ /'"$rlog_revision_pattern"'/) {
@@ -547,7 +595,7 @@ $AWK <$rlogout '
547 } 595 }
548 time = substr($3, 1, length($3) - 1) 596 time = substr($3, 1, length($3) - 1)
549 author = substr($5, 1, length($5)-1) 597 author = substr($5, 1, length($5)-1)
550 printf "%s %s %s %s %s %c", filename, rev, date, time, author, 1 598 printf "%s%s%s%s%s%s%s%s%s%s", filename, SOH, rev, SOH, date, SOH, time, SOH, author, SOH
551 rev = "?" 599 rev = "?"
552 next 600 next
553 } 601 }
@@ -556,29 +604,25 @@ $AWK <$rlogout '
556 if (line == "Initial revision" || line ~ /^file .+ was initially added on branch .+\.$/) { 604 if (line == "Initial revision" || line ~ /^file .+ was initially added on branch .+\.$/) {
557 line = "New file." 605 line = "New file."
558 } 606 }
559 printf "%s%c", line, 1 607 printf "%s%s", line, SOH
560 } 608 }
561' | 609' <"$rlogfile" |
562 610
563# Now each line is of the form 611# Now each line is of the form
564# FILENAME REVISION YYYY-MM-DD HH:MM:SS[+-TIMEZONE] AUTHOR \001LOG 612# FILENAME@REVISION@YYYY-MM-DD@HH:MM:SS[+-TIMEZONE]@AUTHOR@LOG
565# where \001 stands for a carriage return, 613# where @ stands for an SOH (octal code 001),
566# and each line of the log is terminated by \001 instead of \n. 614# and each line of LOG is terminated by SOH instead of \n.
567# Sort the log entries, first by date+time (in reverse order), 615# Sort the log entries, first by date+time (in reverse order),
568# then by author, then by log entry, and finally by file name and revision 616# then by author, then by log entry, and finally by file name and revision
569# (just in case). 617# (just in case).
570sort +2 -4r +4 +0 | 618sort -t"$SOH" +2 -4r +4 +0 |
571 619
572# Finally, reformat the sorted log entries. 620# Finally, reformat the sorted log entries.
573$AWK ' 621$AWK -F"$SOH" '
574 BEGIN { 622 BEGIN {
575 logTZ = "'"$logTZ"'" 623 logTZ = "'"$logTZ"'"
576 revision = "'"$revision"'" 624 revision = "'"$revision"'"
577 625
578 # Some awk variants do not understand "\001", so we have to
579 # put the char directly in the file.
580 SOH="" # <-- There is a single SOH (octal code 001) here.
581
582 # Initialize the fullname and mailaddr associative arrays. 626 # Initialize the fullname and mailaddr associative arrays.
583 '"$initialize_fullname"' 627 '"$initialize_fullname"'
584 '"$initialize_mailaddr"' 628 '"$initialize_mailaddr"'
@@ -594,7 +638,8 @@ $AWK '
594 } 638 }
595 639
596 { 640 {
597 newlog = substr($0, 1 + index($0, SOH)) 641 newlog = ""
642 for (i = 6; i < NF; i++) newlog = newlog $i "\n"
598 643
599 # Ignore log entries prefixed by "#". 644 # Ignore log entries prefixed by "#".
600 if (newlog ~ /^#/) { next } 645 if (newlog ~ /^#/) { next }