diff options
Diffstat (limited to 'ipl/progs/unclog.icn')
-rw-r--r-- | ipl/progs/unclog.icn | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/ipl/progs/unclog.icn b/ipl/progs/unclog.icn new file mode 100644 index 0000000..ec7fe41 --- /dev/null +++ b/ipl/progs/unclog.icn @@ -0,0 +1,109 @@ +############################################################################ +# +# File: unclog.icn +# +# Subject: Program to reformat CVS log output +# +# Author: Gregg M. Townsend +# +# Date: May 2, 2005 +# +############################################################################ +# +# This file is in the public domain. +# +############################################################################ +# +# Usage: unclog [-n nnn] [file] +# +# -n nnn maximum number of files to be listed individually +# (default is 50) +# +# Unclog reads the output of "cvs log", as run without arguments in +# a directory maintained by CVS, and reformats it to correlate CVS +# changes that affected multiple files. The log entries are produced +# in chronological order. +# +############################################################################ + +link options + +$define MAXFILES 50 + +procedure main(args) + local opts, maxfiles, f, line, mods, fname, files, text, s + + opts := options(args, "n+") + maxfiles := \opts["n"] | MAXFILES + + if *args = 0 then + f := &input + else + f := open(args[1]) | stop("cannot open ", args[1]) + + mods := table() + + while line := read(f) do line ? { + + # look for "date:" line + if ="Working file: " then # save working file name + fname := tab(0) + ="date: " | next + tab(find("author: ") + 8) | next + tab(upto(';') + 1) | next + + # this is the "date:" line + # save as first part of description + s := tab(1) + s[23+:3] := "" # remove seconds from clock reading + + # read description of modification + while line := read(f) do { + if line ? =("-----------" | "===========") then break + s ||:= "\n" || line + } + + # have reached end of this entry + # add to table, indexed by text + files := mods[s] + if /files then + files := mods[s] := [] + put(files, fname) + } + + # sort mods by timestamp, which is first part of text + mods := sort(mods, 3) + + # output the mods in order, giving affected files first + while text := get(mods) do { + files := get(mods) + if same(text, mods[1]) then { + # this entry differs from the next one only in timestamp details, + # so combine this entry with the next one + every put(mods[2], !files) + } + else { + # this is a unique entry + write() + if *files >= maxfiles then + write("file: [", *files, " files]") + else + every write("file: ", !sort(files)) + write(text) + write() + } + } +end + + + +# same(text1,text2) -- succeed if two mods are "the same", +# meaning that have identical nontrivial log messages + +procedure same(text1, text2) + + if text1 ? find("*** empty log message ***") then + fail + else + return text1[24:0] == text2[24:0] +end |