static apr_status_t close_wcroot(void *data) { svn_wc__db_wcroot_t *wcroot = data; svn_error_t *err; SVN_ERR_ASSERT_NO_RETURN(wcroot->sdb != NULL); #if defined(VERIFY_ON_CLOSE) && defined(SVN_DEBUG) if (getenv("SVN_CMDLINE_VERIFY_SQL_AT_CLOSE")) { apr_pool_t *scratch_pool = svn_pool_create(NULL); svn_error_clear(svn_wc__db_verify_db_full_internal( wcroot, verify_db_cb, NULL, scratch_pool)); svn_pool_destroy(scratch_pool); } #endif err = svn_sqlite__close(wcroot->sdb); wcroot->sdb = NULL; if (err) { apr_status_t result = err->apr_err; svn_error_clear(err); return result; } return APR_SUCCESS; }
svn_wc_conflict_version_t * svn_wc_conflict_version_create2(const char *repos_url, const char *repos_uuid, const char *repos_relpath, svn_revnum_t revision, svn_node_kind_t kind, apr_pool_t *result_pool) { svn_wc_conflict_version_t *version; version = apr_pcalloc(result_pool, sizeof(*version)); SVN_ERR_ASSERT_NO_RETURN(svn_uri_is_canonical(repos_url, result_pool) && svn_relpath_is_canonical(repos_relpath) && SVN_IS_VALID_REVNUM(revision) /* ### repos_uuid can be NULL :( */); version->repos_url = repos_url; version->peg_rev = revision; version->path_in_repos = repos_relpath; version->node_kind = kind; version->repos_uuid = repos_uuid; return version; }
/* Push information about another directory onto the linked list RB->db. * * CHILD_BATON is the baton returned by the commit editor. RELPATH is the * repository-relative path of this directory. IS_ADDED is true iff this * directory is being added (with or without history). If added with * history then COPYFROM_PATH/COPYFROM_REV are the copyfrom source, else * are NULL/SVN_INVALID_REVNUM. */ static void push_directory(struct revision_baton *rb, void *child_baton, const char *relpath, svn_boolean_t is_added, const char *copyfrom_path, svn_revnum_t copyfrom_rev) { struct directory_baton *child_db = apr_pcalloc(rb->pool, sizeof (*child_db)); SVN_ERR_ASSERT_NO_RETURN( is_added || (copyfrom_path == NULL && copyfrom_rev == SVN_INVALID_REVNUM)); /* If this node is an existing (not newly added) child of a copied node, calculate where it was copied from. */ if (!is_added && ARE_VALID_COPY_ARGS(rb->db->copyfrom_path, rb->db->copyfrom_rev)) { const char *name = svn_relpath_basename(relpath, NULL); copyfrom_path = svn_relpath_join(rb->db->copyfrom_path, name, rb->pool); copyfrom_rev = rb->db->copyfrom_rev; } child_db->baton = child_baton; child_db->relpath = relpath; child_db->copyfrom_path = copyfrom_path; child_db->copyfrom_rev = copyfrom_rev; child_db->parent = rb->db; rb->db = child_db; }
svn_client__pathrev_t * svn_client__pathrev_create(const char *repos_root_url, const char *repos_uuid, svn_revnum_t rev, const char *url, apr_pool_t *result_pool) { svn_client__pathrev_t *loc = apr_palloc(result_pool, sizeof(*loc)); SVN_ERR_ASSERT_NO_RETURN(svn_path_is_url(repos_root_url)); SVN_ERR_ASSERT_NO_RETURN(svn_path_is_url(url)); loc->repos_root_url = apr_pstrdup(result_pool, repos_root_url); loc->repos_uuid = apr_pstrdup(result_pool, repos_uuid); loc->rev = rev; loc->url = apr_pstrdup(result_pool, url); return loc; }
void svn_skel__prepend(svn_skel_t *skel, svn_skel_t *list_skel) { /* If list_skel isn't even a list, somebody's not using this function properly. */ SVN_ERR_ASSERT_NO_RETURN(! list_skel->is_atom); skel->next = list_skel->children; list_skel->children = skel; }
/* Append the concrete representation of SKEL to the string STR. Grow S with new space from POOL as necessary. */ static svn_stringbuf_t * unparse(const svn_skel_t *skel, svn_stringbuf_t *str, apr_pool_t *pool) { if (skel->is_atom) { /* Append an atom to STR. */ if (use_implicit(skel)) svn_stringbuf_appendbytes(str, skel->data, skel->len); else { /* Append the length to STR. */ char buf[200]; int length_len; length_len = putsize(buf, sizeof(buf), skel->len); SVN_ERR_ASSERT_NO_RETURN(length_len > 0); /* Make sure we have room for the length, the space, and the atom's contents. */ svn_stringbuf_ensure(str, str->len + length_len + 1 + skel->len); svn_stringbuf_appendbytes(str, buf, length_len); str->data[str->len++] = ' '; svn_stringbuf_appendbytes(str, skel->data, skel->len); } } else { /* Append a list to STR. */ svn_skel_t *child; /* Emit an opening parenthesis. */ svn_stringbuf_ensure(str, str->len + 1); str->data[str->len++] = '('; /* Append each element. Emit a space between each pair of elements. */ for (child = skel->children; child; child = child->next) { unparse(child, str, pool); if (child->next) { svn_stringbuf_ensure(str, str->len + 1); str->data[str->len++] = ' '; } } /* Emit a closing parenthesis. */ svn_stringbuf_appendbyte(str, ')'); } return str; }
svn_client__pathrev_t * svn_client__pathrev_create_with_relpath(const char *repos_root_url, const char *repos_uuid, svn_revnum_t rev, const char *relpath, apr_pool_t *result_pool) { SVN_ERR_ASSERT_NO_RETURN(svn_relpath_is_canonical(relpath)); return svn_client__pathrev_create( repos_root_url, repos_uuid, rev, svn_path_url_add_component2(repos_root_url, relpath, result_pool), result_pool); }
/* If the components of RELPATH exactly match (after being URI-encoded) the final components of URL, return a copy of URL minus those components allocated in RESULT_POOL; otherwise, return NULL. */ static const char * url_remove_final_relpath(const char *url, const char *relpath, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { char *result = apr_pstrdup(result_pool, url); char *result_end; const char *relpath_end; SVN_ERR_ASSERT_NO_RETURN(svn_path_is_url(url)); SVN_ERR_ASSERT_NO_RETURN(svn_relpath_is_canonical(relpath)); if (relpath[0] == 0) return result; relpath = svn_path_uri_encode(relpath, scratch_pool); result_end = result + strlen(result) - 1; relpath_end = relpath + strlen(relpath) - 1; while (relpath_end >= relpath) { if (*result_end != *relpath_end) return NULL; relpath_end--; result_end--; } if (*result_end != '/') return NULL; *result_end = 0; return result; }
void svn_skel__append(svn_skel_t *list_skel, svn_skel_t *skel) { SVN_ERR_ASSERT_NO_RETURN(list_skel != NULL && !list_skel->is_atom); if (list_skel->children == NULL) { list_skel->children = skel; } else { list_skel = list_skel->children; while (list_skel->next != NULL) list_skel = list_skel->next; list_skel->next = skel; } }
svn_wc_conflict_description2_t * svn_wc_conflict_description_create_text2(const char *local_abspath, apr_pool_t *result_pool) { svn_wc_conflict_description2_t *conflict; SVN_ERR_ASSERT_NO_RETURN(svn_dirent_is_absolute(local_abspath)); conflict = apr_pcalloc(result_pool, sizeof(*conflict)); conflict->local_abspath = apr_pstrdup(result_pool, local_abspath); conflict->node_kind = svn_node_file; conflict->kind = svn_wc_conflict_kind_text; conflict->action = svn_wc_conflict_action_edit; conflict->reason = svn_wc_conflict_reason_edited; return conflict; }
/* Append the concrete representation of SKEL to the string STR. */ static svn_stringbuf_t * unparse(const svn_skel_t *skel, svn_stringbuf_t *str) { if (skel->is_atom) { /* Append an atom to STR. */ if (use_implicit(skel)) svn_stringbuf_appendbytes(str, skel->data, skel->len); else { /* Append the length to STR. Ensure enough space for at least * one 64 bit int. */ char buf[200 + SVN_INT64_BUFFER_SIZE]; apr_size_t length_len; length_len = svn__ui64toa(buf, skel->len); SVN_ERR_ASSERT_NO_RETURN(length_len > 0); /* Make sure we have room for the length, the space, and the atom's contents. */ svn_stringbuf_ensure(str, str->len + length_len + 1 + skel->len); svn_stringbuf_appendbytes(str, buf, length_len); svn_stringbuf_appendbyte(str, ' '); svn_stringbuf_appendbytes(str, skel->data, skel->len); } } else { /* Append a list to STR: an opening parenthesis, the list elements * separated by a space, and a closing parenthesis. */ svn_skel_t *child; svn_stringbuf_appendbyte(str, '('); for (child = skel->children; child; child = child->next) { unparse(child, str); if (child->next) svn_stringbuf_appendbyte(str, ' '); } svn_stringbuf_appendbyte(str, ')'); } return str; }
svn_wc_conflict_description2_t * svn_wc_conflict_description_create_prop2(const char *local_abspath, svn_node_kind_t node_kind, const char *property_name, apr_pool_t *result_pool) { svn_wc_conflict_description2_t *conflict; SVN_ERR_ASSERT_NO_RETURN(svn_dirent_is_absolute(local_abspath)); conflict = apr_pcalloc(result_pool, sizeof(*conflict)); conflict->local_abspath = apr_pstrdup(result_pool, local_abspath); conflict->node_kind = node_kind; conflict->kind = svn_wc_conflict_kind_property; conflict->property_name = apr_pstrdup(result_pool, property_name); return conflict; }
void svn_config_set(svn_config_t *cfg, const char *section, const char *option, const char *value) { cfg_section_t *sec; cfg_option_t *opt; /* Ignore write attempts to r/o configurations. * * Since we should never try to modify r/o data, trigger an assertion * in debug mode. */ #ifdef SVN_DEBUG SVN_ERR_ASSERT_NO_RETURN(!cfg->read_only); #endif if (cfg->read_only) return; remove_expansions(cfg); opt = find_option(cfg, section, option, &sec); if (opt != NULL) { /* Replace the option's value. */ opt->value = apr_pstrdup(cfg->pool, value); opt->expanded = FALSE; return; } /* Create a new option */ svn_config_create_option(&opt, option, value, cfg->option_names_case_sensitive, cfg->pool); if (sec == NULL) { /* Even the section doesn't exist. Create it. */ sec = svn_config_addsection(cfg, section); } svn_hash_sets(sec->options, opt->hash_key, opt); }
/* Prepends a new lcs chunk for the amount of LINES at the given positions * POS0_OFFSET and POS1_OFFSET to the given LCS chain, and returns it. * This function assumes LINES > 0. */ static svn_diff__lcs_t * prepend_lcs(svn_diff__lcs_t *lcs, apr_off_t lines, apr_off_t pos0_offset, apr_off_t pos1_offset, apr_pool_t *pool) { svn_diff__lcs_t *new_lcs; SVN_ERR_ASSERT_NO_RETURN(lines > 0); new_lcs = apr_palloc(pool, sizeof(*new_lcs)); new_lcs->position[0] = apr_pcalloc(pool, sizeof(*new_lcs->position[0])); new_lcs->position[0]->offset = pos0_offset; new_lcs->position[1] = apr_pcalloc(pool, sizeof(*new_lcs->position[1])); new_lcs->position[1]->offset = pos1_offset; new_lcs->length = lines; new_lcs->refcount = 1; new_lcs->next = lcs; return new_lcs; }
/* Make a directory baton to represent the directory was path (relative to EDIT_BATON's path) is PATH. CMP_PATH/CMP_REV are the path/revision against which this directory should be compared for changes. If either is omitted (NULL for the path, SVN_INVALID_REVNUM for the rev), just compare this directory PATH against itself in the previous revision. PARENT_DIR_BATON is the directory baton of this directory's parent, or NULL if this is the top-level directory of the edit. ADDED indicated if this directory is newly added in this revision. Perform all allocations in POOL. */ static struct dir_baton * make_dir_baton(const char *path, const char *cmp_path, svn_revnum_t cmp_rev, void *edit_baton, void *parent_dir_baton, svn_boolean_t added, apr_pool_t *pool) { struct edit_baton *eb = edit_baton; struct dir_baton *pb = parent_dir_baton; struct dir_baton *new_db = apr_pcalloc(pool, sizeof(*new_db)); const char *full_path; /* A path relative to nothing? I don't think so. */ SVN_ERR_ASSERT_NO_RETURN(!path || pb); /* Construct the full path of this node. */ if (pb) full_path = svn_relpath_join(eb->path, path, pool); else full_path = apr_pstrdup(pool, eb->path); /* Remove leading slashes from copyfrom paths. */ if (cmp_path) cmp_path = svn_relpath_canonicalize(cmp_path, pool); new_db->edit_baton = eb; new_db->parent_dir_baton = pb; new_db->path = full_path; new_db->cmp_path = cmp_path; new_db->cmp_rev = cmp_rev; new_db->added = added; new_db->written_out = FALSE; new_db->deleted_entries = apr_hash_make(pool); new_db->pool = pool; return new_db; }
static void mark_parent_stable(const svn_editor_t *editor, const char *relpath) { const char *parent = svn_relpath_dirname(relpath, editor->scratch_pool); const void *marker = svn_hash_gets(editor->completed_nodes, parent); /* If RELPATH has already been marked (to disallow adds, or that it has been fully-completed), then do nothing. */ if (marker == MARKER_ALLOW_ALTER || marker == MARKER_DONE || marker == MARKER_ADDED_DIR) return; /* If the marker is MARKER_ALLOW_ADD, then that means the parent was moved away. There is no way to work on a child. That should have been tested before we got here by VERIFY_PARENT_MAY_EXIST(). */ SVN_ERR_ASSERT_NO_RETURN(marker != MARKER_ALLOW_ADD); /* MARKER is NULL. Upgrade it to MARKER_ALLOW_ALTER. */ MARK_RELPATH(editor, parent, MARKER_ALLOW_ALTER); }
svn_wc_conflict_description2_t * svn_wc_conflict_description_create_tree2( const char *local_abspath, svn_node_kind_t node_kind, svn_wc_operation_t operation, const svn_wc_conflict_version_t *src_left_version, const svn_wc_conflict_version_t *src_right_version, apr_pool_t *result_pool) { svn_wc_conflict_description2_t *conflict; SVN_ERR_ASSERT_NO_RETURN(svn_dirent_is_absolute(local_abspath)); conflict = apr_pcalloc(result_pool, sizeof(*conflict)); conflict->local_abspath = apr_pstrdup(result_pool, local_abspath); conflict->node_kind = node_kind; conflict->kind = svn_wc_conflict_kind_tree; conflict->operation = operation; conflict->src_left_version = svn_wc_conflict_version_dup(src_left_version, result_pool); conflict->src_right_version = svn_wc_conflict_version_dup(src_right_version, result_pool); return conflict; }
/* Prepare LINE for display, pruning or extending it to an appropriate * display width, and stripping the EOL marker, if any. * This function assumes that the data in LINE is encoded in UTF-8. */ static const char * prepare_line_for_display(const char *line, apr_pool_t *pool) { svn_stringbuf_t *buf = svn_stringbuf_create(line, pool); size_t width; size_t line_width = LINE_DISPLAY_WIDTH; apr_pool_t *iterpool; /* Trim EOL. */ if (buf->len >= 2 && buf->data[buf->len - 2] == '\r' && buf->data[buf->len - 1] == '\n') svn_stringbuf_chop(buf, 2); else if (buf->len >= 1 && (buf->data[buf->len - 1] == '\n' || buf->data[buf->len - 1] == '\r')) svn_stringbuf_chop(buf, 1); /* Determine the on-screen width of the line. */ width = svn_utf_cstring_utf8_width(buf->data); if (width == -1) { /* Determining the width failed. Try to get rid of unprintable * characters in the line buffer. */ buf = svn_stringbuf_create(svn_xml_fuzzy_escape(buf->data, pool), pool); width = svn_utf_cstring_utf8_width(buf->data); if (width == -1) width = buf->len; /* fallback: buffer length */ } /* Trim further in case line is still too long, or add padding in case * it is too short. */ iterpool = svn_pool_create(pool); while (width > line_width) { const char *last_valid; svn_pool_clear(iterpool); svn_stringbuf_chop(buf, 1); /* Be careful not to invalidate the UTF-8 string by trimming * just part of a character. */ last_valid = svn_utf__last_valid(buf->data, buf->len); if (last_valid < buf->data + buf->len) svn_stringbuf_chop(buf, (buf->data + buf->len) - last_valid); width = svn_utf_cstring_utf8_width(buf->data); if (width == -1) width = buf->len; /* fallback: buffer length */ } svn_pool_destroy(iterpool); while (width == 0 || width < line_width) { svn_stringbuf_appendbyte(buf, ' '); width++; } SVN_ERR_ASSERT_NO_RETURN(width == line_width); return buf->data; }