📄 diff_file.c
字号:
target_line[0] = original_start + original_length;
target_line[1] = modified_start + modified_length;
/* Output the changed range */
for (i = 0; i < 2; i++)
{
while (output_baton->current_line[i] < target_line[i])
{
SVN_ERR(svn_diff__file_output_unified_line(output_baton, i == 0
? svn_diff__file_output_unified_delete
: svn_diff__file_output_unified_insert, i));
}
}
return SVN_NO_ERROR;
}
static
const char *
svn_diff__file_output_unified_default_hdr(apr_pool_t *pool,
const char *path)
{
apr_finfo_t file_info;
apr_time_exp_t exploded_time;
char time_buffer[64];
apr_size_t time_len;
svn_io_stat(&file_info, path, APR_FINFO_MTIME, pool);
apr_time_exp_lt(&exploded_time, file_info.mtime);
apr_strftime(time_buffer, &time_len, sizeof(time_buffer) - 1,
"%a %b %e %H:%M:%S %Y", &exploded_time);
return apr_psprintf(pool, "%s\t%s", path, time_buffer);
}
static const svn_diff_output_fns_t svn_diff__file_output_unified_vtable =
{
NULL, /* output_common */
svn_diff__file_output_unified_diff_modified,
NULL, /* output_diff_latest */
NULL, /* output_diff_common */
NULL /* output_conflict */
};
svn_error_t *
svn_diff_file_output_unified(svn_stream_t *output_stream,
svn_diff_t *diff,
const char *original_path,
const char *modified_path,
const char *original_header,
const char *modified_header,
apr_pool_t *pool)
{
svn_diff__file_output_baton_t baton;
int i;
if (svn_diff_contains_diffs(diff))
{
memset(&baton, 0, sizeof(baton));
baton.output_stream = output_stream;
baton.pool = pool;
baton.path[0] = original_path;
baton.path[1] = modified_path;
baton.hunk = svn_stringbuf_create("", pool);
for (i = 0; i < 2; i++)
{
SVN_ERR(svn_io_file_open(&baton.file[i], baton.path[i],
APR_READ, APR_OS_DEFAULT, pool) );
}
if (original_header == NULL)
{
original_header =
svn_diff__file_output_unified_default_hdr(pool, original_path);
}
if (modified_header == NULL)
{
modified_header =
svn_diff__file_output_unified_default_hdr(pool, modified_path);
}
SVN_ERR(svn_stream_printf(output_stream, pool,
"--- %s" APR_EOL_STR
"+++ %s" APR_EOL_STR,
original_header, modified_header));
SVN_ERR(svn_diff_output(diff, &baton,
&svn_diff__file_output_unified_vtable));
SVN_ERR(svn_diff__file_output_unified_flush_hunk(&baton));
for (i = 0; i < 2; i++)
{
SVN_ERR(svn_io_file_close(baton.file[i], pool));
}
}
return SVN_NO_ERROR;
}
/** Display diff3 **/
typedef struct svn_diff3__file_output_baton_t
{
svn_stream_t *output_stream;
const char *path[3];
apr_off_t current_line[3];
char *buffer[3];
char *endp[3];
char *curp[3];
const char *conflict_modified;
const char *conflict_original;
const char *conflict_separator;
const char *conflict_latest;
svn_boolean_t display_original_in_conflict;
svn_boolean_t display_resolved_conflicts;
apr_pool_t *pool;
} svn_diff3__file_output_baton_t;
typedef enum svn_diff3__file_output_type_e
{
svn_diff3__file_output_skip,
svn_diff3__file_output_normal
} svn_diff3__file_output_type_e;
static
svn_error_t *
svn_diff3__file_output_line(svn_diff3__file_output_baton_t *baton,
svn_diff3__file_output_type_e type,
int idx)
{
char *curp;
char *endp;
char *eol;
apr_size_t len;
curp = baton->curp[idx];
endp = baton->endp[idx];
/* Lazily update the current line even if we're at EOF.
*/
baton->current_line[idx]++;
if (curp == endp)
return SVN_NO_ERROR;
/* XXX: '\n' doesn't really cut it. We need to be able to detect
* XXX: '\n', '\r' and '\r\n'.
*/
eol = memchr(curp, '\n', endp - curp);
if (!eol)
eol = endp;
else
eol++;
if (type != svn_diff3__file_output_skip)
{
len = eol - curp;
SVN_ERR(svn_stream_write(baton->output_stream, curp, &len));
}
baton->curp[idx] = eol;
return SVN_NO_ERROR;
}
static
svn_error_t *
svn_diff3__file_output_hunk(void *baton,
int idx,
apr_off_t target_line, apr_off_t target_length)
{
svn_diff3__file_output_baton_t *output_baton = baton;
/* Skip lines until we are at the start of the changed range */
while (output_baton->current_line[idx] < target_line)
{
SVN_ERR(svn_diff3__file_output_line(output_baton,
svn_diff3__file_output_skip, idx));
}
target_line += target_length;
while (output_baton->current_line[idx] < target_line)
{
SVN_ERR(svn_diff3__file_output_line(output_baton,
svn_diff3__file_output_normal, idx));
}
return SVN_NO_ERROR;
}
static
svn_error_t *
svn_diff3__file_output_common(void *baton,
apr_off_t original_start, apr_off_t original_length,
apr_off_t modified_start, apr_off_t modified_length,
apr_off_t latest_start, apr_off_t latest_length)
{
return svn_diff3__file_output_hunk(baton, 0,
original_start, original_length);
}
static
svn_error_t *
svn_diff3__file_output_diff_modified(void *baton,
apr_off_t original_start, apr_off_t original_length,
apr_off_t modified_start, apr_off_t modified_length,
apr_off_t latest_start, apr_off_t latest_length)
{
return svn_diff3__file_output_hunk(baton, 1,
modified_start, modified_length);
}
static
svn_error_t *
svn_diff3__file_output_diff_latest(void *baton,
apr_off_t original_start, apr_off_t original_length,
apr_off_t modified_start, apr_off_t modified_length,
apr_off_t latest_start, apr_off_t latest_length)
{
return svn_diff3__file_output_hunk(baton, 2,
latest_start, latest_length);
}
static
svn_error_t *
svn_diff3__file_output_conflict(void *baton,
apr_off_t original_start, apr_off_t original_length,
apr_off_t modified_start, apr_off_t modified_length,
apr_off_t latest_start, apr_off_t latest_length,
svn_diff_t *diff);
static const svn_diff_output_fns_t svn_diff3__file_output_vtable =
{
svn_diff3__file_output_common,
svn_diff3__file_output_diff_modified,
svn_diff3__file_output_diff_latest,
svn_diff3__file_output_diff_modified, /* output_diff_common */
svn_diff3__file_output_conflict
};
static
svn_error_t *
svn_diff3__file_output_conflict(void *baton,
apr_off_t original_start, apr_off_t original_length,
apr_off_t modified_start, apr_off_t modified_length,
apr_off_t latest_start, apr_off_t latest_length,
svn_diff_t *diff)
{
svn_diff3__file_output_baton_t *file_baton = baton;
apr_size_t len;
if (diff && file_baton->display_resolved_conflicts)
{
return svn_diff_output(diff, baton,
&svn_diff3__file_output_vtable);
}
len = strlen(file_baton->conflict_modified);
SVN_ERR(svn_stream_write(file_baton->output_stream,
file_baton->conflict_modified,
&len));
len = sizeof(APR_EOL_STR) - 1;
SVN_ERR(svn_stream_write(file_baton->output_stream,
APR_EOL_STR, &len));
SVN_ERR(svn_diff3__file_output_hunk(baton, 1,
modified_start, modified_length));
if (file_baton->display_original_in_conflict)
{
len = strlen(file_baton->conflict_original);
SVN_ERR(svn_stream_write(file_baton->output_stream,
file_baton->conflict_original, &len));
len = sizeof(APR_EOL_STR) - 1;
SVN_ERR(svn_stream_write(file_baton->output_stream,
APR_EOL_STR, &len));
SVN_ERR(svn_diff3__file_output_hunk(baton, 0,
original_start, original_length));
}
len = strlen(file_baton->conflict_separator);
SVN_ERR(svn_stream_write(file_baton->output_stream,
file_baton->conflict_separator, &len));
len = sizeof(APR_EOL_STR) - 1;
SVN_ERR(svn_stream_write(file_baton->output_stream,
APR_EOL_STR, &len));
SVN_ERR(svn_diff3__file_output_hunk(baton, 2,
latest_start, latest_length));
len = strlen(file_baton->conflict_latest);
SVN_ERR(svn_stream_write(file_baton->output_stream,
file_baton->conflict_latest, &len));
len = sizeof(APR_EOL_STR) - 1;
SVN_ERR(svn_stream_write(file_baton->output_stream,
APR_EOL_STR, &len));
return SVN_NO_ERROR;
}
svn_error_t *
svn_diff_file_output_merge(svn_stream_t *output_stream,
svn_diff_t *diff,
const char *original_path,
const char *modified_path,
const char *latest_path,
const char *conflict_original,
const char *conflict_modified,
const char *conflict_latest,
const char *conflict_separator,
svn_boolean_t display_original_in_conflict,
svn_boolean_t display_resolved_conflicts,
apr_pool_t *pool)
{
svn_diff3__file_output_baton_t baton;
apr_file_t *file[3];
apr_off_t size;
int idx;
#if APR_HAS_MMAP
apr_mmap_t *mm[3] = { 0 };
#endif /* APR_HAS_MMAP */
memset(&baton, 0, sizeof(baton));
baton.output_stream = output_stream;
baton.pool = pool;
baton.path[0] = original_path;
baton.path[1] = modified_path;
baton.path[2] = latest_path;
baton.conflict_modified = conflict_modified ? conflict_modified
: apr_psprintf(pool, "<<<<<<< %s", modified_path);
baton.conflict_original = conflict_original ? conflict_original
: apr_psprintf(pool, "||||||| %s", original_path);
baton.conflict_separator = conflict_separator ? conflict_separator
: "=======";
baton.conflict_latest = conflict_latest ? conflict_latest
: apr_psprintf(pool, ">>>>>>> %s", latest_path);
baton.display_original_in_conflict = display_original_in_conflict;
baton.display_resolved_conflicts = display_resolved_conflicts &&
!display_original_in_conflict;
for (idx = 0; idx < 3; idx++)
{
SVN_ERR(map_or_read_file(&file[idx],
MMAP_T_ARG(mm[idx])
&baton.buffer[idx], &size,
baton.path[idx], pool));
baton.curp[idx] = baton.buffer[idx];
baton.endp[idx] = baton.buffer[idx];
if (baton.endp[idx])
baton.endp[idx] += size;
}
SVN_ERR(svn_diff_output(diff, &baton,
&svn_diff3__file_output_vtable));
for (idx = 0; idx < 3; idx++)
{
#if APR_HAS_MMAP
if (mm[idx])
{
apr_status_t rv = apr_mmap_delete(mm[idx]);
if (rv != APR_SUCCESS)
{
return svn_error_wrap_apr(rv, "Failed to delete mmap '%s'",
baton.path[idx]);
}
}
#endif /* APR_HAS_MMAP */
if (file[idx])
{
SVN_ERR(svn_io_file_close(file[idx], pool));
}
}
return SVN_NO_ERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -