From e8e34c2bcec033a2aae4e342ac2b7a0521fd9cba Mon Sep 17 00:00:00 2001 From: "beard%netscape.com" Date: Thu, 4 Nov 1999 06:05:52 +0000 Subject: [PATCH] communicates with cvsblame.cgi to assign blame to lines of a source file. --- gc/boehm/leaksoup/BlameTable.java | 142 ++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100755 gc/boehm/leaksoup/BlameTable.java diff --git a/gc/boehm/leaksoup/BlameTable.java b/gc/boehm/leaksoup/BlameTable.java new file mode 100755 index 000000000000..13f80c540e9a --- /dev/null +++ b/gc/boehm/leaksoup/BlameTable.java @@ -0,0 +1,142 @@ +/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * The contents of this file are subject to the Netscape Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/NPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is Mozilla Communicator client code, released + * March 31, 1998. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * + * Patrick C. Beard + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU Public License (the "GPL"), in which case the + * provisions of the GPL are applicable instead of those above. + * If you wish to allow use of your version of this file only + * under the terms of the GPL and not to allow others to use your + * version of this file under the NPL, indicate your decision by + * deleting the provisions above and replace them with the notice + * and other provisions required by the GPL. If you do not delete + * the provisions above, a recipient may use your version of this + * file under either the NPL or the GPL. + */ + +import java.io.*; +import java.util.*; +import java.net.*; + +class Blame { + String[] lines; + Hashtable info; + + Blame(String[] lines, Hashtable info) { + this.lines = lines; + this.info = info; + } +} + +public class BlameTable { + private Hashtable blameTable = new Hashtable(); + + public String getBlame(String path, int line) { + Blame blame = (Blame) blameTable.get(path); + if (blame == null) { + blame = assignBlame(path); + blameTable.put(path, blame); + } + if (blame != null) { + String[] lines = blame.lines; + if (line > 0 && lines.length > 0 && line <= lines.length) + return (String) blame.info.get(lines[line - 1]); + } + return "error"; + } + + static final String BLAME_BASE = "http://cvs-mirror.mozilla.org/webtools/bonsai/cvsblame.cgi?data=1&file="; + + private static int parseInt(String str) { + int value = 0; + try { + value = Integer.parseInt(str); + } catch (NumberFormatException nfe) { + } + return value; + } + + /** + * Contact bonsai, and get a blame table for each line in a file. + * This information can be compressed, in all likelyhood. + */ + private Blame assignBlame(String path) { + try { + Vector vec = new Vector(); + URL url = new URL(BLAME_BASE + path); + BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream())); + + // read revision for each line of the file. this is really slow. I asked slam to + // use buffered output, to speed this up. + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + if (line.charAt(0) == 'R') + break; + // decompress "revision:count" to simplify getBlame() above. + int colonIndex = line.indexOf(':'); + String revision = line.substring(0, colonIndex); + int count = parseInt(line.substring(colonIndex + 1)); + while (count-- > 0) + vec.addElement(revision); + } + String[] lines = new String[vec.size()]; + vec.copyInto(lines); + vec.removeAllElements(); + + // read revision records, which are of the form "rev|date|who|comment" where comment can span multiple lines, + // and each record is terminated by a "." on its own line. + Hashtable info = new Hashtable(); + String revision = null; + StringBuffer buffer = new StringBuffer(); + for (String line = reader.readLine(); line != null; line = reader.readLine()) { + // we're in one of two states, either we've seen a line starting with a revision, + // and we're waiting for the final ending line, or we're starting a new revision + // record. + if (revision != null) { + if (line.equals(".")) { + // end of current revision record. + info.put(revision, buffer.toString()); + revision = null; + buffer.setLength(0); + } else { + // continuation of a comment + buffer.append(" " + line); + } + } else { + int orIndex = line.indexOf('|'); + if (orIndex >= 0) { + // new revision info record. + revision = line.substring(0, orIndex); + buffer.append(line); + } + } + } + reader.close(); + + return new Blame(lines, info); + } catch (Exception e) { + System.err.println("[error assigning blame for: " + path + "]"); + e.printStackTrace(System.err); + } + return null; + } +}