[PATCH] Add -p to show C function names was Re: [PATCH] Extra options for libsvn_diff
From: Justin Erenkrantz <justin_at_erenkrantz.com>
Date: 2007-12-26 20:30:07 CET
[ Going way way back into the time machine.... ]
On Feb 16, 2006 12:45 PM, Garrett Rooney <rooneg@electricjellyfish.net> wrote:
I'd like to resurrect this discussion - IOW, I want Subversion to
Julian and C-Mike's comments almost two years ago was that it was
Patch against trunk below. I plan to commit this unless someone
Finally, many kudos to Peter for writing this in the first place. =) -- justin
--- Add -p to match GNU diff's show C function support. (Use 'svn diff -x -p' to activate.) Submitted by: lundblad Updated by: jerenkrantz * subversion/libsvn_diff/diff_file.c (svn_ctype.h): Include. (diff_options): Add show-c-function/p. (svn_diff_file_options_parse): Support -p. (SVN_DIFF__EXTRA_CONTEXT_LENGTH): Define to 50. (svn_diff__file_output_baton_t): Add boolean flag and fields to store context. (output_unified_line): Collect extra context if needed. (output_unified_flush_hunk): Emit extra context if we have it. (output_unified_diff_modified): Collect extra context. (svn_diff_file_output_unified3): Initialize new fields in baton. (svn_diff_file_output_unified2): Pass false to unified3. * subversion/include/svn_diff.h (svn_diff_file_options_t): Add show_c_function boolean. (svn_diff_file_output_unified3): Add in new parameter to new 1.5 function. (svn_diff_file_output_unified2): Document the hidden parameter. * subversion/libsvn_client/diff.c (diff_content_changed): Pass in new show_c_function boolean. * subversion/svn/main.c (svn_cl__options): Document new -p/show-c-function option. Index: subversion/include/svn_diff.h =================================================================== --- subversion/include/svn_diff.h (revision 28650) +++ subversion/include/svn_diff.h (working copy) @@ -338,6 +338,12 @@ typedef struct svn_diff_file_options_t /** Whether to treat all end-of-line markers the same when comparing lines. * The default is @c FALSE. */ svn_boolean_t ignore_eol_style; + /** Whether the '@@' lines of the unified diff output should include a prefix + * of the nearest preceding line that starts with a character that might be + * the initial character of a C language identifier. The default is + * @c FALSE. + */ + svn_boolean_t show_c_function; } svn_diff_file_options_t; /** Allocate a @c svn_diff_file_options_t structure in @a pool, initializing @@ -484,10 +490,11 @@ svn_diff_file_output_unified3(svn_stream_t *output const char *modified_header, const char *header_encoding, const char *relative_to_dir, + svn_boolean_t show_c_function, apr_pool_t *pool); /** Similar to svn_diff_file_output_unified3(), but with @a relative_to_dir - * set to NULL. + * set to NULL and @a show_c_function to false. * * @deprecated Provided for backwards compatibility with the 1.3 API. */ Index: subversion/libsvn_diff/diff_file.c =================================================================== --- subversion/libsvn_diff/diff_file.c (revision 28650) +++ subversion/libsvn_diff/diff_file.c (working copy) @@ -36,6 +36,7 @@ #include "diff.h" #include "svn_private_config.h" #include "svn_path.h" +#include "svn_ctype.h" /* A token, i.e. a line read from a file. */ @@ -546,6 +547,7 @@ static const apr_getopt_option_t diff_options[] = { "ignore-space-change", 'b', 0, NULL }, { "ignore-all-space", 'w', 0, NULL }, { "ignore-eol-style", SVN_DIFF__OPT_IGNORE_EOL_STYLE, 0, NULL }, + { "show-c-function", 'p', 0, NULL }, /* ### For compatibility; we don't support the argument to -u, because * ### we don't have optional argument support. */ { "unified", 'u', 0, NULL }, @@ -598,6 +600,9 @@ svn_diff_file_options_parse(svn_diff_file_options_ case SVN_DIFF__OPT_IGNORE_EOL_STYLE: options->ignore_eol_style = TRUE; break; + case 'p': + options->show_c_function = TRUE; + break; default: break; } @@ -716,6 +721,9 @@ svn_diff_file_diff4(svn_diff_t **diff, /** Display unified context diffs **/ +/* Maximum length of the extra context to show when show_c_function is set. + * GNU diff uses 40, let's be brave and use 50 instead. */ +#define SVN_DIFF__EXTRA_CONTEXT_LENGTH 50 typedef struct svn_diff__file_output_baton_t { svn_stream_t *output_stream; @@ -739,6 +747,14 @@ typedef struct svn_diff__file_output_baton_t apr_off_t hunk_length[2]; svn_stringbuf_t *hunk; + /* Should we emit C functions in the unified diff header */ + svn_boolean_t show_c_function; + /* "Context" to append to the @@ line when the show_c_function option + * is set. */ + svn_stringbuf_t *extra_context; + /* Extra context for the current hunk. */ + char hunk_extra_context[SVN_DIFF__EXTRA_CONTEXT_LENGTH + 1]; + apr_pool_t *pool; } svn_diff__file_output_baton_t; @@ -761,6 +777,8 @@ output_unified_line(svn_diff__file_output_baton_t svn_error_t *err; svn_boolean_t bytes_processed = FALSE; svn_boolean_t had_cr = FALSE; + /* Are we collecting extra context? */ + svn_boolean_t collect_extra = FALSE; length = baton->length[idx]; curp = baton->curp[idx]; @@ -799,6 +817,15 @@ output_unified_line(svn_diff__file_output_baton_t default: break; } + + if (baton->show_c_function + && (type == svn_diff__file_output_unified_skip + || type == svn_diff__file_output_unified_context) + && svn_ctype_isalnum(*curp)) + { + svn_stringbuf_setempty(baton->extra_context); + collect_extra = TRUE; + } } eol = find_eol_start(curp, length); @@ -825,6 +852,11 @@ output_unified_line(svn_diff__file_output_baton_t { svn_stringbuf_appendbytes(baton->hunk, curp, len); } + if (collect_extra) + { + svn_stringbuf_appendbytes(baton->extra_context, + curp, len); + } baton->curp[idx] = eol; baton->length[idx] = length; @@ -840,6 +872,11 @@ output_unified_line(svn_diff__file_output_baton_t svn_stringbuf_appendbytes(baton->hunk, curp, length); } + if (collect_extra) + { + svn_stringbuf_appendbytes(baton->extra_context, curp, length); + } + bytes_processed = TRUE; } @@ -858,6 +895,8 @@ output_unified_line(svn_diff__file_output_baton_t { svn_stringbuf_appendbytes(baton->hunk, curp, 1); } + /* We don't append the LF to extra_context, since it would + * just be stripped anyway. */ ++curp; --length; } @@ -960,7 +999,10 @@ output_unified_flush_hunk(svn_diff__file_output_ba SVN_ERR(svn_stream_printf_from_utf8(baton->output_stream, baton->header_encoding, - baton->pool, " @@" APR_EOL_STR)); + baton->pool, " @@%s%s" APR_EOL_STR, + baton->hunk_extra_context[0] + ? " " : "", + baton->hunk_extra_context)); /* Output the hunk content */ hunk_len = baton->hunk->len; @@ -1011,6 +1053,27 @@ output_unified_diff_modified(void *baton, SVN_ERR(output_unified_line(output_baton, svn_diff__file_output_unified_skip, 0)); } + + if (output_baton->show_c_function) + { + int p; + + /* Save the extra context for later use. + * Note that the last byte of the hunk_extra_context array is never + * touched after it is zero-initialized, so the array is always + * 0-terminated. */ + strncpy(output_baton->hunk_extra_context, + output_baton->extra_context->data, + SVN_DIFF__EXTRA_CONTEXT_LENGTH); + /* Trim whitespace at the end, most notably to get rid of any + * newline characters. */ + p = strlen(output_baton->hunk_extra_context); + while (p > 0 + && svn_ctype_isspace(output_baton->hunk_extra_context[p - 1])) + { + output_baton->hunk_extra_context[--p] = '\0'; + } + } } /* Skip lines until we are at the start of the changed range */ @@ -1084,6 +1147,7 @@ svn_diff_file_output_unified3(svn_stream_t *output const char *modified_header, const char *header_encoding, const char *relative_to_dir, + svn_boolean_t show_c_function, apr_pool_t *pool) { svn_diff__file_output_baton_t baton; @@ -1098,6 +1162,8 @@ svn_diff_file_output_unified3(svn_stream_t *output baton.path[0] = original_path; baton.path[1] = modified_path; baton.hunk = svn_stringbuf_create("", pool); + baton.show_c_function = show_c_function; + baton.extra_context = svn_stringbuf_create("", pool); SVN_ERR(svn_utf_cstring_from_utf8_ex2(&baton.context_str, " ", header_encoding, pool)); @@ -1187,7 +1253,7 @@ svn_diff_file_output_unified2(svn_stream_t *output return svn_diff_file_output_unified3(output_stream, diff, original_path, modified_path, original_header, modified_header, - header_encoding, NULL, pool); + header_encoding, NULL, FALSE, pool); } svn_error_t * Index: subversion/libsvn_client/diff.c =================================================================== --- subversion/libsvn_client/diff.c (revision 28650) +++ subversion/libsvn_client/diff.c (working copy) @@ -604,7 +604,8 @@ diff_content_changed(const char *path, /* Output the actual diff */ SVN_ERR(svn_diff_file_output_unified3 (os, diff, tmpfile1, tmpfile2, label1, label2, - diff_cmd_baton->header_encoding, rel_to_dir, subpool)); + diff_cmd_baton->header_encoding, rel_to_dir, + opts->show_c_function, subpool)); } } Index: subversion/svn/main.c =================================================================== --- subversion/svn/main.c (revision 28650) +++ subversion/svn/main.c (working copy) @@ -172,7 +172,11 @@ const apr_getopt_option_t svn_cl__options[] = " " " --ignore-eol-style:\n" " " - " Ignore changes in EOL style")}, + " Ignore changes in EOL style\n" + " " + " -p (--show-c-function):\n" + " " + " Show C function name in diff output.")}, #endif {"targets", opt_targets, 1, N_("pass contents of file ARG as additional args")}, --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org For additional commands, e-mail: dev-help@subversion.tigris.orgReceived on Wed Dec 26 20:30:22 2007 |
This is an archived mail posted to the Subversion Dev mailing list.
This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.