001: /*
002: * DiffFormatter.java
003: *
004: * Copyright (C) 1998-2003 Peter Graves
005: * $Id: DiffFormatter.java,v 1.6 2003/05/10 15:44:00 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: public final class DiffFormatter extends Formatter {
025: // Formats.
026: private static final int DIFF_FORMAT_TEXT = 0;
027: private static final int DIFF_FORMAT_FILE = 1;
028: private static final int DIFF_FORMAT_HEADER = 2;
029: private static final int DIFF_FORMAT_CONTEXT = 3;
030: private static final int DIFF_FORMAT_INSERTED = 4;
031: private static final int DIFF_FORMAT_DELETED = 5;
032: private static final int DIFF_FORMAT_CHANGED = 6;
033:
034: public static final int DIFF_FORMAT_LAST = 6;
035:
036: public DiffFormatter(Buffer buffer) {
037: this .buffer = buffer;
038: }
039:
040: public LineSegmentList formatLine(Line line) {
041: clearSegmentList();
042: if (line == null || line.length() == 0) {
043: addSegment("", DIFF_FORMAT_TEXT);
044: return segmentList;
045: }
046: final String text = getDetabbedText(line);
047: char c = text.charAt(0);
048: if (c == '+' && !text.startsWith("+++ ")) {
049: // Inserted line.
050: addSegment(text, DIFF_FORMAT_INSERTED);
051: return segmentList;
052: }
053: if (c == '>') {
054: // Inserted line.
055: addSegment(text, DIFF_FORMAT_INSERTED);
056: return segmentList;
057: }
058: if (c == '-' && !text.equals("---") && !text.startsWith("--- ")) {
059: // Deleted line.
060: addSegment(text, DIFF_FORMAT_DELETED);
061: return segmentList;
062: }
063: if (c == '<') {
064: // Deleted line.
065: addSegment(text, DIFF_FORMAT_DELETED);
066: return segmentList;
067: }
068: if (c == '!') {
069: // Changed line (diff -c).
070: addSegment(text, DIFF_FORMAT_CHANGED);
071: return segmentList;
072: }
073: if (c == '?' || text.startsWith("Index: ")) {
074: // File line.
075: addSegment(text, DIFF_FORMAT_FILE);
076: return segmentList;
077: }
078: if (text.startsWith("==== ") && text.endsWith(" ====")) {
079: // File line (p4 diff).
080: addSegment(text, DIFF_FORMAT_FILE);
081: return segmentList;
082: }
083: if (isDiffHeader(text)) {
084: addSegment(text, DIFF_FORMAT_HEADER);
085: return segmentList;
086: }
087: if (c == ' '
088: && buffer instanceof org.armedbear.j.mail.MessageBuffer) {
089: // Diff might be indented.
090: if (isDiffHeader(text.trim())) {
091: addSegment(text, DIFF_FORMAT_HEADER);
092: return segmentList;
093: }
094: int indent = -1;
095: for (Line ln = line.previous(); ln != null; ln = ln
096: .previous()) {
097: String trim = ln.trim();
098: if (trim.startsWith("@@ ") && trim.endsWith(" @@")) {
099: indent = getDetabbedText(ln).indexOf('@');
100: break;
101: }
102: if (trim.startsWith("+++ ")) {
103: indent = getDetabbedText(ln).indexOf('+');
104: break;
105: }
106: }
107: if (indent >= 0) {
108: String s = text.substring(indent);
109: if (s.length() == 0) {
110: addSegment("", DIFF_FORMAT_TEXT);
111: return segmentList;
112: }
113: c = s.charAt(0);
114: if (c == '+' && !s.startsWith("+++ ")) {
115: // Inserted line.
116: addSegment(text, DIFF_FORMAT_INSERTED);
117: return segmentList;
118: }
119: if (c == '-' && !s.startsWith("--- ")) {
120: // Deleted line.
121: addSegment(text, DIFF_FORMAT_DELETED);
122: return segmentList;
123: }
124: if (c == '!') {
125: // Changed line (diff -c).
126: addSegment(s, DIFF_FORMAT_CHANGED);
127: return segmentList;
128: }
129: if (c == '?' || s.startsWith("Index: ")) {
130: // File line.
131: addSegment(text, DIFF_FORMAT_FILE);
132: return segmentList;
133: }
134: if (s.startsWith("==== ") && s.endsWith(" ====")) {
135: // File line (p4 diff).
136: addSegment(text, DIFF_FORMAT_FILE);
137: return segmentList;
138: }
139: }
140: }
141: // Otherwise, assume it's a context line.
142: addSegment(text, DIFF_FORMAT_CONTEXT);
143: return segmentList;
144: }
145:
146: private static boolean isDiffHeader(String s) {
147: if ((s.startsWith("cvs server: ") || s.startsWith("========")
148: || s.startsWith("RCS file: ")
149: || s.startsWith("retrieving revision ")
150: || s.startsWith("diff ") || s.startsWith("*** ")
151: || s.startsWith("--- ") || s.startsWith("+++ ")
152: || (s.startsWith("@@ ") || s.endsWith(" @@")) || (s
153: .startsWith("@ ") && s.endsWith(" @"))))
154: return true;
155: if (s.equals("***************"))
156: return true;
157: if (s.equals("---"))
158: return true;
159: if (s.length() > 0) {
160: char c = s.charAt(0);
161: if (c >= '0' && c <= '9')
162: return true;
163: }
164: return false;
165: }
166:
167: public FormatTable getFormatTable() {
168: if (formatTable == null) {
169: formatTable = new FormatTable("DiffMode");
170: formatTable.addEntryFromPrefs(DIFF_FORMAT_TEXT, "text");
171: formatTable.addEntryFromPrefs(DIFF_FORMAT_FILE, "file",
172: "text");
173: formatTable.addEntryFromPrefs(DIFF_FORMAT_HEADER, "header",
174: "comment");
175: formatTable.addEntryFromPrefs(DIFF_FORMAT_CONTEXT,
176: "context", "text");
177: formatTable.addEntryFromPrefs(DIFF_FORMAT_INSERTED,
178: "inserted", "text");
179: formatTable.addEntryFromPrefs(DIFF_FORMAT_DELETED,
180: "deleted", "text");
181: formatTable.addEntryFromPrefs(DIFF_FORMAT_CHANGED,
182: "changed", "text");
183: }
184: return formatTable;
185: }
186: }
|