Author: stsp
Date: Sun Jan 3 22:50:50 2010
New Revision: 895501
URL: http://svn.apache.org/viewvc?rev=895501&view=rev
Log:
Make svn patch correctly handle patch files with arbitrary line endings.
* subversion/include/private/svn_diff_private.h
(svn_patch_t): Remove eol_str field.
(svn_diff__parse_next_patch): Remove EOL_STR parameter.
* subversion/libsvn_client/patch.c
(match_hunk): Read lines from hunks using svn_stream_readline_detect_eol().
(copy_hunk_text): Likewise, and remove the EOL_STR parameter.
(reject_hunk, apply_one_hunk): Update calls to copy_hunk_text().
(apply_textdiffs): Update calls to svn_diff__parse_next_patch().
* subversion/libsvn_diff/parse-diff.c
(parse_next_hunk): Use svn_stream_readline_detect_eol() to read lines from
the patch file.
(svn_diff__parse_next_patch): Likewise, and remove EOL_STR parameter.
* subversion/tests/libsvn_diff/parse-diff-test.c
(test_parse_unidiff): Update calls to svn_diff__parse_next_patch().
Modified:
subversion/trunk/subversion/include/private/svn_diff_private.h
subversion/trunk/subversion/libsvn_client/patch.c
subversion/trunk/subversion/libsvn_diff/parse-diff.c
subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c
Modified: subversion/trunk/subversion/include/private/svn_diff_private.h
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/include/private/svn_diff_private.h?rev=895501&r1=895500&r2=895501&view=diff
==============================================================================
--- subversion/trunk/subversion/include/private/svn_diff_private.h (original)
+++ subversion/trunk/subversion/include/private/svn_diff_private.h Sun Jan 3
22:50:50 2010
@@ -97,23 +97,18 @@
const char *old_filename;
const char *new_filename;
- /* EOL string used in patch file. */
- const char *eol_str;
-
/* An array containing an svn_hunk_t object for each hunk parsed
* from the patch. */
apr_array_header_t *hunks;
} svn_patch_t;
-/* Return the next *PATCH in PATCH_FILE. The patch file is assumed to
- * have consistent EOL-markers as specified in EOL_STR.
+/* Return the next *PATCH in PATCH_FILE.
* If no patch can be found, set *PATCH to NULL.
* Allocate results in RESULT_POOL.
* Use SCRATCH_POOL for all other allocations. */
svn_error_t *
svn_diff__parse_next_patch(svn_patch_t **patch,
apr_file_t *patch_file,
- const char *eol_str,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool);
Modified: subversion/trunk/subversion/libsvn_client/patch.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/patch.c?rev=895501&r1=895500&r2=895501&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/patch.c (original)
+++ subversion/trunk/subversion/libsvn_client/patch.c Sun Jan 3 22:50:50 2010
@@ -445,8 +445,8 @@
{
svn_pool_clear(iterpool);
- SVN_ERR(svn_stream_readline(hunk->original_text, &hunk_line,
- target->patch->eol_str, &hunk_eof,
iterpool));
+ SVN_ERR(svn_stream_readline_detect_eol(hunk->original_text, &hunk_line,
+ NULL, &hunk_eof, iterpool));
SVN_ERR(svn_stream_readline(target->stream, &target_line,
target->eol_str,
&target->eof, iterpool));
if (! hunk_eof && hunk_line->len > 0)
@@ -697,12 +697,10 @@
/* Copy HUNK_TEXT into TARGET, line by line, such that the line filter
* and transformation callbacks set on HUNK_TEXT by the diff parsing
* code in libsvn_diff will trigger. ABSPATH is the absolute path to the
- * file underlying TARGET. Use EOL_STR as EOL indicator when
- * reading from HUNK_TEXT and when writing to TARGET. */
+ * file underlying TARGET. */
static svn_error_t *
copy_hunk_text(svn_stream_t *hunk_text, svn_stream_t *target,
- const char *abspath, const char *eol_str,
- apr_pool_t *scratch_pool)
+ const char *abspath, apr_pool_t *scratch_pool)
{
svn_boolean_t eof;
apr_pool_t *iterpool;
@@ -711,18 +709,20 @@
do
{
svn_stringbuf_t *line;
+ const char *eol_str;
svn_pool_clear(iterpool);
- SVN_ERR(svn_stream_readline(hunk_text, &line, eol_str, &eof, iterpool));
+ SVN_ERR(svn_stream_readline_detect_eol(hunk_text, &line, &eol_str,
+ &eof, iterpool));
if (! eof)
{
if (line->len >= 1)
SVN_ERR(try_stream_write(target, abspath, line->data, line->len,
iterpool));
- /* Add newline. */
- SVN_ERR(try_stream_write(target, abspath, eol_str, strlen(eol_str),
- iterpool));
+ if (eol_str)
+ SVN_ERR(try_stream_write(target, abspath, eol_str, strlen(eol_str),
+ iterpool));
}
}
while (! eof);
@@ -746,8 +746,7 @@
SVN_ERR(svn_stream_write(target->reject, hunk_header, &len));
SVN_ERR(copy_hunk_text(hunk->diff_text, target->reject,
- target->reject_path,
- target->patch->eol_str, pool));
+ target->reject_path, pool));
target->had_rejects = TRUE;
return SVN_NO_ERROR;
@@ -796,7 +795,7 @@
/* Copy the patched hunk text into the patched stream. */
SVN_ERR(copy_hunk_text(hunk->modified_text, target->patched,
- target->patched_path, target->patch->eol_str, pool));
+ target->patched_path, pool));
return SVN_NO_ERROR;
}
@@ -1058,8 +1057,8 @@
if (ctx->cancel_func)
SVN_ERR(ctx->cancel_func(ctx->cancel_baton));
- SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, patch_eol_str,
- iterpool, iterpool));
+ SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, iterpool,
+ iterpool));
if (patch)
{
SVN_ERR(apply_one_patch(patch, wc_path, dry_run, ctx, strip_count,
Modified: subversion/trunk/subversion/libsvn_diff/parse-diff.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_diff/parse-diff.c?rev=895501&r1=895500&r2=895501&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_diff/parse-diff.c (original)
+++ subversion/trunk/subversion/libsvn_diff/parse-diff.c Sun Jan 3 22:50:50
2010
@@ -249,8 +249,8 @@
/* Remember the current line's offset, and read the line. */
last_line = pos;
- SVN_ERR(svn_stream_readline(stream, &line, patch->eol_str, &eof,
- iterpool));
+ SVN_ERR(svn_stream_readline_detect_eol(stream, &line, NULL, &eof,
+ iterpool));
/* Lines starting with a backslash are comments, such as
* "\ No newline at end of file". */
@@ -385,7 +385,6 @@
svn_error_t *
svn_diff__parse_next_patch(svn_patch_t **patch,
apr_file_t *patch_file,
- const char *eol_str,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -411,7 +410,6 @@
/* Record what we already know about the patch. */
*patch = apr_pcalloc(result_pool, sizeof(**patch));
(*patch)->patch_file = patch_file;
- (*patch)->eol_str = eol_str;
(*patch)->path = fname;
/* Get a stream to read lines from the patch file.
@@ -429,7 +427,8 @@
svn_pool_clear(iterpool);
/* Read a line from the stream. */
- SVN_ERR(svn_stream_readline(stream, &line, eol_str, &eof, iterpool));
+ SVN_ERR(svn_stream_readline_detect_eol(stream, &line, NULL, &eof,
+ iterpool));
/* See if we have a diff header. */
if (line->len > strlen(indicator) && starts_with(line->data, indicator))
Modified: subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c?rev=895501&r1=895500&r2=895501&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c (original)
+++ subversion/trunk/subversion/tests/libsvn_diff/parse-diff-test.c Sun Jan 3
22:50:50 2010
@@ -89,7 +89,7 @@
/* We have two patches with one hunk each.
* Parse the first patch. */
- SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, NL, pool, pool));
+ SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, pool, pool));
SVN_ERR_ASSERT(patch);
SVN_ERR_ASSERT(! strcmp(patch->old_filename, "A/C/gamma"));
SVN_ERR_ASSERT(! strcmp(patch->new_filename, "A/C/gamma"));
@@ -118,7 +118,7 @@
SVN_ERR_ASSERT(buf->len == 0);
/* Parse the second patch. */
- SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, NL, pool, pool));
+ SVN_ERR(svn_diff__parse_next_patch(&patch, patch_file, pool, pool));
SVN_ERR_ASSERT(patch);
SVN_ERR_ASSERT(! strcmp(patch->old_filename, "A/D/gamma.orig"));
SVN_ERR_ASSERT(! strcmp(patch->new_filename, "A/D/gamma"));