From b460d41b47c1d7a9742ea59ca2e4de49fcfc6f22 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Wed, 10 Mar 2004 18:25:25 +0000 Subject: [PATCH] There is only one dump function now. --- comparator.py | 57 ++++++++++++++++++++++++++++++++------------------- filterator | 46 ++++++++++++++--------------------------- 2 files changed, 51 insertions(+), 52 deletions(-) diff --git a/comparator.py b/comparator.py index bc242a3..0faf309 100644 --- a/comparator.py +++ b/comparator.py @@ -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 diff --git a/filterator b/filterator index 6540676..9f50dd8 100755 --- a/filterator +++ b/filterator @@ -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): -- 2.43.0