Index: subversion/libsvn_client/patch.c =================================================================== --- subversion/libsvn_client/patch.c (revision 964865) +++ subversion/libsvn_client/patch.c (arbetskopia) @@ -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 text_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 hunk_info_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 hunk_info_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; +} text_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 hunk_info_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 hunk_info_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. */ + text_info_t *text_info; /* The pool the target is allocated in. */ apr_pool_t *pool; @@ -254,7 +262,7 @@ resolve_target_wc_file_info(svn_wc_context_t *wc_c 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->text_info->keywords, keywords_val->data, rev_str, url, changed_date, author, result_pool)); @@ -264,8 +272,8 @@ resolve_target_wc_file_info(svn_wc_context_t *wc_c 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->text_info->eol_style, + &target->text_info->eol_str, eol_style_val->data); } @@ -421,16 +429,23 @@ init_patch_target(patch_target_t **patch_target, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { patch_target_t *target; + text_info_t *text_info; target = apr_pcalloc(result_pool, sizeof(*target)); + text_info = apr_pcalloc(result_pool, sizeof(*text_info)); + text_info->current_line = 1; + text_info->eol_style = svn_subst_eol_style_none; + text_info->lines = apr_array_make(result_pool, 0, + sizeof(svn_stream_mark_t *)); + text_info->hunks = apr_array_make(result_pool, 0, sizeof(hunk_info_t *)); + text_info->keywords = apr_hash_make(result_pool); + text_info->pool = result_pool; + + target->text_info = text_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_target, APR_OS_DEFAULT, result_pool)); /* Create a stream to read from the target. */ - target->stream = svn_stream_from_aprfile2(target->file, - FALSE, result_pool); + text_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_target, /* 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 = (text_info->eol_style == svn_subst_eol_style_fixed + || text_info->eol_style == svn_subst_eol_style_native); + text_info->patched = svn_subst_stream_translated( + patched_raw, text_info->eol_str, repair_eol, + text_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(&text_info->reject, &target->reject_path, NULL, remove_tempfiles ? svn_io_file_del_on_pool_cleanup : @@ -498,7 +513,7 @@ init_patch_target(patch_target_t **patch_target, 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(text_info->reject, diff_header, &len)); } *patch_target = target; @@ -510,7 +525,7 @@ init_patch_target(patch_target_t **patch_target, * Do temporary allocations in SCRATCH_POOL. */ static svn_error_t * -read_line(patch_target_t *target, +read_line(text_info_t *text_info, const char **line, apr_pool_t *scratch_pool, apr_pool_t *result_pool) @@ -518,33 +533,33 @@ static svn_error_t * svn_stringbuf_t *line_raw; const char *eol_str; - if (target->eof) + if (text_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(text_info->current_line <= text_info->lines->nelts + 1); + if (text_info->current_line == text_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(text_info->stream, &mark, text_info->pool)); + APR_ARRAY_PUSH(text_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(text_info->stream, &line_raw, + &eol_str, &text_info->eof, scratch_pool)); - if (target->eol_style == svn_subst_eol_style_none) - target->eol_str = eol_str; + if (text_info->eol_style == svn_subst_eol_style_none) + text_info->eol_str = eol_str; /* Contract keywords. */ SVN_ERR(svn_subst_translate_cstring2(line_raw->data, line, NULL, FALSE, - target->keywords, FALSE, + text_info->keywords, FALSE, result_pool)); - if (! target->eof) - target->current_line++; + if (! text_info->eof) + text_info->current_line++; return SVN_NO_ERROR; } @@ -554,7 +569,7 @@ static svn_error_t * * Do temporary allocations in SCRATCH_POOL. */ static svn_error_t * -seek_to_line(patch_target_t *target, svn_linenum_t line, +seek_to_line(text_info_t *text_info, svn_linenum_t line, apr_pool_t *scratch_pool) { svn_linenum_t saved_line; @@ -562,36 +577,36 @@ static svn_error_t * SVN_ERR_ASSERT(line > 0); - if (line == target->current_line) + if (line == text_info->current_line) return SVN_NO_ERROR; - saved_line = target->current_line; - saved_eof = target->eof; + saved_line = text_info->current_line; + saved_eof = text_info->eof; - if (line <= target->lines->nelts) + if (line <= text_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(text_info->lines, line - 1, svn_stream_mark_t *); + SVN_ERR(svn_stream_seek(text_info->stream, mark)); + text_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 (! text_info->eof && text_info->current_line < line) { svn_pool_clear(iterpool); - SVN_ERR(read_line(target, &dummy, iterpool, iterpool)); + SVN_ERR(read_line(text_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 > text_info->current_line) + text_info->eof = FALSE; return SVN_NO_ERROR; } @@ -605,7 +620,7 @@ static svn_error_t * * 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, text_info_t *text_info, const svn_hunk_t *hunk, int fuzz, svn_boolean_t ignore_whitespace, svn_boolean_t match_modified, apr_pool_t *pool) @@ -623,10 +638,10 @@ static svn_error_t * *matched = FALSE; - if (target->eof) + if (text_info->eof) return SVN_NO_ERROR; - saved_line = target->current_line; + saved_line = text_info->current_line; lines_read = 0; lines_matched = FALSE; original_length = svn_diff_hunk_get_original_length(hunk); @@ -656,10 +671,10 @@ static svn_error_t * SVN_ERR(svn_subst_translate_cstring2(hunk_line->data, &hunk_line_translated, NULL, FALSE, - target->keywords, FALSE, + text_info->keywords, FALSE, iterpool)); lines_read++; - SVN_ERR(read_line(target, &target_line, iterpool, iterpool)); + SVN_ERR(read_line(text_info, &target_line, iterpool, iterpool)); if (! hunk_eof) { if (lines_read <= fuzz && leading_context > fuzz) @@ -686,11 +701,11 @@ static svn_error_t * } } } - while (lines_matched && ! (hunk_eof || target->eof)); + while (lines_matched && ! (hunk_eof || text_info->eof)); if (hunk_eof) *matched = lines_matched; - else if (target->eof) + else if (text_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. */ @@ -707,7 +722,7 @@ static svn_error_t * else *matched = FALSE; } - SVN_ERR(seek_to_line(target, saved_line, iterpool)); + SVN_ERR(seek_to_line(text_info, saved_line, iterpool)); svn_pool_destroy(iterpool); @@ -729,7 +744,7 @@ static svn_error_t * * 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, text_info_t *text_info, const svn_hunk_t *hunk, svn_boolean_t match_first, svn_linenum_t upper_line, int fuzz, svn_boolean_t ignore_whitespace, @@ -741,8 +756,8 @@ static svn_error_t * *matched_line = 0; iterpool = svn_pool_create(pool); - while ((target->current_line < upper_line || upper_line == 0) && - ! target->eof) + while ((text_info->current_line < upper_line || upper_line == 0) && + ! text_info->eof) { svn_boolean_t matched; int i; @@ -752,19 +767,19 @@ static svn_error_t * if (cancel_func) SVN_ERR((cancel_func)(cancel_baton)); - SVN_ERR(match_hunk(&matched, target, hunk, fuzz, ignore_whitespace, + SVN_ERR(match_hunk(&matched, text_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 < text_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(text_info->hunks, i, const hunk_info_t *); if (match_modified) length = svn_diff_hunk_get_modified_length(hi->hunk); @@ -772,22 +787,23 @@ static svn_error_t * 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)); + text_info->current_line >= hi->matched_line && + text_info->current_line < (hi->matched_line + length)); if (taken) break; } if (! taken) { - *matched_line = target->current_line; + *matched_line = text_info->current_line; if (match_first) break; } } - if (! target->eof) - SVN_ERR(seek_to_line(target, target->current_line + 1, iterpool)); + if (! text_info->eof) + SVN_ERR(seek_to_line(text_info, text_info->current_line + 1, + iterpool)); } svn_pool_destroy(iterpool); @@ -834,11 +850,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->text_info->keywords, FALSE, iterpool)); SVN_ERR(svn_subst_translate_cstring2(hunk_line->data, &hunk_line_translated, - NULL, FALSE, target->keywords, + NULL, FALSE, + target->text_info->keywords, FALSE, iterpool)); lines_matched = ! strcmp(line_translated, hunk_line_translated); if (eof != hunk_eof) @@ -868,6 +886,7 @@ match_existing_file(svn_boolean_t *match, * Do temporary allocations in POOL. */ static svn_error_t * get_hunk_info(hunk_info_t **hi, patch_target_t *target, + text_info_t *text_info, const svn_hunk_t *hunk, int fuzz, svn_boolean_t ignore_whitespace, svn_cancel_func_t cancel_func, void *cancel_baton, @@ -911,7 +930,7 @@ get_hunk_info(hunk_info_t **hi, patch_target_t *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 = text_info->current_line; svn_linenum_t modified_start; /* Check if the hunk is already applied. @@ -928,8 +947,9 @@ get_hunk_info(hunk_info_t **hi, patch_target_t *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(text_info, modified_start, scratch_pool)); + SVN_ERR(scan_for_match(&matched_line, text_info, + hunk, TRUE, modified_start + 1, fuzz, ignore_whitespace, TRUE, cancel_func, cancel_baton, @@ -944,14 +964,14 @@ get_hunk_info(hunk_info_t **hi, patch_target_t *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(text_info, original_start, scratch_pool)); + if (text_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, text_info, hunk, TRUE, original_start + 1, fuzz, ignore_whitespace, FALSE, cancel_func, cancel_baton, @@ -960,11 +980,11 @@ get_hunk_info(hunk_info_t **hi, patch_target_t *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(text_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, text_info, hunk, FALSE, original_start, fuzz, ignore_whitespace, FALSE, cancel_func, cancel_baton, @@ -976,15 +996,15 @@ get_hunk_info(hunk_info_t **hi, patch_target_t *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, text_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(text_info, saved_line, scratch_pool)); } else { @@ -1026,23 +1046,24 @@ try_stream_write(svn_stream_t *stream, const char * 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(text_info_t *text_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 ((text_info->current_line < line || line == 0) && ! text_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(text_info, &target_line, iterpool, iterpool)); + if (! text_info->eof) + target_line = apr_pstrcat(iterpool, target_line, text_info->eol_str, + NULL); - SVN_ERR(try_stream_write(target->patched, target->patched_path, + SVN_ERR(try_stream_write(text_info->patched, patched_path, target_line, strlen(target_line), iterpool)); } svn_pool_destroy(iterpool); @@ -1054,7 +1075,8 @@ static svn_error_t * * reject stream of TARGET, 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, text_info_t *text_info, + hunk_info_t *hi, apr_pool_t *pool) { const char *hunk_header; apr_size_t len; @@ -1068,7 +1090,7 @@ static svn_error_t * 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(text_info->reject, hunk_header, &len)); iterpool = svn_pool_create(pool); do @@ -1083,11 +1105,11 @@ static svn_error_t * if (! eof) { if (hunk_line->len >= 1) - SVN_ERR(try_stream_write(target->reject, target->reject_path, + SVN_ERR(try_stream_write(text_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(text_info->reject, target->reject_path, eol_str, strlen(eol_str), iterpool)); } } @@ -1102,7 +1124,8 @@ static svn_error_t * /* Write the modified text of hunk described by HI to the patched * stream of TARGET. 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, text_info_t *text_info, + hunk_info_t *hi, apr_pool_t *pool) { svn_linenum_t lines_read; svn_boolean_t eof; @@ -1116,19 +1139,19 @@ static svn_error_t * * 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(text_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 = text_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(text_info, line, pool)); + if (text_info->current_line != line && ! text_info->eof) { /* Seek failed, reject this hunk. */ hi->rejected = TRUE; - SVN_ERR(reject_hunk(target, hi, pool)); + SVN_ERR(reject_hunk(target, text_info, hi, pool)); return SVN_NO_ERROR; } } @@ -1153,17 +1176,17 @@ static svn_error_t * 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(text_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 (text_info->eol_style != svn_subst_eol_style_none) + eol_str = text_info->eol_str; - SVN_ERR(try_stream_write(target->patched, target->patched_path, + SVN_ERR(try_stream_write(text_info->patched, target->patched_path, eol_str, strlen(eol_str), iterpool)); } } @@ -1229,13 +1252,13 @@ send_patch_notification(const patch_target_t *targ apr_pool_t *iterpool; iterpool = svn_pool_create(pool); - for (i = 0; i < target->hunks->nelts; i++) + for (i = 0; i < target->text_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->text_info->hunks, i, hunk_info_t *); if (hi->already_applied) action = svn_wc_notify_patch_hunk_already_applied; @@ -1335,7 +1358,7 @@ apply_one_patch(patch_target_t **patch_target, svn * 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->text_info, hunk, fuzz, ignore_whitespace, cancel_func, cancel_baton, result_pool, iterpool)); @@ -1343,31 +1366,32 @@ apply_one_patch(patch_target_t **patch_target, svn } while (hi->rejected && fuzz <= MAX_FUZZ && ! hi->already_applied); - APR_ARRAY_PUSH(target->hunks, hunk_info_t *) = hi; + APR_ARRAY_PUSH(target->text_info->hunks, hunk_info_t *) = hi; } /* Apply or reject hunks. */ - for (i = 0; i < target->hunks->nelts; i++) + for (i = 0; i < target->text_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->text_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->text_info, hi, iterpool)); else - SVN_ERR(apply_hunk(target, hi, iterpool)); + SVN_ERR(apply_hunk(target, target->text_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->text_info, 0, + target->patched_path, scratch_pool)); + if (! target->text_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 @@ -1379,9 +1403,9 @@ apply_one_patch(patch_target_t **patch_target, svn /* 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->text_info->stream)); + SVN_ERR(svn_stream_close(target->text_info->patched)); + SVN_ERR(svn_stream_close(target->text_info->reject)); if (! target->skipped) {