You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2010/07/19 16:01:26 UTC
svn commit: r965488 - /subversion/trunk/subversion/libsvn_client/patch.c
Author: dannas
Date: Mon Jul 19 14:01:26 2010
New Revision: 965488
URL: http://svn.apache.org/viewvc?rev=965488&view=rev
Log:
Create target_content_info_t for storing text related parts of
patch_target_t.
This is a step towards handling properties in the patch code. The idea
is that target_content_info_t should be able to describe any text, be
it from a file or a property. But for now we're only dealing with texts from a
file.
* subversion/libsvn_client/patch.c
(target_content_info): New.
(patch_target_t): Fields related to the text have been moved to the
field 'content_info'
(init_patch_target): Initialize 'content_info'.
(resolve_target_wc_file_info,
read_line,
seek_to_line,
match_hunk,
scan_for_match): Replace 'target->' with 'content_info->' for fields
related to text content.
(match_existing_file): Use 'target->content_info' for accessing the
streams. We still need other fields from the target.
(get_hunk_info): Add 'content_info' parameter. We still need target for
match_existing_file().
(copy_lines_to_target): Add 'content_info' parameter.
(reject_hunk,
apply_hunk): Add 'content_info' parameter. We still need target for
marking a target as having rejects.
(send_patch_notification): Uses content_info->hunks
(apply_one_patch): Pass around target->content_info to the match and
apply/reject functions.
Modified:
subversion/trunk/subversion/libsvn_client/patch.c
Modified: subversion/trunk/subversion/libsvn_client/patch.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_client/patch.c?rev=965488&r1=965487&r2=965488&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_client/patch.c (original)
+++ subversion/trunk/subversion/libsvn_client/patch.c Mon Jul 19 14:01:26 2010
@@ -65,28 +65,7 @@ typedef struct hunk_info_t {
int fuzz;
} hunk_info_t;
-typedef struct patch_target_t {
- /* The patch being applied. */
- const svn_patch_t *patch;
-
- /* The target path as it appeared in the patch file,
- * but in canonicalised form. */
- const char *canon_path_from_patchfile;
-
- /* The target path, relative to the working copy directory the
- * patch is being applied to. A patch strip count applies to this
- * and only this path. This is never NULL. */
- const char *local_relpath;
-
- /* The absolute path of the target on the filesystem.
- * Any symlinks the path from the patch file may contain are resolved.
- * Is not always known, so it may be NULL. */
- char *local_abspath;
-
- /* The target file, read-only, seekable. This is NULL in case the target
- * file did not exist prior to patch application. */
- apr_file_t *file;
-
+typedef struct target_content_info_t {
/* A stream to read lines form the target file. This is NULL in case
* the target file did not exist prior to patch application. */
svn_stream_t *stream;
@@ -98,16 +77,10 @@ typedef struct patch_target_t {
* so EOL transformation and keyword contraction is done transparently. */
svn_stream_t *patched;
- /* Path to the temporary file underlying the result stream. */
- const char *patched_path;
-
/* The reject stream, write-only, not seekable.
* Hunks that are rejected will be written to this stream. */
svn_stream_t *reject;
- /* Path to the temporary file underlying the reject stream. */
- const char *reject_path;
-
/* The line last read from the target file. */
svn_linenum_t current_line;
@@ -127,6 +100,44 @@ typedef struct patch_target_t {
/* An array containing hunk_info_t structures for hunks already matched. */
apr_array_header_t *hunks;
+ /* True if end-of-file was reached while reading from the target. */
+ svn_boolean_t eof;
+
+ /* The keywords of the target. */
+ apr_hash_t *keywords;
+
+ /* The pool the target_info is allocated in. */
+ apr_pool_t *pool;
+} target_content_info_t;
+
+typedef struct patch_target_t {
+ /* The patch being applied. */
+ const svn_patch_t *patch;
+
+ /* The target path as it appeared in the patch file,
+ * but in canonicalised form. */
+ const char *canon_path_from_patchfile;
+
+ /* The target path, relative to the working copy directory the
+ * patch is being applied to. A patch strip count applies to this
+ * and only this path. This is never NULL. */
+ const char *local_relpath;
+
+ /* The absolute path of the target on the filesystem.
+ * Any symlinks the path from the patch file may contain are resolved.
+ * Is not always known, so it may be NULL. */
+ char *local_abspath;
+
+ /* The target file, read-only, seekable. This is NULL in case the target
+ * file did not exist prior to patch application. */
+ apr_file_t *file;
+
+ /* Path to the temporary file underlying the result stream. */
+ const char *patched_path;
+
+ /* Path to the temporary file underlying the reject stream. */
+ const char *reject_path;
+
/* The node kind of the target as found in WC-DB prior
* to patch application. */
svn_node_kind_t db_kind;
@@ -137,9 +148,6 @@ typedef struct patch_target_t {
/* True if the target was locally deleted prior to patching. */
svn_boolean_t locally_deleted;
- /* True if end-of-file was reached while reading from the target. */
- svn_boolean_t eof;
-
/* True if the target had to be skipped for some reason. */
svn_boolean_t skipped;
@@ -167,8 +175,8 @@ typedef struct patch_target_t {
/* True if the target has the executable bit set. */
svn_boolean_t executable;
- /* The keywords of the target. */
- apr_hash_t *keywords;
+ /* All the information that is specifict to the content of the target. */
+ target_content_info_t *content_info;
/* The pool the target is allocated in. */
apr_pool_t *pool;
@@ -254,7 +262,7 @@ resolve_target_wc_file_info(svn_wc_conte
SVN_ERR(svn_wc__node_get_url(&url, wc_ctx,
target->local_abspath,
scratch_pool, scratch_pool));
- SVN_ERR(svn_subst_build_keywords2(&target->keywords,
+ SVN_ERR(svn_subst_build_keywords2(&target->content_info->keywords,
keywords_val->data,
rev_str, url, changed_date,
author, result_pool));
@@ -264,8 +272,8 @@ resolve_target_wc_file_info(svn_wc_conte
APR_HASH_KEY_STRING);
if (eol_style_val)
{
- svn_subst_eol_style_from_value(&target->eol_style,
- &target->eol_str,
+ svn_subst_eol_style_from_value(&target->content_info->eol_style,
+ &target->content_info->eol_str,
eol_style_val->data);
}
@@ -421,16 +429,23 @@ init_patch_target(patch_target_t **patch
apr_pool_t *result_pool, apr_pool_t *scratch_pool)
{
patch_target_t *target;
+ target_content_info_t *content_info;
target = apr_pcalloc(result_pool, sizeof(*target));
+ content_info = apr_pcalloc(result_pool, sizeof(*content_info));
+
+ content_info->current_line = 1;
+ content_info->eol_style = svn_subst_eol_style_none;
+ content_info->lines = apr_array_make(result_pool, 0,
+ sizeof(svn_stream_mark_t *));
+ content_info->hunks = apr_array_make(result_pool, 0, sizeof(hunk_info_t *));
+ content_info->keywords = apr_hash_make(result_pool);
+ content_info->pool = result_pool;
+
+ target->content_info = content_info;
/* All other fields are FALSE or NULL due to apr_pcalloc(). */
target->patch = patch;
- target->current_line = 1;
- target->eol_style = svn_subst_eol_style_none;
- target->lines = apr_array_make(result_pool, 0,
- sizeof(svn_stream_mark_t *));
- target->hunks = apr_array_make(result_pool, 0, sizeof(hunk_info_t *));
target->db_kind = svn_node_none;
target->kind_on_disk = svn_node_none;
target->pool = result_pool;
@@ -453,8 +468,8 @@ init_patch_target(patch_target_t **patch
APR_OS_DEFAULT, result_pool));
/* Create a stream to read from the target. */
- target->stream = svn_stream_from_aprfile2(target->file,
- FALSE, result_pool);
+ content_info->stream = svn_stream_from_aprfile2(target->file,
+ FALSE, result_pool);
/* Also check the file for local mods and the Xbit. */
SVN_ERR(svn_wc_text_modified_p2(&target->local_mods, wc_ctx,
@@ -475,16 +490,16 @@ init_patch_target(patch_target_t **patch
/* Expand keywords in the patched file.
* Repair newlines if svn:eol-style dictates a particular style. */
- repair_eol = (target->eol_style == svn_subst_eol_style_fixed ||
- target->eol_style == svn_subst_eol_style_native);
- target->patched = svn_subst_stream_translated(
- patched_raw, target->eol_str, repair_eol,
- target->keywords, TRUE, result_pool);
+ repair_eol = (content_info->eol_style == svn_subst_eol_style_fixed
+ || content_info->eol_style == svn_subst_eol_style_native);
+ content_info->patched = svn_subst_stream_translated(
+ patched_raw, content_info->eol_str, repair_eol,
+ content_info->keywords, TRUE, result_pool);
/* We'll also need a stream to write rejected hunks to.
* We don't expand keywords, nor normalise line-endings,
* in reject files. */
- SVN_ERR(svn_stream_open_unique(&target->reject,
+ SVN_ERR(svn_stream_open_unique(&content_info->reject,
&target->reject_path, NULL,
remove_tempfiles ?
svn_io_file_del_on_pool_cleanup :
@@ -498,19 +513,19 @@ init_patch_target(patch_target_t **patch
target->canon_path_from_patchfile,
APR_EOL_STR);
len = strlen(diff_header);
- SVN_ERR(svn_stream_write(target->reject, diff_header, &len));
+ SVN_ERR(svn_stream_write(content_info->reject, diff_header, &len));
}
*patch_target = target;
return SVN_NO_ERROR;
}
-/* Read a *LINE from TARGET. If the line has not been read before
- * mark the line in TARGET->LINES. Allocate *LINE in RESULT_POOL.
+/* Read a *LINE from CONTENT_INFO. If the line has not been read before
+ * mark the line in CONTENT_INFO->LINES. Allocate *LINE in RESULT_POOL.
* Do temporary allocations in SCRATCH_POOL.
*/
static svn_error_t *
-read_line(patch_target_t *target,
+read_line(target_content_info_t *content_info,
const char **line,
apr_pool_t *scratch_pool,
apr_pool_t *result_pool)
@@ -518,43 +533,44 @@ read_line(patch_target_t *target,
svn_stringbuf_t *line_raw;
const char *eol_str;
- if (target->eof)
+ if (content_info->eof)
{
*line = "";
return SVN_NO_ERROR;
}
- SVN_ERR_ASSERT(target->current_line <= target->lines->nelts + 1);
- if (target->current_line == target->lines->nelts + 1)
+ SVN_ERR_ASSERT(content_info->current_line <= content_info->lines->nelts + 1);
+ if (content_info->current_line == content_info->lines->nelts + 1)
{
svn_stream_mark_t *mark;
- SVN_ERR(svn_stream_mark(target->stream, &mark, target->pool));
- APR_ARRAY_PUSH(target->lines, svn_stream_mark_t *) = mark;
+ SVN_ERR(svn_stream_mark(content_info->stream, &mark,
+ content_info->pool));
+ APR_ARRAY_PUSH(content_info->lines, svn_stream_mark_t *) = mark;
}
- SVN_ERR(svn_stream_readline_detect_eol(target->stream, &line_raw,
- &eol_str, &target->eof,
+ SVN_ERR(svn_stream_readline_detect_eol(content_info->stream, &line_raw,
+ &eol_str, &content_info->eof,
scratch_pool));
- if (target->eol_style == svn_subst_eol_style_none)
- target->eol_str = eol_str;
+ if (content_info->eol_style == svn_subst_eol_style_none)
+ content_info->eol_str = eol_str;
/* Contract keywords. */
SVN_ERR(svn_subst_translate_cstring2(line_raw->data, line,
NULL, FALSE,
- target->keywords, FALSE,
+ content_info->keywords, FALSE,
result_pool));
- if (! target->eof)
- target->current_line++;
+ if (! content_info->eof)
+ content_info->current_line++;
return SVN_NO_ERROR;
}
-/* Seek to the specified LINE in TARGET.
- * Mark any lines not read before in TARGET->LINES.
+/* Seek to the specified LINE in CONTENT_INFO.
+ * Mark any lines not read before in CONTENT_INFO->LINES.
* Do temporary allocations in SCRATCH_POOL.
*/
static svn_error_t *
-seek_to_line(patch_target_t *target, svn_linenum_t line,
+seek_to_line(target_content_info_t *content_info, svn_linenum_t line,
apr_pool_t *scratch_pool)
{
svn_linenum_t saved_line;
@@ -562,50 +578,50 @@ seek_to_line(patch_target_t *target, svn
SVN_ERR_ASSERT(line > 0);
- if (line == target->current_line)
+ if (line == content_info->current_line)
return SVN_NO_ERROR;
- saved_line = target->current_line;
- saved_eof = target->eof;
+ saved_line = content_info->current_line;
+ saved_eof = content_info->eof;
- if (line <= target->lines->nelts)
+ if (line <= content_info->lines->nelts)
{
svn_stream_mark_t *mark;
- mark = APR_ARRAY_IDX(target->lines, line - 1, svn_stream_mark_t *);
- SVN_ERR(svn_stream_seek(target->stream, mark));
- target->current_line = line;
+ mark = APR_ARRAY_IDX(content_info->lines, line - 1, svn_stream_mark_t *);
+ SVN_ERR(svn_stream_seek(content_info->stream, mark));
+ content_info->current_line = line;
}
else
{
const char *dummy;
apr_pool_t *iterpool = svn_pool_create(scratch_pool);
- while (! target->eof && target->current_line < line)
+ while (! content_info->eof && content_info->current_line < line)
{
svn_pool_clear(iterpool);
- SVN_ERR(read_line(target, &dummy, iterpool, iterpool));
+ SVN_ERR(read_line(content_info, &dummy, iterpool, iterpool));
}
svn_pool_destroy(iterpool);
}
/* After seeking backwards from EOF position clear EOF indicator. */
- if (saved_eof && saved_line > target->current_line)
- target->eof = FALSE;
+ if (saved_eof && saved_line > content_info->current_line)
+ content_info->eof = FALSE;
return SVN_NO_ERROR;
}
/* Indicate in *MATCHED whether the original text of HUNK matches the patch
- * TARGET at its current line. Lines within FUZZ lines of the start or end
- * of HUNK will always match. If IGNORE_WHITESPACE is set, we ignore
+ * CONTENT_INFO at its current line. Lines within FUZZ lines of the start or
+ * end of HUNK will always match. If IGNORE_WHITESPACE is set, we ignore
* whitespace when doing the matching. When this function returns, neither
- * TARGET->CURRENT_LINE nor the file offset in the target file will have
- * changed. If MATCH_MODIFIED is TRUE, match the modified hunk text,
+ * CONTENT_INFO->CURRENT_LINE nor the file offset in the target file will
+ * have changed. If MATCH_MODIFIED is TRUE, match the modified hunk text,
* rather than the original hunk text.
* Do temporary allocations in POOL. */
static svn_error_t *
-match_hunk(svn_boolean_t *matched, patch_target_t *target,
+match_hunk(svn_boolean_t *matched, target_content_info_t *content_info,
const svn_hunk_t *hunk, int fuzz,
svn_boolean_t ignore_whitespace,
svn_boolean_t match_modified, apr_pool_t *pool)
@@ -623,10 +639,10 @@ match_hunk(svn_boolean_t *matched, patch
*matched = FALSE;
- if (target->eof)
+ if (content_info->eof)
return SVN_NO_ERROR;
- saved_line = target->current_line;
+ saved_line = content_info->current_line;
lines_read = 0;
lines_matched = FALSE;
original_length = svn_diff_hunk_get_original_length(hunk);
@@ -656,10 +672,10 @@ match_hunk(svn_boolean_t *matched, patch
SVN_ERR(svn_subst_translate_cstring2(hunk_line->data,
&hunk_line_translated,
NULL, FALSE,
- target->keywords, FALSE,
+ content_info->keywords, FALSE,
iterpool));
lines_read++;
- SVN_ERR(read_line(target, &target_line, iterpool, iterpool));
+ SVN_ERR(read_line(content_info, &target_line, iterpool, iterpool));
if (! hunk_eof)
{
if (lines_read <= fuzz && leading_context > fuzz)
@@ -686,11 +702,11 @@ match_hunk(svn_boolean_t *matched, patch
}
}
}
- while (lines_matched && ! (hunk_eof || target->eof));
+ while (lines_matched && ! (hunk_eof || content_info->eof));
if (hunk_eof)
*matched = lines_matched;
- else if (target->eof)
+ else if (content_info->eof)
{
/* If the target has no newline at end-of-file, we get an EOF
* indication for the target earlier than we do get it for the hunk. */
@@ -711,14 +727,14 @@ match_hunk(svn_boolean_t *matched, patch
else
*matched = FALSE;
}
- SVN_ERR(seek_to_line(target, saved_line, iterpool));
+ SVN_ERR(seek_to_line(content_info, saved_line, iterpool));
svn_pool_destroy(iterpool);
return SVN_NO_ERROR;
}
-/* Scan lines of TARGET for a match of the original text of HUNK,
+/* Scan lines of CONTENT_INFO for a match of the original text of HUNK,
* up to but not including the specified UPPER_LINE. Use fuzz factor FUZZ.
* If UPPER_LINE is zero scan until EOF occurs when reading from TARGET.
* Return the line at which HUNK was matched in *MATCHED_LINE.
@@ -733,7 +749,8 @@ match_hunk(svn_boolean_t *matched, patch
* Call cancel CANCEL_FUNC with baton CANCEL_BATON to trigger cancellation.
* Do all allocations in POOL. */
static svn_error_t *
-scan_for_match(svn_linenum_t *matched_line, patch_target_t *target,
+scan_for_match(svn_linenum_t *matched_line,
+ target_content_info_t *content_info,
const svn_hunk_t *hunk, svn_boolean_t match_first,
svn_linenum_t upper_line, int fuzz,
svn_boolean_t ignore_whitespace,
@@ -745,8 +762,8 @@ scan_for_match(svn_linenum_t *matched_li
*matched_line = 0;
iterpool = svn_pool_create(pool);
- while ((target->current_line < upper_line || upper_line == 0) &&
- ! target->eof)
+ while ((content_info->current_line < upper_line || upper_line == 0) &&
+ ! content_info->eof)
{
svn_boolean_t matched;
int i;
@@ -756,19 +773,19 @@ scan_for_match(svn_linenum_t *matched_li
if (cancel_func)
SVN_ERR((cancel_func)(cancel_baton));
- SVN_ERR(match_hunk(&matched, target, hunk, fuzz, ignore_whitespace,
+ SVN_ERR(match_hunk(&matched, content_info, hunk, fuzz, ignore_whitespace,
match_modified, iterpool));
if (matched)
{
svn_boolean_t taken = FALSE;
/* Don't allow hunks to match at overlapping locations. */
- for (i = 0; i < target->hunks->nelts; i++)
+ for (i = 0; i < content_info->hunks->nelts; i++)
{
const hunk_info_t *hi;
svn_linenum_t length;
- hi = APR_ARRAY_IDX(target->hunks, i, const hunk_info_t *);
+ hi = APR_ARRAY_IDX(content_info->hunks, i, const hunk_info_t *);
if (match_modified)
length = svn_diff_hunk_get_modified_length(hi->hunk);
@@ -776,22 +793,23 @@ scan_for_match(svn_linenum_t *matched_li
length = svn_diff_hunk_get_original_length(hi->hunk);
taken = (! hi->rejected &&
- target->current_line >= hi->matched_line &&
- target->current_line < (hi->matched_line + length));
+ content_info->current_line >= hi->matched_line &&
+ content_info->current_line < (hi->matched_line + length));
if (taken)
break;
}
if (! taken)
{
- *matched_line = target->current_line;
+ *matched_line = content_info->current_line;
if (match_first)
break;
}
}
- if (! target->eof)
- SVN_ERR(seek_to_line(target, target->current_line + 1, iterpool));
+ if (! content_info->eof)
+ SVN_ERR(seek_to_line(content_info, content_info->current_line + 1,
+ iterpool));
}
svn_pool_destroy(iterpool);
@@ -838,11 +856,13 @@ match_existing_file(svn_boolean_t *match
iterpool, iterpool));
/* Contract keywords. */
SVN_ERR(svn_subst_translate_cstring2(line->data, &line_translated,
- NULL, FALSE, target->keywords,
+ NULL, FALSE,
+ target->content_info->keywords,
FALSE, iterpool));
SVN_ERR(svn_subst_translate_cstring2(hunk_line->data,
&hunk_line_translated,
- NULL, FALSE, target->keywords,
+ NULL, FALSE,
+ target->content_info->keywords,
FALSE, iterpool));
lines_matched = ! strcmp(line_translated, hunk_line_translated);
if (eof != hunk_eof)
@@ -861,17 +881,18 @@ match_existing_file(svn_boolean_t *match
return SVN_NO_ERROR;
}
-/* Determine the line at which a HUNK applies to the TARGET file,
- * and return an appropriate hunk_info object in *HI, allocated from
+/* Determine the line at which a HUNK applies to the CONTENT_INFO of TARGET
+ * file, and return an appropriate hunk_info object in *HI, allocated from
* RESULT_POOL. Use fuzz factor FUZZ. Set HI->FUZZ to FUZZ. If no correct
* line can be determined, set HI->REJECTED to TRUE.
* IGNORE_WHITESPACE tells whether whitespace should be considered when
- * matching. When this function returns, neither TARGET->CURRENT_LINE nor
+ * matching. When this function returns, neither CONTENT_INFO->CURRENT_LINE nor
* the file offset in the target file will have changed.
* Call cancel CANCEL_FUNC with baton CANCEL_BATON to trigger cancellation.
* Do temporary allocations in POOL. */
static svn_error_t *
get_hunk_info(hunk_info_t **hi, patch_target_t *target,
+ target_content_info_t *content_info,
const svn_hunk_t *hunk, int fuzz,
svn_boolean_t ignore_whitespace,
svn_cancel_func_t cancel_func, void *cancel_baton,
@@ -915,7 +936,7 @@ get_hunk_info(hunk_info_t **hi, patch_ta
}
else if (original_start > 0 && target->kind_on_disk == svn_node_file)
{
- svn_linenum_t saved_line = target->current_line;
+ svn_linenum_t saved_line = content_info->current_line;
svn_linenum_t modified_start;
/* Check if the hunk is already applied.
@@ -932,8 +953,10 @@ get_hunk_info(hunk_info_t **hi, patch_ta
}
else
{
- SVN_ERR(seek_to_line(target, modified_start, scratch_pool));
- SVN_ERR(scan_for_match(&matched_line, target, hunk, TRUE,
+ SVN_ERR(seek_to_line(content_info, modified_start,
+ scratch_pool));
+ SVN_ERR(scan_for_match(&matched_line, content_info,
+ hunk, TRUE,
modified_start + 1,
fuzz, ignore_whitespace, TRUE,
cancel_func, cancel_baton,
@@ -948,14 +971,14 @@ get_hunk_info(hunk_info_t **hi, patch_ta
{
/* Scan for a match at the line where the hunk thinks it
* should be going. */
- SVN_ERR(seek_to_line(target, original_start, scratch_pool));
- if (target->current_line != original_start)
+ SVN_ERR(seek_to_line(content_info, original_start, scratch_pool));
+ if (content_info->current_line != original_start)
{
/* Seek failed. */
matched_line = 0;
}
else
- SVN_ERR(scan_for_match(&matched_line, target, hunk, TRUE,
+ SVN_ERR(scan_for_match(&matched_line, content_info, hunk, TRUE,
original_start + 1, fuzz,
ignore_whitespace, FALSE,
cancel_func, cancel_baton,
@@ -964,11 +987,11 @@ get_hunk_info(hunk_info_t **hi, patch_ta
if (matched_line != original_start)
{
/* Scan the whole file again from the start. */
- SVN_ERR(seek_to_line(target, 1, scratch_pool));
+ SVN_ERR(seek_to_line(content_info, 1, scratch_pool));
/* Scan forward towards the hunk's line and look for a line
* where the hunk matches. */
- SVN_ERR(scan_for_match(&matched_line, target, hunk, FALSE,
+ SVN_ERR(scan_for_match(&matched_line, content_info, hunk, FALSE,
original_start, fuzz,
ignore_whitespace, FALSE,
cancel_func, cancel_baton,
@@ -980,15 +1003,15 @@ get_hunk_info(hunk_info_t **hi, patch_ta
{
/* Scan forward towards the end of the file and look
* for a line where the hunk matches. */
- SVN_ERR(scan_for_match(&matched_line, target, hunk, TRUE, 0,
- fuzz, ignore_whitespace, FALSE,
- cancel_func, cancel_baton,
+ SVN_ERR(scan_for_match(&matched_line, content_info, hunk,
+ TRUE, 0, fuzz, ignore_whitespace,
+ FALSE, cancel_func, cancel_baton,
scratch_pool));
}
}
}
- SVN_ERR(seek_to_line(target, saved_line, scratch_pool));
+ SVN_ERR(seek_to_line(content_info, saved_line, scratch_pool));
}
else
{
@@ -1030,23 +1053,25 @@ try_stream_write(svn_stream_t *stream, c
* If LINE is zero, copy lines until end-of-file has been reached.
* Do all allocations in POOL. */
static svn_error_t *
-copy_lines_to_target(patch_target_t *target, svn_linenum_t line,
- apr_pool_t *pool)
+copy_lines_to_target(target_content_info_t *content_info, svn_linenum_t line,
+ const char *patched_path, apr_pool_t *pool)
{
apr_pool_t *iterpool;
iterpool = svn_pool_create(pool);
- while ((target->current_line < line || line == 0) && ! target->eof)
+ while ((content_info->current_line < line || line == 0)
+ && ! content_info->eof)
{
const char *target_line;
svn_pool_clear(iterpool);
- SVN_ERR(read_line(target, &target_line, iterpool, iterpool));
- if (! target->eof)
- target_line = apr_pstrcat(iterpool, target_line, target->eol_str, NULL);
+ SVN_ERR(read_line(content_info, &target_line, iterpool, iterpool));
+ if (! content_info->eof)
+ target_line = apr_pstrcat(iterpool, target_line, content_info->eol_str,
+ NULL);
- SVN_ERR(try_stream_write(target->patched, target->patched_path,
+ SVN_ERR(try_stream_write(content_info->patched, patched_path,
target_line, strlen(target_line), iterpool));
}
svn_pool_destroy(iterpool);
@@ -1055,10 +1080,11 @@ copy_lines_to_target(patch_target_t *tar
}
/* Write the diff text of the hunk described by HI to the
- * reject stream of TARGET, and mark TARGET as having had rejects.
+ * reject stream of CONTENT_INFO, and mark TARGET as having had rejects.
* Do temporary allocations in POOL. */
static svn_error_t *
-reject_hunk(patch_target_t *target, hunk_info_t *hi, apr_pool_t *pool)
+reject_hunk(patch_target_t *target, target_content_info_t *content_info,
+ hunk_info_t *hi, apr_pool_t *pool)
{
const char *hunk_header;
apr_size_t len;
@@ -1072,7 +1098,7 @@ reject_hunk(patch_target_t *target, hunk
svn_diff_hunk_get_modified_length(hi->hunk),
APR_EOL_STR);
len = strlen(hunk_header);
- SVN_ERR(svn_stream_write(target->reject, hunk_header, &len));
+ SVN_ERR(svn_stream_write(content_info->reject, hunk_header, &len));
iterpool = svn_pool_create(pool);
do
@@ -1087,11 +1113,11 @@ reject_hunk(patch_target_t *target, hunk
if (! eof)
{
if (hunk_line->len >= 1)
- SVN_ERR(try_stream_write(target->reject, target->reject_path,
+ SVN_ERR(try_stream_write(content_info->reject, target->reject_path,
hunk_line->data, hunk_line->len,
iterpool));
if (eol_str)
- SVN_ERR(try_stream_write(target->reject, target->reject_path,
+ SVN_ERR(try_stream_write(content_info->reject, target->reject_path,
eol_str, strlen(eol_str), iterpool));
}
}
@@ -1104,9 +1130,10 @@ reject_hunk(patch_target_t *target, hunk
}
/* Write the modified text of hunk described by HI to the patched
- * stream of TARGET. Do temporary allocations in POOL. */
+ * stream of CONTENT_INFO. Do temporary allocations in POOL. */
static svn_error_t *
-apply_hunk(patch_target_t *target, hunk_info_t *hi, apr_pool_t *pool)
+apply_hunk(patch_target_t *target, target_content_info_t *content_info,
+ hunk_info_t *hi, apr_pool_t *pool)
{
svn_linenum_t lines_read;
svn_boolean_t eof;
@@ -1120,19 +1147,19 @@ apply_hunk(patch_target_t *target, hunk_
* Also copy leading lines of context which matched with fuzz.
* The target has changed on the fuzzy-matched lines,
* so we should retain the target's version of those lines. */
- SVN_ERR(copy_lines_to_target(target, hi->matched_line + hi->fuzz,
- pool));
+ SVN_ERR(copy_lines_to_target(content_info, hi->matched_line + hi->fuzz,
+ target->patched_path, pool));
/* Skip the target's version of the hunk.
* Don't skip trailing lines which matched with fuzz. */
- line = target->current_line +
+ line = content_info->current_line +
svn_diff_hunk_get_original_length(hi->hunk) - (2 * hi->fuzz);
- SVN_ERR(seek_to_line(target, line, pool));
- if (target->current_line != line && ! target->eof)
+ SVN_ERR(seek_to_line(content_info, line, pool));
+ if (content_info->current_line != line && ! content_info->eof)
{
/* Seek failed, reject this hunk. */
hi->rejected = TRUE;
- SVN_ERR(reject_hunk(target, hi, pool));
+ SVN_ERR(reject_hunk(target, content_info, hi, pool));
return SVN_NO_ERROR;
}
}
@@ -1157,18 +1184,20 @@ apply_hunk(patch_target_t *target, hunk_
lines_read <= svn_diff_hunk_get_modified_length(hi->hunk) - hi->fuzz)
{
if (hunk_line->len >= 1)
- SVN_ERR(try_stream_write(target->patched, target->patched_path,
+ SVN_ERR(try_stream_write(content_info->patched,
+ target->patched_path,
hunk_line->data, hunk_line->len,
iterpool));
if (eol_str)
{
/* Use the EOL as it was read from the patch file,
* unless the target's EOL style is set by svn:eol-style */
- if (target->eol_style != svn_subst_eol_style_none)
- eol_str = target->eol_str;
+ if (content_info->eol_style != svn_subst_eol_style_none)
+ eol_str = content_info->eol_str;
- SVN_ERR(try_stream_write(target->patched, target->patched_path,
- eol_str, strlen(eol_str), iterpool));
+ SVN_ERR(try_stream_write(content_info->patched,
+ target->patched_path, eol_str,
+ strlen(eol_str), iterpool));
}
}
}
@@ -1233,13 +1262,13 @@ send_patch_notification(const patch_targ
apr_pool_t *iterpool;
iterpool = svn_pool_create(pool);
- for (i = 0; i < target->hunks->nelts; i++)
+ for (i = 0; i < target->content_info->hunks->nelts; i++)
{
hunk_info_t *hi;
svn_pool_clear(iterpool);
- hi = APR_ARRAY_IDX(target->hunks, i, hunk_info_t *);
+ hi = APR_ARRAY_IDX(target->content_info->hunks, i, hunk_info_t *);
if (hi->already_applied)
action = svn_wc_notify_patch_hunk_already_applied;
@@ -1339,7 +1368,7 @@ apply_one_patch(patch_target_t **patch_t
* If no match is found initially, try with fuzz. */
do
{
- SVN_ERR(get_hunk_info(&hi, target, hunk, fuzz,
+ SVN_ERR(get_hunk_info(&hi, target, target->content_info, hunk, fuzz,
ignore_whitespace,
cancel_func, cancel_baton,
result_pool, iterpool));
@@ -1347,31 +1376,32 @@ apply_one_patch(patch_target_t **patch_t
}
while (hi->rejected && fuzz <= MAX_FUZZ && ! hi->already_applied);
- APR_ARRAY_PUSH(target->hunks, hunk_info_t *) = hi;
+ APR_ARRAY_PUSH(target->content_info->hunks, hunk_info_t *) = hi;
}
/* Apply or reject hunks. */
- for (i = 0; i < target->hunks->nelts; i++)
+ for (i = 0; i < target->content_info->hunks->nelts; i++)
{
hunk_info_t *hi;
svn_pool_clear(iterpool);
- hi = APR_ARRAY_IDX(target->hunks, i, hunk_info_t *);
+ hi = APR_ARRAY_IDX(target->content_info->hunks, i, hunk_info_t *);
if (hi->already_applied)
continue;
else if (hi->rejected)
- SVN_ERR(reject_hunk(target, hi, iterpool));
+ SVN_ERR(reject_hunk(target, target->content_info, hi, iterpool));
else
- SVN_ERR(apply_hunk(target, hi, iterpool));
+ SVN_ERR(apply_hunk(target, target->content_info, hi, iterpool));
}
svn_pool_destroy(iterpool);
if (target->kind_on_disk == svn_node_file)
{
/* Copy any remaining lines to target. */
- SVN_ERR(copy_lines_to_target(target, 0, scratch_pool));
- if (! target->eof)
+ SVN_ERR(copy_lines_to_target(target->content_info, 0,
+ target->patched_path, scratch_pool));
+ if (! target->content_info->eof)
{
/* We could not copy the entire target file to the temporary file,
* and would truncate the target if we copied the temporary file
@@ -1383,9 +1413,9 @@ apply_one_patch(patch_target_t **patch_t
/* Close the streams of the target so that their content is flushed
* to disk. This will also close underlying streams and files. */
if (target->kind_on_disk == svn_node_file)
- SVN_ERR(svn_stream_close(target->stream));
- SVN_ERR(svn_stream_close(target->patched));
- SVN_ERR(svn_stream_close(target->reject));
+ SVN_ERR(svn_stream_close(target->content_info->stream));
+ SVN_ERR(svn_stream_close(target->content_info->patched));
+ SVN_ERR(svn_stream_close(target->content_info->reject));
if (! target->skipped)
{