]> thyrsus.com Git - comparator.git/commitdiff
There is only one dump function now.
authorEric S. Raymond <esr@thyrsus.com>
Wed, 10 Mar 2004 18:25:25 +0000 (18:25 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Wed, 10 Mar 2004 18:25:25 +0000 (18:25 +0000)
comparator.py
filterator

index bc242a34ece3e927f88278cc9b27cac9626718ae..0faf30939090ecd70ec26c34c9cf3076bce319a0 100644 (file)
@@ -47,16 +47,17 @@ class CommonReport:
             elif tag == "Filtering":
                 self.filtering = value
         # Read file properties
-        self.trees = {}
+        self.trees = []
         while 1:
             line = self.fp.readline()
             if not line or line == '%%\n':
                 break
             (tree, properties) = line.split(":")
-            self.trees[tree] = {}
+            propdict = {}
             for assignment in properties.split(", "):
                 (property, value) = assignment.split("=")
-                self.trees[tree][property.strip()] = int(value)
+                propdict[property.strip()] = int(value)
+            self.trees.append([tree, propdict])
         self.cliques = []
         # Reading the clique data is slow, so we only do it
         # on demand.
@@ -123,58 +124,72 @@ class CommonReport:
                     filtered.append(clique)
                     break
             else:
-                properties = self.trees[file.split("/")[0]]
+                for (treename, properties) in self.trees:
+                    if treename == file.split("/")[0]:
+                        break
                 properties['matches'] -= 1
                 properties['matchlines'] -= end - start + 1
         self.cliques = filtered
         self.matches = len(filtered)
 
-    def metadump(self, fp=sys.stdout, divider="%%\n", fmt=None):
+    def metadump(self, fp=sys.stdout, divider="%%\n", fmt=None, moredict={}):
         "Dump the header in a canonical format."
+        fp.write("Filtering: %s\n" %  self.filtering)
         fp.write("Filter-Program: filterator 1.0\n")
         fp.write("Hash-Method: RXOR\n")
+        fp.write("Matches: %d\n" %  self.matches)
         if self.merge_program:
             fp.write("Merge-Program: %s\n" % self.merge_program)
         fp.write("Normalization: %s\n" % self.normalization)
         fp.write("Shred-Size: %d\n" %  self.shredsize)
-        fp.write("Filtering: %s\n" %  self.filtering)
+        for (key, value) in moredict.items():
+            fp.write("%s: %d\n" %  (key, value))
         fp.write(divider)
-        for tree in self.trees:
-            rep = tree + ":"
-            for (key, value) in self.trees[tree].items():
-                rep += " %s=%s," % (key, value)
+        for (treename, properties) in self.trees:
+            rep = treename + ":"
+            keys = properties.keys()
+            keys.sort()
+            for key in keys:
+                rep += " %s=%s," % (key, properties[key])
             fp.write(rep[:-1] + "\n")
         fp.write(divider)
         if fmt:
             for clique in self.cliques:
-                for (file, start, end) in clique:
-                    fp.write(fmt(file, start, end, self.files[file]))
-                fp.write(divider)
+                fp.write(fmt(clique))
 
     def preen(self):
         "Fix the file properties of this report."
         matches = {}
         matchlines = {}
-        for tree in self.trees:
-            matches[tree] = matchlines[tree] = 0
+        for (treename, dummy) in self.trees:
+            matches[treename] = matchlines[treename] = 0
         for clique in self.cliques:
             firstmatch = {}
-            for tree in self.trees:
-                firstmatch[tree] = 0
+            for (treename, dummy) in self.trees:
+                firstmatch[treename] = 0
             for (file, start, end) in clique:
-                properties = self.trees[file.split("/")[0]]
-                if not tree in firstmatch:
+                for (treename, properties) in self.trees:
+                    if treename == file.split("/")[0]:
+                        break
+                if not treename in firstmatch:
                     properties['matches'] += 1
                     firstmatch[tree] = True 
                 properties['matchlines'] += end - start + 1
         self.matches = len(self.cliques)
 
+    def cliquedump(self, clique):
+        "Dump a clique in a form identical to the input one."
+        rep = ""
+        for (file, start, end) in clique:
+            rep += "%s:%d:%d:%d\n" % (file, start, end, self.files[file])
+        rep += "%%\n"
+        return rep
+
     def dump(self, fp):
         "Dump in SCF-B format."
         self.preen()
         fp.write("#SCF-B 2.0\n")
-        self.metadump(fp=fp, divider="%%\n",
-                      fmt=lambda f,s,e, z: "%s:%d:%d:%d\n" % (f,s,e,z))
+        self.metadump(fp=fp, fmt=self.cliquedump)
 
 # Property flags
 C_CODE         = 0x01
index 65406766fd358550fd7b704aff529544746209f9..9f50dd84d7c72482f9db71ad5aa79e45abdf07df 100755 (executable)
@@ -4,33 +4,17 @@
 #
 import sys, comparator, re
 
-def report_common(state):
-    "Generate a report on common code."
-    print "Filter-Program: filterator 1.0"
-    print "Hash-Method: RXOR"
-    if state.merge_program:
-        print "Merge-Program:", state.merge_program
-    print "Normalization:", state.normalization
-    print "Shred-Size: %d" % state.shredsize
-    if minsize:
-        print "Minimum-Size: %d" % minsize
-    print 75 * '-'
-    for tree in state.trees:
-        rep = tree + ":"
-        for (key, value) in state.trees[tree].items():
-            rep += " %s=%s," % (key, value)
-        sys.stdout.write(rep[:-1] + "\n")
-    print 75 * '-'
-    state.read_matches()
-    for clique in state.cliques:
-        (file, start, end, text) = state.extract_text(clique)
-        if start == 1 and end == state.files[file]:
-            print "%% %s:%d-%d: entire (%d matches)" % \
-                  (file, start, end, len(clique))
-        else:
-            print "%% %s:%d-%d: (%d matches)" % \
-                  (file, start, end, len(clique))
-        sys.stdout.write(text)
+def reporthook(clique):
+    rep = ""
+    (file, start, end, text) = state.extract_text(clique)
+    if start == 1 and end == state.files[file]:
+        rep += "%% %s:%d-%d: entire (%d matches)" % \
+              (file, start, end, len(clique))
+    else:
+        rep += "%% %s:%d-%d: (%d matches)" % \
+              (file, start, end, len(clique))
+        rep += text
+    return rep
 
 if __name__ == '__main__':
     # Main line begins here
@@ -49,7 +33,7 @@ if __name__ == '__main__':
         if opt == '-d':
             dir = val
         elif opt == '-f':
-            filter = val
+            filter = re.compile(val)
         elif opt == '-m':
             minsize = int(val)
         elif opt == '-n':
@@ -58,12 +42,12 @@ if __name__ == '__main__':
     try:
         state = comparator.CommonReport(sys.stdin, dir)
         if minsize:
-            state.filter_by_size(minsize)
+            state.cliquefilter(lambda file,start,end: end-start+1 >= minsize)
         if filter:
-            state.filter_by_filename(re.compile(filter))
+            state.cliquefilter(lambda file, start, end: filter.search(file))
         try:
             if expand:
-                report_common(state)
+                state.metadump(sys.stdout, 75 * '-', reporthook, {"Minimum-Size":minsize})
             else:
                 state.dump(sys.stdout)
         except (KeyboardInterrupt, IOError):