001: /*
002: Copyright 2001 Nicholas Allen (nallen@freenet.co.uk)
003: This file is part of JavaCVS.
004: JavaCVS is free software; you can redistribute it and/or modify
005: it under the terms of the GNU General Public License as published by
006: the Free Software Foundation; either version 2 of the License, or
007: (at your option) any later version.
008: JavaCVS is distributed in the hope that it will be useful,
009: but WITHOUT ANY WARRANTY; without even the implied warranty of
010: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
011: GNU General Public License for more details.
012: You should have received a copy of the GNU General Public License
013: along with JavaCVS; if not, write to the Free Software
014: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
015: */
016: package allensoft.diff;
017:
018: import java.io.BufferedReader;
019: import java.io.FileReader;
020: import java.io.IOException;
021: import java.io.Reader;
022:
023: /**
024: * DOCUMENT ME!
025: *
026: * @author $author$
027: */
028: public class UnixDiffParser implements DiffParser {
029: private BufferedReader m_Differences;
030: private String encoding;
031:
032: /**
033: * Creates a new UnixDiffParser object.
034: *
035: * @param differences DOCUMENT ME!
036: */
037: public UnixDiffParser(Reader differences, String encoding) {
038: m_Differences = new BufferedReader(differences);
039: this .encoding = encoding;
040: }
041:
042: /**
043: * DOCUMENT ME!
044: *
045: * @return DOCUMENT ME!
046: *
047: * @throws DiffException DOCUMENT ME!
048: */
049: public Difference getNextDifference() throws DiffException {
050: StringBuffer buffer = new StringBuffer(500);
051:
052: try {
053: mainLoop: while (true) {
054: String sLine = m_Differences.readLine();
055:
056: System.out.println("Difference \"" + sLine + "\"");
057:
058: if (sLine == null)
059: break;
060:
061: // Check if this line could potentially be the start of a difference
062: if ((sLine.length() > 2)
063: && Character.isDigit(sLine.charAt(0))) {
064: int nStartLineInFile1 = -1;
065: int nEndLineInFile1 = -1;
066: int nStartLineInFile2 = -1;
067: int nEndLineInFile2 = -1;
068: int i;
069: char cDiffType;
070: char c = 0;
071:
072: // Scan to first ',' or a, c, or d character.
073: for (i = 1; i < sLine.length(); i++) {
074: c = sLine.charAt(i);
075:
076: if (Character.isDigit(c))
077: continue;
078:
079: else if ((c == ',') || (c == 'a') || (c == 'd')
080: || (c == 'c'))
081: break;
082:
083: // Unrecognized char so ignore this line and process next one
084: else
085:
086: continue mainLoop;
087: }
088:
089: nStartLineInFile1 = Integer.parseInt(sLine
090: .substring(0, i));
091:
092: // Successfully parsed first line number
093: // Check for second line number
094: if (c == ',') {
095: int nStartN2 = i + 1;
096:
097: for (i = nStartN2 + 1; i < sLine.length(); i++) {
098: c = sLine.charAt(i);
099:
100: if (Character.isDigit(c))
101: continue;
102:
103: else if ((c == 'a') || (c == 'd')
104: || (c == 'c'))
105: break;
106:
107: else
108:
109: continue mainLoop;
110: }
111:
112: nEndLineInFile1 = Integer.parseInt(sLine
113: .substring(nStartN2, i));
114: }
115:
116: // Remember the type of difference
117: cDiffType = c;
118:
119: int nStartN3 = i + 1;
120:
121: for (i = nStartN3 + 1; i < sLine.length(); i++) {
122: c = sLine.charAt(i);
123:
124: if (Character.isDigit(c))
125: continue;
126:
127: else if (c == ',')
128: break;
129:
130: else
131:
132: continue mainLoop;
133: }
134:
135: nStartLineInFile2 = Integer.parseInt(sLine
136: .substring(nStartN3, i));
137:
138: if (c == ',') {
139: int nStartN4 = i + 1;
140:
141: for (i = nStartN4 + 1; i < sLine.length(); i++) {
142: c = sLine.charAt(i);
143:
144: if (Character.isDigit(c))
145: continue;
146:
147: else
148:
149: continue mainLoop;
150: }
151:
152: nEndLineInFile2 = Integer.parseInt(sLine
153: .substring(nStartN4));
154: }
155:
156: if (cDiffType == 'c') // Changed text
157: {
158: if (nEndLineInFile1 == -1)
159: nEndLineInFile1 = nStartLineInFile1;
160:
161: if (nEndLineInFile2 == -1)
162: nEndLineInFile2 = nStartLineInFile2;
163:
164: buffer.setLength(0);
165:
166: // Read lines changed from into buffer (i.e lines starting with '<')
167: for (int j = nStartLineInFile1; j <= nEndLineInFile1; j++) {
168: sLine = m_Differences.readLine();
169: System.out.println("Difference \"" + sLine
170: + "\"");
171:
172: if (sLine == null)
173: break mainLoop;
174:
175: if (sLine.length() <= 1)
176: continue mainLoop;
177:
178: if (sLine.charAt(0) == '<') {
179: if (sLine.length() > 2) {
180: System.out
181: .println("DIFF - APPENDING \""
182: + sLine
183: .substring(2)
184: + "\"");
185: buffer.append(sLine.substring(2));
186: }
187:
188: buffer.append('\n');
189: } else
190:
191: continue mainLoop;
192: }
193:
194: sLine = m_Differences.readLine();
195: System.out.println("Difference \"" + sLine
196: + "\"");
197:
198: if (sLine == null)
199: break mainLoop;
200:
201: if (sLine
202: .startsWith("\\ No newline at end of file")) {
203: buffer.setLength(buffer.length() - 1);
204: sLine = m_Differences.readLine();
205: }
206:
207: if (!sLine.equals("---"))
208: continue mainLoop;
209:
210: String sChangedFrom = buffer.toString();
211:
212: buffer.setLength(0);
213:
214: // Read lines changed to into buffer (i.e lines starting with '>')
215: for (int j = nStartLineInFile2; j <= nEndLineInFile2; j++) {
216: sLine = m_Differences.readLine();
217: System.out.println("Difference \"" + sLine
218: + "\"");
219:
220: if (sLine == null)
221: break mainLoop;
222:
223: if (sLine.length() <= 1)
224: continue mainLoop;
225:
226: if (sLine.charAt(0) == '>') {
227: if (sLine.length() > 2) {
228: System.out
229: .println("DIFF - APPENDING \""
230: + sLine
231: .substring(2)
232: + "\"");
233: buffer.append(sLine.substring(2));
234: }
235:
236: buffer.append('\n');
237: } else
238:
239: continue mainLoop;
240: }
241:
242: String sChangedTo = buffer.toString();
243:
244: return new Change(nStartLineInFile1,
245: nEndLineInFile1, nStartLineInFile2,
246: nEndLineInFile2, sChangedFrom,
247: sChangedTo);
248: } else if (cDiffType == 'a') // Inserted some text
249: {
250: if (nEndLineInFile1 != -1) // Can't be specified for insertion
251:
252: continue mainLoop;
253:
254: if (nEndLineInFile2 == -1)
255: nEndLineInFile2 = nStartLineInFile2;
256:
257: buffer.setLength(0);
258:
259: // Read lines inserted into buffer (i.e lines starting with '>')
260: for (int j = nStartLineInFile2; j <= nEndLineInFile2; j++) {
261: sLine = m_Differences.readLine();
262: System.out.println("Difference \"" + sLine
263: + "\"");
264:
265: if (sLine == null)
266: break mainLoop;
267:
268: if (sLine.length() <= 1)
269: continue mainLoop;
270:
271: if (sLine.charAt(0) == '>') {
272: if (sLine.length() > 2) {
273: System.out
274: .println("DIFF - APPENDING \""
275: + sLine
276: .substring(2)
277: + "\"");
278: buffer.append(sLine.substring(2));
279: }
280:
281: buffer.append('\n');
282: } else
283:
284: continue mainLoop;
285: }
286:
287: String sInsertedText = buffer.toString();
288:
289: return new Insertion(nStartLineInFile1,
290: nStartLineInFile2, nEndLineInFile2,
291: sInsertedText);
292: } else if (cDiffType == 'd') // Deleted some text
293: {
294: if (nEndLineInFile1 == -1)
295: nEndLineInFile1 = nStartLineInFile1;
296:
297: if (nEndLineInFile2 != -1)
298: continue mainLoop;
299:
300: buffer.setLength(0);
301:
302: // Read lines changed from into buffer (i.e lines starting with '<')
303: for (int j = nStartLineInFile1; j <= nEndLineInFile1; j++) {
304: sLine = m_Differences.readLine();
305: System.out.println("Difference \"" + sLine
306: + "\"");
307:
308: if (sLine == null)
309: break mainLoop;
310:
311: if (sLine.length() <= 1)
312: continue mainLoop;
313:
314: if (sLine.charAt(0) == '<') {
315: if (sLine.length() > 2) {
316: System.out
317: .println("DIFF - APPENDING \""
318: + sLine
319: .substring(2)
320: + "\"");
321: buffer.append(sLine.substring(2));
322: }
323:
324: buffer.append('\n');
325: } else
326:
327: continue mainLoop;
328: }
329:
330: String sDeletedText = buffer.toString();
331:
332: return new Deletion(nStartLineInFile1,
333: nEndLineInFile1, nStartLineInFile2,
334: sDeletedText);
335: }
336: }
337: }
338: } catch (IOException e) {
339: throw new DiffException("Error reading differences:", e);
340: }
341:
342: /*finally
343: {
344: try {m_Differences.close();}
345: catch (IOException e) { }
346: }*/
347: return null;
348: }
349: }
|