Alien-SVN
view release on metacpan or search on metacpan
src/subversion/subversion/libsvn_diff/diff_file.c view on Meta::CPAN
* ### we don't have optional argument support. */
{ "unified", 'u', 0, NULL },
{ NULL, 0, 0, NULL }
};
svn_diff_file_options_t *
svn_diff_file_options_create(apr_pool_t *pool)
{
return apr_pcalloc(pool, sizeof(svn_diff_file_options_t));
}
/* A baton for use with opt_parsing_error_func(). */
struct opt_parsing_error_baton_t
{
svn_error_t *err;
apr_pool_t *pool;
};
/* Store an error message from apr_getopt_long(). Set BATON->err to a new
* error with a message generated from FMT and the remaining arguments.
* Implements apr_getopt_err_fn_t. */
static void
opt_parsing_error_func(void *baton,
const char *fmt, ...)
{
struct opt_parsing_error_baton_t *b = baton;
const char *message;
va_list ap;
va_start(ap, fmt);
message = apr_pvsprintf(b->pool, fmt, ap);
va_end(ap);
/* Skip leading ": " (if present, which it always is in known cases). */
if (strncmp(message, ": ", 2) == 0)
message += 2;
b->err = svn_error_create(SVN_ERR_INVALID_DIFF_OPTION, NULL, message);
}
svn_error_t *
svn_diff_file_options_parse(svn_diff_file_options_t *options,
const apr_array_header_t *args,
apr_pool_t *pool)
{
apr_getopt_t *os;
struct opt_parsing_error_baton_t opt_parsing_error_baton;
/* Make room for each option (starting at index 1) plus trailing NULL. */
const char **argv = apr_palloc(pool, sizeof(char*) * (args->nelts + 2));
opt_parsing_error_baton.err = NULL;
opt_parsing_error_baton.pool = pool;
argv[0] = "";
memcpy((void *) (argv + 1), args->elts, sizeof(char*) * args->nelts);
argv[args->nelts + 1] = NULL;
apr_getopt_init(&os, pool, args->nelts + 1, argv);
/* Capture any error message from apr_getopt_long(). This will typically
* say which option is wrong, which we would not otherwise know. */
os->errfn = opt_parsing_error_func;
os->errarg = &opt_parsing_error_baton;
while (1)
{
const char *opt_arg;
int opt_id;
apr_status_t err = apr_getopt_long(os, diff_options, &opt_id, &opt_arg);
if (APR_STATUS_IS_EOF(err))
break;
if (err)
/* Wrap apr_getopt_long()'s error message. Its doc string implies
* it always will produce one, but never mind if it doesn't. Avoid
* using the message associated with the return code ERR, because
* it refers to the "command line" which may be misleading here. */
return svn_error_create(SVN_ERR_INVALID_DIFF_OPTION,
opt_parsing_error_baton.err,
_("Error in options to internal diff"));
switch (opt_id)
{
case 'b':
/* -w takes precedence over -b. */
if (! options->ignore_space)
options->ignore_space = svn_diff_file_ignore_space_change;
break;
case 'w':
options->ignore_space = svn_diff_file_ignore_space_all;
break;
case SVN_DIFF__OPT_IGNORE_EOL_STYLE:
options->ignore_eol_style = TRUE;
break;
case 'p':
options->show_c_function = TRUE;
break;
default:
break;
}
}
/* Check for spurious arguments. */
if (os->ind < os->argc)
return svn_error_createf(SVN_ERR_INVALID_DIFF_OPTION, NULL,
_("Invalid argument '%s' in diff options"),
os->argv[os->ind]);
return SVN_NO_ERROR;
}
svn_error_t *
svn_diff_file_diff_2(svn_diff_t **diff,
const char *original,
const char *modified,
const svn_diff_file_options_t *options,
apr_pool_t *pool)
{
svn_diff__file_baton_t baton = { 0 };
baton.options = options;
( run in 0.346 second using v1.01-cache-2.11-cpan-483215c6ad5 )