summaryrefslogtreecommitdiff
path: root/ipl/progs/unclog.icn
diff options
context:
space:
mode:
Diffstat (limited to 'ipl/progs/unclog.icn')
-rw-r--r--ipl/progs/unclog.icn109
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