Author: brane
Date: Fri Aug 9 20:50:50 2013
New Revision: 1512490
URL: http://svn.apache.org/r1512490
Log:
Implement a file-based diff utility in JavaHL.
[in subversion/bindings/javahl/src/org/apache/subversion/javahl]
* SVNUtil.java (SVNUtil.FileDiff): New static method.
(SVNUtil.FileMerge): Fix docstring.
* util/DiffLib.java (SVNUtil.FileDiff): Implement.
(SVNUtil.nativeFileDiff): New native wrapper declaration.
(SVNUtil.FileMerge): Tweak implementation.
[in subversion/bindings/javahl/native]
* org_apache_subversion_javahl_util_DiffLib.cpp
(Java_org_apache_subversion_javahl_util_DiffLib_nativeFileDiff):
Native implementation of SVNUtil.FileDiff.
[in subversion/bindings/javahl/tests/org/apache/subversion/javahl]
* UtilTests.java (UtilTests.fileContentsPrefix): Add terminating newline.
(UtilTests.testFileDiff): New test case.
(UtilTests.testFileMerge): Add newlines to file contents and adjust
the expected result.
Modified:
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
Modified:
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp?rev=1512490&r1=1512489&r2=1512490&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp
(original)
+++
subversion/trunk/subversion/bindings/javahl/native/org_apache_subversion_javahl_util_DiffLib.cpp
Fri Aug 9 20:50:50 2013
@@ -36,6 +36,79 @@
#include "svn_diff.h"
JNIEXPORT void JNICALL
+Java_org_apache_subversion_javahl_util_DiffLib_nativeFileDiff(
+ JNIEnv* env, jobject jthis,
+ jstring joriginal_file,
+ jstring jmodified_file,
+
+ jint jignore_space_ordinal,
+ jboolean jignore_eol_style,
+ jboolean jshow_c_function,
+
+ jstring joriginal_header,
+ jstring jmodified_header,
+ jstring jheader_encoding,
+ jstring jrelative_to_dir,
+
+ jobject jresult_stream)
+{
+ JNIEntry(DiffLib, nativeFileDiff);
+
+ // Using a "global" request pool since we don't keep a context with
+ // its own pool around for these functions.
+ SVN::Pool pool;
+
+ Path original(joriginal_file, pool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ SVN_JNI_ERR(original.error_occurred(),);
+
+ Path modified(jmodified_file, pool);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+ SVN_JNI_ERR(modified.error_occurred(),);
+
+ svn_diff_t* diff;
+ svn_diff_file_options_t* diff_options =
+ svn_diff_file_options_create(pool.getPool());
+ diff_options->ignore_space =
+ svn_diff_file_ignore_space_t(jignore_space_ordinal);
+ diff_options->ignore_eol_style = svn_boolean_t(jignore_eol_style);
+ diff_options->show_c_function = svn_boolean_t(jshow_c_function);
+ SVN_JNI_ERR(svn_diff_file_diff_2(&diff,
+ original.c_str(),
+ modified.c_str(),
+ diff_options,
+ pool.getPool()),);
+
+ JNIStringHolder original_header(joriginal_header);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ JNIStringHolder modified_header(jmodified_header);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ JNIStringHolder header_encoding(jheader_encoding);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ JNIStringHolder relative_to_dir(jrelative_to_dir);
+ if (JNIUtil::isJavaExceptionThrown())
+ return;
+
+ OutputStream result_stream(jresult_stream);
+
+ SVN_JNI_ERR(svn_diff_file_output_unified3(
+ result_stream.getStream(pool), diff,
+ original.c_str(), modified.c_str(),
+ original_header.c_str(), modified_header.c_str(),
+ header_encoding.c_str(), relative_to_dir.c_str(),
+ diff_options->show_c_function,
+ pool.getPool()),);
+}
+
+JNIEXPORT void JNICALL
Java_org_apache_subversion_javahl_util_DiffLib_nativeFileMerge(
JNIEnv* env, jobject jthis,
jstring joriginal_file,
Modified:
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java?rev=1512490&r1=1512489&r2=1512490&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
(original)
+++
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/SVNUtil.java
Fri Aug 9 20:50:50 2013
@@ -108,15 +108,58 @@ public class SVNUtil
}
/**
- * Given three versions of a file, base
- * (<code>originalFile</code>), incoming
- * (<code>modifiedFile</code>) and current
+ * Given two versions of a file, base (<code>originalFile</code>)
+ * and current (<code>modifiedFile</code>), show differences between
+ * them in unified diff format.
+ *
+ * @param originalFile The base file version (unmodified)
+ * @param modifiedFile The incoming file version (locally modified)
+ * @param diffOptions Options controlling how files are compared.
+ * May be <code>null</code>.
+ * @param originalHeader The header to display for the base file
+ * in the unidiff index block. If it is <code>null</code>,
+ * the <code>originalFile</code> path and its modification
+ * time will be used instead.
+ * @param modifiedHeader The header to display for the current
+ * file in the unidiff index block. If it is <code>null</code>,
+ * the <code>currentFile</code> path and its modification
+ * time will be used instead.
+ * @param headerEncoding The character encoding of the unidiff headers.
+ * @param relativeToDir If this parameter is not <null>, it must
+ * be the path of a (possibly non-immediate) parent of both
+ * <code>originalFile</code> and <code>modifiedFile</code>.
+ * This path will be stripped from the beginning of those
+ * file names if they are used in the unidiff index header.
+ * @param resultStream The stream that receives the merged output.
+ * @throws ClientException
+ */
+ public static void FileDiff(String originalFile,
+ String modifiedFile,
+ SVNUtil.DiffOptions diffOptions,
+
+ String originalHeader,
+ String modifiedHeader,
+ String headerEncoding,
+ String relativeToDir,
+
+ OutputStream resultStream)
+ throws ClientException
+ {
+ new DiffLib().FileDiff(originalFile, modifiedFile, diffOptions,
+ originalHeader, modifiedHeader, headerEncoding,
+ relativeToDir, resultStream);
+ }
+
+
+ /**
+ * Given three versions of a file, base (<code>originalFile</code>),
+ * incoming (<code>modifiedFile</code>) and current
* (<code>latestFile</code>, produce a merged result, possibly
* displaying conflict markers.
*
* @param originalFile The base file version (common ancestor)
* @param modifiedFile The incoming file version (modified elsewhere)
- * @param latestFile The current file version (modified locally)
+ * @param latestFile The current file version (locally modified)
* @param diffOptions Options controlling how files are compared.
* May be <code>null</code>.
* @param conflictOriginal Optional custom conflict marker for
@@ -128,6 +171,7 @@ public class SVNUtil
* @param conflictSeparator Optional custom conflict separator.
* @param conflictStyle Determines how conflicts are displayed.
* @param resultStream The stream that receives the merged output.
+ * @throws ClientException
*/
public static void FileMerge(String originalFile,
String modifiedFile,
Modified:
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java?rev=1512490&r1=1512489&r2=1512490&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
(original)
+++
subversion/trunk/subversion/bindings/javahl/src/org/apache/subversion/javahl/util/DiffLib.java
Fri Aug 9 20:50:50 2013
@@ -43,6 +43,51 @@ public class DiffLib
NativeResources.loadNativeLibrary();
}
+ /** @see ISVNUtil.FileDiff */
+ public void FileDiff(String originalFile,
+ String modifiedFile,
+ SVNUtil.DiffOptions diffOptions,
+
+ String originalHeader,
+ String modifiedHeader,
+ String headerEncoding,
+ String relativeToDir,
+
+ OutputStream resultStream)
+ throws ClientException
+ {
+ nativeFileDiff(originalFile, modifiedFile,
+
+ // Interpret the diff options
+ (diffOptions == null
+ ? SVNUtil.DiffOptions.IgnoreSpace.none.ordinal()
+ : diffOptions.ignoreSpace.ordinal()),
+ (diffOptions == null ? false
+ : diffOptions.ignoreEolStyle),
+ (diffOptions == null ? false
+ : diffOptions.showCFunction),
+
+ originalHeader, modifiedHeader, headerEncoding,
+ relativeToDir, resultStream);
+ }
+
+ private native
+ void nativeFileDiff(String originalFile,
+ String modifiedFile,
+
+ // Interpreted diff options
+ int ignoreSpace,
+ boolean ignoreEolStyle,
+ boolean showCFunction,
+
+ String originalHeader,
+ String modifiedHeader,
+ String headerEncoding,
+ String relativeToDir,
+
+ OutputStream resultStream)
+ throws ClientException;
+
/** @see ISVNUtil.FileMerge */
public void FileMerge(String originalFile,
String modifiedFile,
@@ -58,9 +103,7 @@ public class DiffLib
OutputStream resultStream)
throws ClientException
{
- nativeFileMerge(originalFile,
- modifiedFile,
- latestFile,
+ nativeFileMerge(originalFile, modifiedFile, latestFile,
// Interpret the diff options
(diffOptions == null
@@ -71,9 +114,7 @@ public class DiffLib
(diffOptions == null ? false
: diffOptions.showCFunction),
- conflictOriginal,
- conflictModified,
- conflictLatest,
+ conflictOriginal, conflictModified, conflictLatest,
conflistSeparator,
// Interpret the conflict style
Modified:
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java?rev=1512490&r1=1512489&r2=1512490&view=diff
==============================================================================
---
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
(original)
+++
subversion/trunk/subversion/bindings/javahl/tests/org/apache/subversion/javahl/UtilTests.java
Fri Aug 9 20:50:50 2013
@@ -64,7 +64,7 @@ public class UtilTests extends SVNTests
}
}
- private final byte[] fileContentsPrefix = "1\n2\n3\n4".getBytes();
+ private final byte[] fileContentsPrefix = "1\n2\n3\n4\n".getBytes();
private final byte[] fileContentsSuffix = "N-3\nN-2\nN-1\nN\n".getBytes();
private void writeFileContents(File file, String contents) throws Throwable
@@ -76,15 +76,39 @@ public class UtilTests extends SVNTests
out.close();
}
+ public void testFileDiff() throws Throwable
+ {
+ File original = File.createTempFile("merge", ".original", localTmp);
+ File modified = File.createTempFile("merge", ".modified", localTmp);
+
+ writeFileContents(original, "\noriginal\n\n");
+ writeFileContents(modified, "\nmodified\n\n");
+
+ ByteArrayOutputStream result = new ByteArrayOutputStream();
+ SVNUtil.FileDiff(original.getAbsolutePath(),
+ modified.getAbsolutePath(),
+ null, "original", "modified", "UTF-8", null,
+ result);
+
+ final byte[] expected = ("--- original\n" +
+ "+++ modified\n" +
+ "@@ -3,7 +3,7 @@\n" +
+ " 3\n 4\n \n" +
+ "-original\n" +
+ "+modified\n" +
+ " \n N-3\n N-2\n").getBytes();
+ Assert.assertArrayEquals(expected, result.toByteArray());
+ }
+
public void testFileMerge() throws Throwable
{
File original = File.createTempFile("merge", ".original", localTmp);
File modified = File.createTempFile("merge", ".modified", localTmp);
File latest = File.createTempFile("merge", ".latest", localTmp);
- writeFileContents(original, "\noriginal\n");
- writeFileContents(modified, "\nmodified\n");
- writeFileContents(latest, "\nlatest\n");
+ writeFileContents(original, "\noriginal\n\n");
+ writeFileContents(modified, "\nmodified\n\n");
+ writeFileContents(latest, "\nlatest\n\n");
ByteArrayOutputStream result = new ByteArrayOutputStream();
SVNUtil.FileMerge(original.getAbsolutePath(),
@@ -98,14 +122,14 @@ public class UtilTests extends SVNTests
SVNUtil.ConflictDisplayStyle.modified_original_latest,
result);
- final byte[] expected = ("1\n2\n3\n4\n" +
+ final byte[] expected = ("1\n2\n3\n4\n\n" +
"<<<<<<< branch\n" +
"modified\n" +
"||||||| base\n" +
"original\n" +
"=======\n" +
"latest\n" +
- ">>>>>>> local\n" +
+ ">>>>>>> local\n\n" +
"N-3\nN-2\nN-1\nN\n").getBytes();
Assert.assertArrayEquals(expected, result.toByteArray());
}