aboutsummaryrefslogtreecommitdiffstats
path: root/lib-src
diff options
context:
space:
mode:
authorPaul Eggert1995-03-21 05:37:42 +0000
committerPaul Eggert1995-03-21 05:37:42 +0000
commit44ef8c25be36ef55178ddf4b0c9db4272ea6039c (patch)
tree5465a6b1ac3e3d2c21c44b634de9e823b481b632 /lib-src
parentd382f61045e7fdd00dea62e50e2cdfa7df03d869 (diff)
downloademacs-44ef8c25be36ef55178ddf4b0c9db4272ea6039c.tar.gz
emacs-44ef8c25be36ef55178ddf4b0c9db4272ea6039c.zip
Add -u "login<tab>fullname<tab>mailaddr" option, which replaces the
(now obsolescent) -n login fullname mailaddr option. Don't omit path from repository root when logging CVS files. Add -R option for recursive rlog. (AWK): New environment variable (default `awk') for name of awk program. (output_authors, tab, loginFullnameMailaddrs, recursive): New variables. Quote authors and fullnames correctly.
Diffstat (limited to 'lib-src')
-rwxr-xr-xlib-src/rcs2log219
1 files changed, 159 insertions, 60 deletions
diff --git a/lib-src/rcs2log b/lib-src/rcs2log
index 63d366dcf63..5760a41b8c1 100755
--- a/lib-src/rcs2log
+++ b/lib-src/rcs2log
@@ -12,9 +12,9 @@
12 12
13# Author: Paul Eggert <eggert@twinsun.com> 13# Author: Paul Eggert <eggert@twinsun.com>
14 14
15# $Id: rcs2log,v 1.17 1994/08/09 20:43:48 rms Exp eggert $ 15# $Id: rcs2log,v 1.19 1995/03/21 05:11:06 eggert Exp $
16 16
17# Copyright 1992, 1993 Free Software Foundation, Inc. 17# Copyright 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
18 18
19# This program is free software; you can redistribute it and/or modify 19# This program is free software; you can redistribute it and/or modify
20# it under the terms of the GNU General Public License as published by 20# it under the terms of the GNU General Public License as published by
@@ -30,51 +30,69 @@
30# along with this program; see the file COPYING. If not, write to 30# along with this program; see the file COPYING. If not, write to
31# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 31# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
32 32
33tab=' '
33nl=' 34nl='
34' 35'
35 36
36# Parse options. 37# Parse options.
37 38
38# defaults 39# defaults
40: ${AWK=awk}
39: ${TMPDIR=/tmp} 41: ${TMPDIR=/tmp}
40hostname= # name of local host (if empty, will deduce it later) 42hostname= # name of local host (if empty, will deduce it later)
41indent=8 # indent of log line 43indent=8 # indent of log line
42initialize_fullname= # awk assignments to set up fullname array
43initialize_mailaddr= # awk assignments to set up mailaddr array
44length=79 # suggested max width of log line 44length=79 # suggested max width of log line
45logins= # login names for people we know fullnames and mailaddresses of 45logins= # login names for people we know fullnames and mailaddresses of
46loginsout= # temporary file holding sorted logins 46loginFullnameMailaddrs= # login<tab>fullname<tab>mailaddr triplets
47recursive= # t if we want recursive rlog
47rlog_options= # options to pass to rlog 48rlog_options= # options to pass to rlog
48tabwidth=8 # width of horizontal tab 49tabwidth=8 # width of horizontal tab
49 50
50while : 51while :
51do 52do
52 case $1 in 53 case $1 in
53 -i) indent=${2?};; 54 -i) indent=${2?}; shift;;
54 -h) hostname=${2?};; 55 -h) hostname=${2?}; shift;;
55 -l) length=${2?};; 56 -l) length=${2?}; shift;;
56 -n) logins=$logins$nl${2?} 57 -[nu]) # -n is obsolescent; it is replaced by -u.
57 loginsout=$TMPDIR/rcs2log$$l 58 case $1 in
58 case $2${3?}${4?} in 59 -n) case ${2?}${3?}${4?} in
59 *\"* | *\\* | *"$nl"*) 60 *"$tab"* | *"$nl"*)
60 echo >&2 "$0: -n '$2' '$3' '$4': special characters not allowed" 61 echo >&2 "$0: -n '$2' '$3' '$4': tabs, newlines not allowed"
61 exit 1 62 exit 1
63 esac
64 loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2$tab$3$tab$4
65 shift; shift; shift;;
66 -u)
67 case ${2?} in
68 *"$nl"*)
69 echo >&2 "$0: -u '$2': newlines not allowed"
70 exit 1;;
71 *"$tab"*"$tab"*"$tab"*)
72 echo >&2 "$0: -u '$2': too many fields"
73 exit 1;;
74 *"$tab"*"$tab"*)
75 ;;
76 *)
77 echo >&2 "$0: -u '$2': not enough fields"
78 exit 1
79 esac
80 loginFullnameMailaddrs=$loginFullnameMailaddrs$nl$2
81 shift
62 esac 82 esac
63 initialize_fullname="$initialize_fullname 83 logins=$logins$nl$login
64 fullname[\"$2\"] = \"$3\"" 84 ;;
65 initialize_mailaddr="$initialize_mailaddr 85 -r) rlog_options=$rlog_options$nl${2?}; shift;;
66 mailaddr[\"$2\"] = \"$4\"" 86 -R) recursive=t;;
67 shift; shift;; 87 -t) tabwidth=${2?}; shift;;
68 -r) rlog_options=$rlog_options$nl${2?};;
69 -t) tabwidth=${2?};;
70 -*) echo >&2 "$0: usage: $0 [options] [file ...] 88 -*) echo >&2 "$0: usage: $0 [options] [file ...]
71Options: 89Options:
72 [-h hostname] [-i indent] [-l length] [-n login fullname mailaddr]... 90 [-h hostname] [-i indent] [-l length] [-R] [-r rlog_option]
73 [-r rlog_option]... [-t tabwidth]" 91 [-t tabwidth] [-u 'login<TAB>fullname<TAB>mailaddr']..."
74 exit 1;; 92 exit 1;;
75 *) break 93 *) break
76 esac 94 esac
77 shift; shift 95 shift
78done 96done
79 97
80month_data=' 98month_data='
@@ -133,7 +151,7 @@ then
133 exit 151 exit
134 } 152 }
135 ' 153 '
136 d=`awk "$e" <ChangeLog` || exit 154 d=`$AWK "$e" <ChangeLog` || exit
137 case $d in 155 case $d in
138 ?*) date=$d 156 ?*) date=$d
139 esac 157 esac
@@ -160,28 +178,46 @@ case $# in
1600) 1780)
161 case $repository in 179 case $repository in
162 '') 180 '')
163 files=
164 for file in RCS/.* RCS/* .*,v *,v
165 do
166 case $file in
167 RCS/. | RCS/..) continue;;
168 RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue
169 esac
170 files=$files$nl$file
171 done
172 case $files in
173 '') exit 0
174 esac
175 oldIFS=$IFS 181 oldIFS=$IFS
176 IFS=$nl 182 IFS=$nl
177 set $files 183 case $recursive in
184 t)
185 RCSdirs=`find . -name RCS -type d -print`
186 filesFromRCSfiles='s|,v$||; s|/RCS/|/|; s|^\./||'
187 files=`
188 {
189 case $RCSdirs in
190 ?*) find $RCSdirs -type f -print
191 esac
192 find . -name '*,v' -print
193 } |
194 sort -u |
195 sed "$filesFromRCSfiles"
196 `;;
197 *)
198 files=
199 for file in RCS/.* RCS/* .*,v *,v
200 do
201 case $file in
202 RCS/. | RCS/..) continue;;
203 RCS/.\* | RCS/\* | .\*,v | \*,v) test -f "$file" || continue
204 esac
205 files=$files$nl$file
206 done
207 case $files in
208 '') exit 0
209 esac
210 esac
211 set x $files
212 shift
178 IFS=$oldIFS 213 IFS=$oldIFS
179 esac 214 esac
180esac 215esac
181 216
217llogout=$TMPDIR/rcs2log$$l
182rlogout=$TMPDIR/rcs2log$$r 218rlogout=$TMPDIR/rcs2log$$r
183trap exit 1 2 13 15 219trap exit 1 2 13 15
184trap "rm -f $loginsout $rlogout; exit 1" 0 220trap "rm -f $llogout $rlogout; exit 1" 0
185 221
186$rlog "$datearg" $rlog_options ${1+"$@"} >$rlogout || exit 222$rlog "$datearg" $rlog_options ${1+"$@"} >$rlogout || exit
187 223
@@ -191,27 +227,60 @@ $rlog "$datearg" $rlog_options ${1+"$@"} >$rlogout || exit
191# Warning: foreign authors (i.e. not known in the passwd file) are mishandled; 227# Warning: foreign authors (i.e. not known in the passwd file) are mishandled;
192# you have to fix the resulting output by hand. 228# you have to fix the resulting output by hand.
193 229
194case $loginsout in 230initialize_fullname=
195?*) sort -u -o $loginsout <<EOF || exit 231initialize_mailaddr=
232
233case $loginFullnameMailaddrs in
234?*)
235 case $loginFullnameMailaddrs in
236 *\"* | *\\*)
237 sed 's/["\\]/\\&/g' >$llogout <<EOF || exit
238$loginFullnameMailaddrs
239EOF
240 loginFullnameMailaddrs=`cat $llogout`
241 esac
242
243 oldIFS=$IFS
244 IFS=$nl
245 for loginFullnameMailaddr in $loginFullnameMailaddrs
246 do
247 IFS=$tab
248 set x $loginFullnameMailaddr
249 login=$2
250 fullname=$3
251 mailaddr=$4
252 initialize_fullname="$initialize_fullname
253 fullname[\"$login\"] = \"$fullname\""
254 initialize_mailaddr="$initialize_mailaddr
255 mailaddr[\"$login\"] = \"$mailaddr\""
256 done
257 IFS=$oldIFS
258esac
259
260case $llogout in
261?*) sort -u -o $llogout <<EOF || exit
196$logins 262$logins
197EOF 263EOF
198esac 264esac
265output_authors='/^date: / {
266 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 ~ /^[^;]*;$/) {
267 print substr($5, 1, length($5)-1)
268 }
269}'
199authors=` 270authors=`
200 sed -n 's|^date: *[0-9]*[-/][0-9][0-9][-/][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9][-+0-9]*; *author: *\([^; ]*\).*|\1|p' <$rlogout | 271 $AWK "$output_authors" <$rlogout |
201 case $loginsout in 272 case $llogout in
202 '') sort -u;; 273 '') sort -u;;
203 ?*) sort -u | comm -23 - $loginsout 274 ?*) sort -u | comm -23 - $llogout
204 esac 275 esac
205` 276`
206case $authors in 277case $authors in
207?*) 278?*)
208 initialize_author= 279 cat >$llogout <<EOF || exit
209 for author in $authors 280$authors
210 do 281EOF
211 initialize_author="$initialize_author 282 initialize_author_script='s/["\\]/\\&/g; s/.*/author[\"&\"] = 1/'
212 author[\"$author\"] = 1 283 initialize_author=`sed -e "$initialize_author_script" <$llogout`
213 "
214 done
215 awkscript=' 284 awkscript='
216 BEGIN { 285 BEGIN {
217 alphabet = "abcdefghijklmnopqrstuvwxyz" 286 alphabet = "abcdefghijklmnopqrstuvwxyz"
@@ -239,7 +308,25 @@ case $authors in
239 if (i) A = substr(ALPHABET, i, 1) 308 if (i) A = substr(ALPHABET, i, 1)
240 fullname = substr(fullname, 1, abbr-1) A substr($1, 2) substr(fullname, abbr+1) 309 fullname = substr(fullname, 1, abbr-1) A substr($1, 2) substr(fullname, abbr+1)
241 } 310 }
242 printf "fullname[\"%s\"] = \"%s\"\n", $1, fullname 311
312 # Quote quotes and backslashes properly in full names.
313 # Do not use gsub; traditional awk lacks it.
314 quoted = ""
315 rest = fullname
316 for (;;) {
317 p = index(rest, "\\")
318 q = index(rest, "\"")
319 if (p) {
320 if (q && q<p) p = q
321 } else {
322 if (!q) break
323 p = q
324 }
325 quoted = quoted substr(rest, 1, p-1) "\\" substr(rest, p, 1)
326 rest = substr(rest, p+1)
327 }
328
329 printf "fullname[\"%s\"] = \"%s%s\"\n", $1, quoted, rest
243 author[$1] = 0 330 author[$1] = 0
244 } 331 }
245 } 332 }
@@ -247,7 +334,7 @@ case $authors in
247 334
248 initialize_fullname=` 335 initialize_fullname=`
249 (cat /etc/passwd; ypmatch $authors passwd) 2>/dev/null | 336 (cat /etc/passwd; ypmatch $authors passwd) 2>/dev/null |
250 awk -F: "$awkscript" 337 $AWK -F: "$awkscript"
251 `$initialize_fullname 338 `$initialize_fullname
252esac 339esac
253 340
@@ -278,7 +365,7 @@ printlogline='{
278 # Print each line of the log, transliterating \r to \n. 365 # Print each line of the log, transliterating \r to \n.
279 while ((i = index(Log, CR)) != 0) { 366 while ((i = index(Log, CR)) != 0) {
280 logline = substr(Log, 1, i-1) 367 logline = substr(Log, 1, i-1)
281 if (logline ~ /[^ ]/) { 368 if (logline ~ /[^'"$tab"' ]/) {
282 printf "%s%s\n", sep, logline 369 printf "%s%s\n", sep, logline
283 } else { 370 } else {
284 print "" 371 print ""
@@ -304,8 +391,20 @@ esac
304# First, reformat the rlog output so that each line contains one log entry. 391# First, reformat the rlog output so that each line contains one log entry.
305# Transliterate \n to \r so that multiline entries fit on a single line. 392# Transliterate \n to \r so that multiline entries fit on a single line.
306# Discard irrelevant rlog output. 393# Discard irrelevant rlog output.
307awk <$rlogout ' 394$AWK <$rlogout '
308 /^Working file:/ { filename = $3 } 395 BEGIN { repository = "'"$repository"'" }
396 /^RCS file:/ {
397 if (repository != "") {
398 filename = $3
399 if (substr(filename, 1, length(repository) + 1) == repository "/") {
400 filename = substr(filename, length(repository) + 2)
401 }
402 if (filename ~ /,v$/) {
403 filename = substr(filename, 1, length(filename) - 2)
404 }
405 }
406 }
407 /^Working file:/ { if (repository == "") filename = $3 }
309 /^date: /, /^(-----------*|===========*)$/ { 408 /^date: /, /^(-----------*|===========*)$/ {
310 if ($0 ~ /^branches: /) { next } 409 if ($0 ~ /^branches: /) { next }
311 if ($0 ~ /^date: [0-9][- +\/0-9:]*;/) { 410 if ($0 ~ /^date: [0-9][- +\/0-9:]*;/) {
@@ -339,7 +438,7 @@ awk <$rlogout '
339sort +1 -3r +3 +0 | 438sort +1 -3r +3 +0 |
340 439
341# Finally, reformat the sorted log entries. 440# Finally, reformat the sorted log entries.
342awk ' 441$AWK '
343 BEGIN { 442 BEGIN {
344 # Some awks do not understand "\r" or "\013", so we have to 443 # Some awks do not understand "\r" or "\013", so we have to
345 # put a carriage return directly in the file. 444 # put a carriage return directly in the file.
@@ -392,10 +491,10 @@ awk '
392 newclumpname = "" 491 newclumpname = ""
393 sep = "\n" 492 sep = "\n"
394 if (date == "") sep = "" 493 if (date == "") sep = ""
395 if (newlog ~ /^\{[^ }]*}[ ]/) { 494 if (newlog ~ /^\{[^'"$tab"' }]*}['"$tab"' ]/) {
396 i = index(newlog, "}") 495 i = index(newlog, "}")
397 newclumpname = substr(newlog, 1, i) 496 newclumpname = substr(newlog, 1, i)
398 while (substr(newlog, i+1) ~ /^[ ]/) i++ 497 while (substr(newlog, i+1) ~ /^['"$tab"' ]/) i++
399 newlog = substr(newlog, i+1) 498 newlog = substr(newlog, i+1)
400 if (clumpname == newclumpname) sep = "" 499 if (clumpname == newclumpname) sep = ""
401 } 500 }
@@ -459,4 +558,4 @@ awk '
459 558
460# Exit successfully. 559# Exit successfully.
461 560
462exec rm -f $loginsout $rlogout 561exec rm -f $llogout $rlogout