svn_error_t * svn_opt_args_to_target_array(apr_array_header_t **targets_p, apr_getopt_t *os, const apr_array_header_t *known_targets, svn_opt_revision_t *start_revision, svn_opt_revision_t *end_revision, svn_boolean_t extract_revisions, apr_pool_t *pool) { apr_array_header_t *output_targets; SVN_ERR(svn_opt_args_to_target_array2(&output_targets, os, known_targets, pool)); if (extract_revisions) { svn_opt_revision_t temprev; const char *path; if (output_targets->nelts > 0) { path = APR_ARRAY_IDX(output_targets, 0, const char *); SVN_ERR(svn_opt_parse_path(&temprev, &path, path, pool)); if (temprev.kind != svn_opt_revision_unspecified) { APR_ARRAY_IDX(output_targets, 0, const char *) = path; start_revision->kind = temprev.kind; start_revision->value = temprev.value; } }
/* * Our main entry point for 'checkout' subcommand. */ svn_error_t * svn_cl__get(apr_getopt_t *os, void *baton, apr_pool_t *pool) { svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; apr_array_header_t *targets; struct mw_conf_head machine_config, root; struct callback_args args; struct mw_config_data *config_data; struct conf_list_entry *node; const char *project; int i; openlog("mwbuild", LOG_ODELAY, LOG_USER); TAILQ_INIT(&machine_config); TAILQ_INIT(&root); args.opt_state = opt_state; args.pool = pool; args.ctx = ctx; args.action = MW_GET_ACTION; SVN_ERR(svn_opt_args_to_target_array2(&targets, os, opt_state->targets, pool)); if ((config_data = mw_get_config(args.action, baton, pool)) == NULL) { fprintf(stderr, "Could not get config\n"); exit(1); } /* machine_config is just the machine config, which is needed to check for * custom MWBUILD_* paths, which effects later actions. */ mw_parse_config(&machine_config, config_data, 1); mw_set_config_defaults(&machine_config); mw_do_expansion(&machine_config); /* Open the action log */ args.logfd = mw_open_action_log(&machine_config, "get"); /* if we have no options, call this to print all known projects */ if (targets->nelts == 0) { mw_process_machine_projects(&machine_config, &mw_conf_list_get, &args); } else { for (i = 0; i < targets->nelts; i++) { project = ((const char **) (targets->elts))[i]; mw_process_project_settings(&machine_config, project, &mw_conf_list_get, &args); } } mw_free_conflist(&root, 1); return (SVN_NO_ERROR); }
/* This implements the `svn_opt_subcommand_t' interface. */ svn_error_t * svn_cl__cat(apr_getopt_t *os, void *baton, apr_pool_t *pool) { svn_cl__opt_state_t *opt_state = ((svn_cl__cmd_baton_t *) baton)->opt_state; svn_client_ctx_t *ctx = ((svn_cl__cmd_baton_t *) baton)->ctx; apr_array_header_t *targets; int i; svn_stream_t *out; apr_pool_t *subpool = svn_pool_create(pool); SVN_ERR(svn_opt_args_to_target_array2(&targets, os, opt_state->targets, pool)); /* Cat cannot operate on an implicit '.' so a filename is required */ if (! targets->nelts) return svn_error_create(SVN_ERR_CL_INSUFFICIENT_ARGS, 0, NULL); SVN_ERR(svn_stream_for_stdout(&out, pool)); for (i = 0; i < targets->nelts; i++) { const char *target = ((const char **) (targets->elts))[i]; const char *truepath; svn_opt_revision_t peg_revision; svn_pool_clear(subpool); SVN_ERR(svn_cl__check_cancel(ctx->cancel_baton)); /* Get peg revisions. */ SVN_ERR(svn_opt_parse_path(&peg_revision, &truepath, target, subpool)); SVN_ERR(svn_cl__try( svn_client_cat2(out, truepath, &peg_revision, &(opt_state->start_revision), ctx, subpool), NULL, opt_state->quiet, SVN_ERR_UNVERSIONED_RESOURCE, SVN_ERR_ENTRY_NOT_FOUND, SVN_ERR_CLIENT_IS_DIRECTORY, SVN_NO_ERROR)); } svn_pool_destroy(subpool); return SVN_NO_ERROR; }
static svn_error_t * test_svn_opt_args_to_target_array2(const char **msg, svn_boolean_t msg_only, svn_test_opts_t *opts, apr_pool_t *pool) { apr_size_t i; static struct { const char *input; const char *output; /* NULL means an error is expected. */ } const tests[] = { { ".", "" }, { ".@BASE", "@BASE" }, { "foo///bar", "foo/bar" }, { "foo///bar@13", "foo/bar@13" }, { "foo///bar@HEAD", "foo/bar@HEAD" }, { "foo///bar@{1999-12-31}", "foo/bar@{1999-12-31}" }, { "http://a//b////", "http://a/b" }, { "http://a///b@27", "http://a/b@27" }, { "http://a/b//@COMMITTED", "http://a/b@COMMITTED" }, { "foo///bar@1:2", "foo/bar@1:2" }, { "foo///bar@baz", "foo/bar@baz" }, { "foo///bar@", "foo/bar@" }, { "foo///bar///@13", "foo/bar@13" }, { "foo///bar@@13", "foo/bar@@13" }, { "foo///@bar@HEAD", "foo/@bar@HEAD" }, { "foo@///bar", "foo@/bar" }, { "foo@HEAD///bar", "foo@HEAD/bar" }, }; *msg = "test svn_opt_args_to_target_array2"; if (msg_only) return SVN_NO_ERROR; for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) { const char *input = tests[i].input; const char *expected_output = tests[i].output; apr_array_header_t *targets; apr_getopt_t *os; const int argc = 2; const char *argv[3] = { 0 }; apr_status_t apr_err; svn_error_t *err; argv[0] = "opt-test"; argv[1] = input; argv[2] = NULL; apr_err = apr_getopt_init(&os, pool, argc, argv); if (apr_err) return svn_error_wrap_apr(apr_err, "Error initializing command line arguments"); err = svn_opt_args_to_target_array2(&targets, os, NULL, pool); if (expected_output) { const char *actual_output; if (err) return err; if (argc - 1 != targets->nelts) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "Passed %d target(s) to " "svn_opt_args_to_target_array2() but " "got %d back.", argc - 1, targets->nelts); actual_output = APR_ARRAY_IDX(targets, 0, const char *); if (! svn_path_is_canonical(actual_output, pool)) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "Input '%s' to " "svn_opt_args_to_target_array2() should " "have returned a canonical path but " "'%s' is not.", input, actual_output); if (strcmp(expected_output, actual_output) != 0) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "Input '%s' to " "svn_opt_args_to_target_array2() should " "have returned '%s' but returned '%s'.", input, expected_output, actual_output); } else { if (! err) return svn_error_createf(SVN_ERR_TEST_FAILED, NULL, "Unexpected success in passing '%s' " "to svn_opt_args_to_target_array2().", input); } }