void svn_cl__print_xml_lock(svn_stringbuf_t **sb, const svn_lock_t *lock, apr_pool_t *pool) { /* "<lock>" */ svn_xml_make_open_tag(sb, pool, svn_xml_normal, "lock", SVN_VA_NULL); /* "<token>xx</token>" */ svn_cl__xml_tagged_cdata(sb, pool, "token", lock->token); /* "<owner>xx</owner>" */ svn_cl__xml_tagged_cdata(sb, pool, "owner", lock->owner); /* "<comment>xx</comment>" */ svn_cl__xml_tagged_cdata(sb, pool, "comment", lock->comment); /* "<created>xx</created>" */ svn_cl__xml_tagged_cdata(sb, pool, "created", svn_time_to_cstring(lock->creation_date, pool)); /* "<expires>xx</expires>" */ if (lock->expiration_date != 0) svn_cl__xml_tagged_cdata(sb, pool, "expires", svn_time_to_cstring(lock->expiration_date, pool)); /* "</lock>" */ svn_xml_make_close_tag(sb, pool, "lock"); }
void svn_cl__print_xml_commit(svn_stringbuf_t **sb, svn_revnum_t revision, const char *author, const char *date, apr_pool_t *pool) { /* "<commit ...>" */ svn_xml_make_open_tag(sb, pool, svn_xml_normal, "commit", "revision", apr_psprintf(pool, "%ld", revision), SVN_VA_NULL); /* "<author>xx</author>" */ if (author) svn_cl__xml_tagged_cdata(sb, pool, "author", author); /* "<date>xx</date>" */ if (date) svn_cl__xml_tagged_cdata(sb, pool, "date", date); /* "</commit>" */ svn_xml_make_close_tag(sb, pool, "commit"); }
svn_error_t * svn_cl__print_status_xml(const char *path, svn_wc_status2_t *status, apr_pool_t *pool) { svn_stringbuf_t *sb = svn_stringbuf_create("", pool); apr_hash_t *att_hash; if (status->text_status == svn_wc_status_none && status->repos_text_status == svn_wc_status_none) return SVN_NO_ERROR; svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry", "path", svn_path_local_style(path, pool), NULL); att_hash = apr_hash_make(pool); apr_hash_set(att_hash, "item", APR_HASH_KEY_STRING, generate_status_desc(status->text_status)); apr_hash_set(att_hash, "props", APR_HASH_KEY_STRING, generate_status_desc(status->prop_status)); if (status->locked) apr_hash_set(att_hash, "wc-locked", APR_HASH_KEY_STRING, "true"); if (status->copied) apr_hash_set(att_hash, "copied", APR_HASH_KEY_STRING, "true"); if (status->switched) apr_hash_set(att_hash, "switched", APR_HASH_KEY_STRING, "true"); if (status->entry && ! status->entry->copied) apr_hash_set(att_hash, "revision", APR_HASH_KEY_STRING, apr_psprintf(pool, "%ld", status->entry->revision)); svn_xml_make_open_tag_hash(&sb, pool, svn_xml_normal, "wc-status", att_hash); if (status->entry && SVN_IS_VALID_REVNUM(status->entry->cmt_rev)) { svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "commit", "revision", apr_psprintf(pool, "%ld", status->entry->cmt_rev), NULL); svn_cl__xml_tagged_cdata(&sb, pool, "author", status->entry->cmt_author); if (status->entry->cmt_date) svn_cl__xml_tagged_cdata(&sb, pool, "date", svn_time_to_cstring (status->entry->cmt_date, pool)); svn_xml_make_close_tag(&sb, pool, "commit"); } if (status->entry && status->entry->lock_token) { svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "lock", NULL); svn_cl__xml_tagged_cdata(&sb, pool, "token", status->entry->lock_token); /* If lock_owner is NULL, assume WC is corrupt. */ if (status->entry->lock_owner) svn_cl__xml_tagged_cdata(&sb, pool, "owner", status->entry->lock_owner); else return svn_error_createf(SVN_ERR_WC_CORRUPT, NULL, _("'%s' has lock token, but no lock owner"), svn_path_local_style(path, pool)); svn_cl__xml_tagged_cdata(&sb, pool, "comment", status->entry->lock_comment); svn_cl__xml_tagged_cdata(&sb, pool, "created", svn_time_to_cstring (status->entry->lock_creation_date, pool)); svn_xml_make_close_tag(&sb, pool, "lock"); } svn_xml_make_close_tag(&sb, pool, "wc-status"); if (status->repos_text_status != svn_wc_status_none || status->repos_prop_status != svn_wc_status_none || status->repos_lock) { svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "repos-status", "item", generate_status_desc(status->repos_text_status), "props", generate_status_desc(status->repos_prop_status), NULL); if (status->repos_lock) { svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "lock", NULL); svn_cl__xml_tagged_cdata(&sb, pool, "token", status->repos_lock->token); svn_cl__xml_tagged_cdata(&sb, pool, "owner", status->repos_lock->owner); svn_cl__xml_tagged_cdata(&sb, pool, "comment", status->repos_lock->comment); svn_cl__xml_tagged_cdata(&sb, pool, "created", svn_time_to_cstring (status->repos_lock->creation_date, pool)); if (status->repos_lock->expiration_date != 0) { svn_cl__xml_tagged_cdata(&sb, pool, "expires", svn_time_to_cstring (status->repos_lock->expiration_date, pool)); } svn_xml_make_close_tag(&sb, pool, "lock"); } svn_xml_make_close_tag(&sb, pool, "repos-status"); } svn_xml_make_close_tag(&sb, pool, "entry"); return svn_cl__error_checked_fputs(sb->data, stdout); }
/* This implements `svn_log_entry_receiver_t', printing the logs in XML. * * BATON is of type `struct log_receiver_baton'. * * Here is an example of the output; note that the "<log>" and * "</log>" tags are not emitted by this function: * * $ svn log --xml -r 1648:1649 * <log> * <logentry * revision="1648"> * <author>david</author> * <date>2002-04-06T16:34:51.428043Z</date> * <msg> * packages/rpm/subversion.spec : Now requires apache 2.0.36. * </msg> * </logentry> * <logentry * revision="1649"> * <author>cmpilato</author> * <date>2002-04-06T17:01:28.185136Z</date> * <msg>Fix error handling when the $EDITOR is needed but unavailable. Ah * ... now that's *much* nicer. * * * subversion/clients/cmdline/util.c * (svn_cl__edit_externally): Clean up the "no external editor" * error message. * (svn_cl__get_log_message): Wrap "no external editor" * errors with helpful hints about the -m and -F options. * * * subversion/libsvn_client/commit.c * (svn_client_commit): Actually capture and propogate "no external * editor" errors.</msg> * </logentry> * </log> * */ static svn_error_t * log_entry_receiver_xml(void *baton, svn_log_entry_t *log_entry, apr_pool_t *pool) { struct log_receiver_baton *lb = baton; /* Collate whole log message into sb before printing. */ svn_stringbuf_t *sb = svn_stringbuf_create("", pool); char *revstr; const char *author; const char *date; const char *message; if (lb->cancel_func) SVN_ERR(lb->cancel_func(lb->cancel_baton)); svn_compat_log_revprops_out(&author, &date, &message, log_entry->revprops); if (author) author = svn_xml_fuzzy_escape(author, pool); if (date) date = svn_xml_fuzzy_escape(date, pool); if (message) message = svn_xml_fuzzy_escape(message, pool); if (log_entry->revision == 0 && message == NULL) return SVN_NO_ERROR; if (! SVN_IS_VALID_REVNUM(log_entry->revision)) { svn_xml_make_close_tag(&sb, pool, "logentry"); SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout)); apr_array_pop(lb->merge_stack); return SVN_NO_ERROR; } revstr = apr_psprintf(pool, "%ld", log_entry->revision); /* <logentry revision="xxx"> */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "logentry", "revision", revstr, NULL); /* <author>xxx</author> */ svn_cl__xml_tagged_cdata(&sb, pool, "author", author); /* Print the full, uncut, date. This is machine output. */ /* According to the docs for svn_log_entry_receiver_t, either NULL or the empty string represents no date. Avoid outputting an empty date element. */ if (date && date[0] == '\0') date = NULL; /* <date>xxx</date> */ svn_cl__xml_tagged_cdata(&sb, pool, "date", date); if (log_entry->changed_paths) { apr_hash_index_t *hi; char *path; /* <paths> */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "paths", NULL); for (hi = apr_hash_first(pool, log_entry->changed_paths); hi != NULL; hi = apr_hash_next(hi)) { void *val; char action[2]; svn_log_changed_path_t *log_item; apr_hash_this(hi, (void *) &path, NULL, &val); log_item = val; action[0] = log_item->action; action[1] = '\0'; if (log_item->copyfrom_path && SVN_IS_VALID_REVNUM(log_item->copyfrom_rev)) { /* <path action="X" copyfrom-path="xxx" copyfrom-rev="xxx"> */ svn_stringbuf_t *escpath = svn_stringbuf_create("", pool); svn_xml_escape_attr_cstring(&escpath, log_item->copyfrom_path, pool); revstr = apr_psprintf(pool, "%ld", log_item->copyfrom_rev); svn_xml_make_open_tag(&sb, pool, svn_xml_protect_pcdata, "path", "action", action, "copyfrom-path", escpath->data, "copyfrom-rev", revstr, NULL); } else { /* <path action="X"> */ svn_xml_make_open_tag(&sb, pool, svn_xml_protect_pcdata, "path", "action", action, NULL); } /* xxx</path> */ svn_xml_escape_cdata_cstring(&sb, path, pool); svn_xml_make_close_tag(&sb, pool, "path"); } /* </paths> */ svn_xml_make_close_tag(&sb, pool, "paths"); } if (message != NULL) { /* <msg>xxx</msg> */ svn_cl__xml_tagged_cdata(&sb, pool, "msg", message); } svn_compat_log_revprops_clear(log_entry->revprops); if (log_entry->revprops && apr_hash_count(log_entry->revprops) > 0) { svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "revprops", NULL); SVN_ERR(svn_cl__print_xml_prop_hash(&sb, log_entry->revprops, FALSE, /* name_only */ pool)); svn_xml_make_close_tag(&sb, pool, "revprops"); } if (log_entry->has_children) APR_ARRAY_PUSH(lb->merge_stack, svn_revnum_t) = log_entry->revision; else svn_xml_make_close_tag(&sb, pool, "logentry"); SVN_ERR(svn_cl__error_checked_fputs(sb->data, stdout)); return SVN_NO_ERROR; }
/* This implements the svn_client_list_func_t API, printing a single dirent in XML format. */ static svn_error_t * print_dirent_xml(void *baton, const char *path, const svn_dirent_t *dirent, const svn_lock_t *lock, const char *abs_path, apr_pool_t *pool) { struct print_baton *pb = baton; const char *entryname; svn_stringbuf_t *sb; if (strcmp(path, "") == 0) { if (dirent->kind == svn_node_file) entryname = svn_dirent_basename(abs_path, pool); else if (pb->verbose) entryname = "."; else /* Don't bother to list if no useful information will be shown. */ return SVN_NO_ERROR; } else entryname = path; if (pb->ctx->cancel_func) SVN_ERR(pb->ctx->cancel_func(pb->ctx->cancel_baton)); sb = svn_stringbuf_create("", pool); svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry", "kind", svn_cl__node_kind_str_xml(dirent->kind), NULL); svn_cl__xml_tagged_cdata(&sb, pool, "name", entryname); if (dirent->kind == svn_node_file) { svn_cl__xml_tagged_cdata (&sb, pool, "size", apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, dirent->size)); } svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "commit", "revision", apr_psprintf(pool, "%ld", dirent->created_rev), NULL); svn_cl__xml_tagged_cdata(&sb, pool, "author", dirent->last_author); if (dirent->time) svn_cl__xml_tagged_cdata(&sb, pool, "date", svn_time_to_cstring(dirent->time, pool)); svn_xml_make_close_tag(&sb, pool, "commit"); if (lock) { svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "lock", NULL); svn_cl__xml_tagged_cdata(&sb, pool, "token", lock->token); svn_cl__xml_tagged_cdata(&sb, pool, "owner", lock->owner); svn_cl__xml_tagged_cdata(&sb, pool, "comment", lock->comment); svn_cl__xml_tagged_cdata(&sb, pool, "created", svn_time_to_cstring(lock->creation_date, pool)); if (lock->expiration_date != 0) svn_cl__xml_tagged_cdata(&sb, pool, "expires", svn_time_to_cstring (lock->expiration_date, pool)); svn_xml_make_close_tag(&sb, pool, "lock"); } svn_xml_make_close_tag(&sb, pool, "entry"); return svn_cl__error_checked_fputs(sb->data, stdout); }
/* A callback of type svn_client_info_receiver2_t. Prints svn info in xml mode to standard out */ static svn_error_t * print_info_xml(void *baton, const char *target, const svn_client_info2_t *info, apr_pool_t *pool) { svn_stringbuf_t *sb = svn_stringbuf_create("", pool); const char *rev_str; const char *path_prefix = baton; if (SVN_IS_VALID_REVNUM(info->rev)) rev_str = apr_psprintf(pool, "%ld", info->rev); else rev_str = apr_pstrdup(pool, _("Resource is not under version control.")); /* "<entry ...>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry", "path", svn_cl__local_style_skip_ancestor( path_prefix, target, pool), "kind", svn_cl__node_kind_str_xml(info->kind), "revision", rev_str, NULL); svn_cl__xml_tagged_cdata(&sb, pool, "url", info->URL); if (info->repos_root_URL || info->repos_UUID) { /* "<repository>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "repository", NULL); /* "<root> xx </root>" */ svn_cl__xml_tagged_cdata(&sb, pool, "root", info->repos_root_URL); /* "<uuid> xx </uuid>" */ svn_cl__xml_tagged_cdata(&sb, pool, "uuid", info->repos_UUID); /* "</repository>" */ svn_xml_make_close_tag(&sb, pool, "repository"); } if (info->wc_info) { /* "<wc-info>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "wc-info", NULL); /* "<wcroot-abspath> xx </wcroot-abspath>" */ if (info->wc_info->wcroot_abspath) svn_cl__xml_tagged_cdata(&sb, pool, "wcroot-abspath", info->wc_info->wcroot_abspath); /* "<schedule> xx </schedule>" */ svn_cl__xml_tagged_cdata(&sb, pool, "schedule", schedule_str(info->wc_info->schedule)); /* "<depth> xx </depth>" */ { svn_depth_t depth = info->wc_info->depth; /* In the entries world info just passed depth infinity for files */ if (depth == svn_depth_unknown && info->kind == svn_node_file) depth = svn_depth_infinity; svn_cl__xml_tagged_cdata(&sb, pool, "depth", svn_depth_to_word(depth)); } /* "<copy-from-url> xx </copy-from-url>" */ svn_cl__xml_tagged_cdata(&sb, pool, "copy-from-url", info->wc_info->copyfrom_url); /* "<copy-from-rev> xx </copy-from-rev>" */ if (SVN_IS_VALID_REVNUM(info->wc_info->copyfrom_rev)) svn_cl__xml_tagged_cdata(&sb, pool, "copy-from-rev", apr_psprintf(pool, "%ld", info->wc_info->copyfrom_rev)); /* "<text-updated> xx </text-updated>" */ if (info->wc_info->recorded_time) svn_cl__xml_tagged_cdata(&sb, pool, "text-updated", svn_time_to_cstring( info->wc_info->recorded_time, pool)); /* "<checksum> xx </checksum>" */ /* ### Print the checksum kind. */ svn_cl__xml_tagged_cdata(&sb, pool, "checksum", svn_checksum_to_cstring(info->wc_info->checksum, pool)); if (info->wc_info->changelist) /* "<changelist> xx </changelist>" */ svn_cl__xml_tagged_cdata(&sb, pool, "changelist", info->wc_info->changelist); /* "</wc-info>" */ svn_xml_make_close_tag(&sb, pool, "wc-info"); } if (info->last_changed_author || SVN_IS_VALID_REVNUM(info->last_changed_rev) || info->last_changed_date) { svn_cl__print_xml_commit(&sb, info->last_changed_rev, info->last_changed_author, svn_time_to_cstring(info->last_changed_date, pool), pool); } if (info->wc_info && info->wc_info->conflicts) { int i; for (i = 0; i < info->wc_info->conflicts->nelts; i++) { const svn_wc_conflict_description2_t *conflict = APR_ARRAY_IDX(info->wc_info->conflicts, i, const svn_wc_conflict_description2_t *); switch (conflict->kind) { case svn_wc_conflict_kind_text: /* "<conflict>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "conflict", NULL); /* "<prev-base-file> xx </prev-base-file>" */ svn_cl__xml_tagged_cdata(&sb, pool, "prev-base-file", conflict->base_abspath); /* "<prev-wc-file> xx </prev-wc-file>" */ svn_cl__xml_tagged_cdata(&sb, pool, "prev-wc-file", conflict->my_abspath); /* "<cur-base-file> xx </cur-base-file>" */ svn_cl__xml_tagged_cdata(&sb, pool, "cur-base-file", conflict->their_abspath); /* "</conflict>" */ svn_xml_make_close_tag(&sb, pool, "conflict"); break; case svn_wc_conflict_kind_property: /* "<conflict>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "conflict", NULL); /* "<prop-file> xx </prop-file>" */ svn_cl__xml_tagged_cdata(&sb, pool, "prop-file", conflict->their_abspath); /* "</conflict>" */ svn_xml_make_close_tag(&sb, pool, "conflict"); break; case svn_wc_conflict_kind_tree: SVN_ERR(svn_cl__append_tree_conflict_info_xml(sb, conflict, pool)); break; } } }
/* A callback of type svn_info_receiver_t. Prints svn info in xml mode to standard out */ static svn_error_t * print_info_xml(void *baton, const char *target, const svn_info_t *info, apr_pool_t *pool) { svn_stringbuf_t *sb = svn_stringbuf_create("", pool); const char *rev_str; if (SVN_IS_VALID_REVNUM(info->rev)) rev_str = apr_psprintf(pool, "%ld", info->rev); else rev_str = apr_pstrdup(pool, _("Resource is not under version control.")); /* "<entry ...>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "entry", "path", svn_path_local_style(target, pool), "kind", svn_cl__node_kind_str_xml(info->kind), "revision", rev_str, NULL); svn_cl__xml_tagged_cdata(&sb, pool, "url", info->URL); if (info->repos_root_URL || info->repos_UUID) { /* "<repository>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "repository", NULL); /* "<root> xx </root>" */ svn_cl__xml_tagged_cdata(&sb, pool, "root", info->repos_root_URL); /* "<uuid> xx </uuid>" */ svn_cl__xml_tagged_cdata(&sb, pool, "uuid", info->repos_UUID); /* "</repository>" */ svn_xml_make_close_tag(&sb, pool, "repository"); } if (info->has_wc_info) { /* "<wc-info>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "wc-info", NULL); /* "<schedule> xx </schedule>" */ svn_cl__xml_tagged_cdata(&sb, pool, "schedule", schedule_str(info->schedule)); /* "<depth> xx </depth>" */ svn_cl__xml_tagged_cdata(&sb, pool, "depth", svn_depth_to_word(info->depth)); /* "<copy-from-url> xx </copy-from-url>" */ svn_cl__xml_tagged_cdata(&sb, pool, "copy-from-url", info->copyfrom_url); /* "<copy-from-rev> xx </copy-from-rev>" */ if (SVN_IS_VALID_REVNUM(info->copyfrom_rev)) svn_cl__xml_tagged_cdata(&sb, pool, "copy-from-rev", apr_psprintf(pool, "%ld", info->copyfrom_rev)); /* "<text-updated> xx </text-updated>" */ if (info->text_time) svn_cl__xml_tagged_cdata(&sb, pool, "text-updated", svn_time_to_cstring(info->text_time, pool)); /* "<checksum> xx </checksum>" */ svn_cl__xml_tagged_cdata(&sb, pool, "checksum", info->checksum); if (info->changelist) /* "<changelist> xx </changelist>" */ svn_cl__xml_tagged_cdata(&sb, pool, "changelist", info->changelist); /* "</wc-info>" */ svn_xml_make_close_tag(&sb, pool, "wc-info"); } if (info->last_changed_author || SVN_IS_VALID_REVNUM(info->last_changed_rev) || info->last_changed_date) { svn_cl__print_xml_commit(&sb, info->last_changed_rev, info->last_changed_author, svn_time_to_cstring(info->last_changed_date, pool), pool); } if (info->conflict_old || info->conflict_wrk || info->conflict_new || info->prejfile) { /* "<conflict>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "conflict", NULL); /* "<prev-base-file> xx </prev-base-file>" */ svn_cl__xml_tagged_cdata(&sb, pool, "prev-base-file", info->conflict_old); /* "<prev-wc-file> xx </prev-wc-file>" */ svn_cl__xml_tagged_cdata(&sb, pool, "prev-wc-file", info->conflict_wrk); /* "<cur-base-file> xx </cur-base-file>" */ svn_cl__xml_tagged_cdata(&sb, pool, "cur-base-file", info->conflict_new); /* "<prop-file> xx </prop-file>" */ svn_cl__xml_tagged_cdata(&sb, pool, "prop-file", info->prejfile); /* "</conflict>" */ svn_xml_make_close_tag(&sb, pool, "conflict"); } if (info->lock) { /* "<lock>" */ svn_xml_make_open_tag(&sb, pool, svn_xml_normal, "lock", NULL); /* "<token> xx </token>" */ svn_cl__xml_tagged_cdata(&sb, pool, "token", info->lock->token); /* "<owner> xx </owner>" */ svn_cl__xml_tagged_cdata(&sb, pool, "owner", info->lock->owner); /* "<comment ...> xxxx </comment>" */ svn_cl__xml_tagged_cdata(&sb, pool, "comment", info->lock->comment); /* "<created> xx </created>" */ svn_cl__xml_tagged_cdata(&sb, pool, "created", svn_time_to_cstring (info->lock->creation_date, pool)); /* "<expires> xx </expires>" */ svn_cl__xml_tagged_cdata(&sb, pool, "expires", svn_time_to_cstring (info->lock->expiration_date, pool)); /* "</lock>" */ svn_xml_make_close_tag(&sb, pool, "lock"); } if (info->tree_conflict) SVN_ERR(svn_cl__append_tree_conflict_info_xml(sb, info->tree_conflict, pool)); /* "</entry>" */ svn_xml_make_close_tag(&sb, pool, "entry"); return svn_cl__error_checked_fputs(sb->data, stdout); }