⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editor.c

📁 subversion-1.4.3-1.tar.gz 配置svn的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * editor.c :  Driving and consuming an editor across an svn connection * * ==================================================================== * Copyright (c) 2000-2006 CollabNet.  All rights reserved. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution.  The terms * are also available at http://subversion.tigris.org/license-1.html. * If newer versions of this license are posted there, you may use a * newer version instead, at your option. * * This software consists of voluntary contributions made by many * individuals.  For exact contribution history, see the revision * history and logs, available at http://subversion.tigris.org/. * ==================================================================== */#define APR_WANT_STRFUNC#include <apr_want.h>#include <apr_general.h>#include <apr_strings.h>#include <apr_md5.h>#include <assert.h>#include "svn_types.h"#include "svn_string.h"#include "svn_error.h"#include "svn_path.h"#include "svn_delta.h"#include "svn_ra_svn.h"#include "svn_pools.h"#include "svn_private_config.h"#include "ra_svn.h"/* * Both the client and server in the svn protocol need to drive and * consume editors.  For a commit, the client drives and the server * consumes; for an update/switch/status/diff, the server drives and * the client consumes.  This file provides a generic framework for * marshalling and unmarshalling editor operations over an svn * connection; both ends are useful for both server and client. */typedef struct {  svn_ra_svn_conn_t *conn;  svn_ra_svn_edit_callback callback;    /* Called on successful completion. */  void *callback_baton;  int next_token;} ra_svn_edit_baton_t;/* Works for both directories and files. */typedef struct {  svn_ra_svn_conn_t *conn;  apr_pool_t *pool;  ra_svn_edit_baton_t *eb;  const char *token;} ra_svn_baton_t;typedef struct {  const svn_delta_editor_t *editor;  void *edit_baton;  apr_hash_t *tokens;  svn_boolean_t *aborted;  apr_pool_t *pool;  svn_boolean_t for_replay;} ra_svn_driver_state_t;typedef struct {  const char *token;  void *baton;  svn_error_t *err;                     /* Tracks delayed errors. */  apr_pool_t *pool;} ra_svn_token_entry_t;/* --- CONSUMING AN EDITOR BY PASSING EDIT OPERATIONS OVER THE NET --- */static const char *make_token(char type, ra_svn_edit_baton_t *eb,                              apr_pool_t *pool){  return apr_psprintf(pool, "%c%d", type, eb->next_token++);}static ra_svn_baton_t *ra_svn_make_baton(svn_ra_svn_conn_t *conn,                                         apr_pool_t *pool,                                         ra_svn_edit_baton_t *eb,                                         const char *token){  ra_svn_baton_t *b;  b = apr_palloc(pool, sizeof(*b));  b->conn = conn;  b->pool = pool;  b->eb = eb;  b->token = token;  return b;}static svn_error_t *ra_svn_target_rev(void *edit_baton, svn_revnum_t rev,                                      apr_pool_t *pool){  ra_svn_edit_baton_t *eb = edit_baton;  SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "target-rev", "r", rev));  SVN_ERR(svn_ra_svn_read_cmd_response(eb->conn, pool, ""));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_open_root(void *edit_baton, svn_revnum_t rev,                                     apr_pool_t *pool, void **root_baton){  ra_svn_edit_baton_t *eb = edit_baton;  const char *token = make_token('d', eb, pool);  SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "open-root", "(?r)c", rev,                               token));  SVN_ERR(svn_ra_svn_read_cmd_response(eb->conn, pool, ""));  *root_baton = ra_svn_make_baton(eb->conn, pool, eb, token);  return SVN_NO_ERROR;}static svn_error_t *ra_svn_delete_entry(const char *path, svn_revnum_t rev,                                        void *parent_baton, apr_pool_t *pool){  ra_svn_baton_t *b = parent_baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "delete-entry", "c(?r)c",                               path, rev, b->token));  SVN_ERR(svn_ra_svn_read_cmd_response(b->conn, pool, ""));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_add_dir(const char *path, void *parent_baton,                                   const char *copy_path,                                   svn_revnum_t copy_rev,                                   apr_pool_t *pool, void **child_baton){  ra_svn_baton_t *b = parent_baton;  const char *token = make_token('d', b->eb, pool);  assert((copy_path && SVN_IS_VALID_REVNUM(copy_rev))         || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev)));  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "add-dir", "ccc(?cr)", path,                               b->token, token, copy_path, copy_rev));  SVN_ERR(svn_ra_svn_read_cmd_response(b->conn, pool, ""));  *child_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);  return SVN_NO_ERROR;}static svn_error_t *ra_svn_open_dir(const char *path, void *parent_baton,                                    svn_revnum_t rev, apr_pool_t *pool,                                    void **child_baton){  ra_svn_baton_t *b = parent_baton;  const char *token = make_token('d', b->eb, pool);  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "open-dir", "ccc(?r)",                               path, b->token, token, rev));  SVN_ERR(svn_ra_svn_read_cmd_response(b->conn, pool, ""));  *child_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);  return SVN_NO_ERROR;}static svn_error_t *ra_svn_change_dir_prop(void *dir_baton, const char *name,                                           const svn_string_t *value,                                           apr_pool_t *pool){  ra_svn_baton_t *b = dir_baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "change-dir-prop", "cc(?s)",                               b->token, name, value));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_close_dir(void *dir_baton, apr_pool_t *pool){  ra_svn_baton_t *b = dir_baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "close-dir", "c", b->token));  SVN_ERR(svn_ra_svn_read_cmd_response(b->conn, pool, ""));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_add_file(const char *path,                                    void *parent_baton,                                    const char *copy_path,                                    svn_revnum_t copy_rev,                                    apr_pool_t *pool,                                    void **file_baton){  ra_svn_baton_t *b = parent_baton;  const char *token = make_token('c', b->eb, pool);  assert((copy_path && SVN_IS_VALID_REVNUM(copy_rev))         || (!copy_path && !SVN_IS_VALID_REVNUM(copy_rev)));  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "add-file", "ccc(?cr)", path,                               b->token, token, copy_path, copy_rev));  *file_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);  return SVN_NO_ERROR;}static svn_error_t *ra_svn_open_file(const char *path,                                     void *parent_baton,                                     svn_revnum_t rev,                                     apr_pool_t *pool,                                     void **file_baton){  ra_svn_baton_t *b = parent_baton;  const char *token = make_token('c', b->eb, pool);  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "open-file", "ccc(?r)",                               path, b->token, token, rev));  *file_baton = ra_svn_make_baton(b->conn, pool, b->eb, token);  return SVN_NO_ERROR;}static svn_error_t *ra_svn_svndiff_handler(void *baton, const char *data,                                           apr_size_t *len){  ra_svn_baton_t *b = baton;  svn_string_t str;  str.data = data;  str.len = *len;  return svn_ra_svn_write_string(b->conn, b->pool, &str);}static svn_error_t *ra_svn_svndiff_close_handler(void *baton){  ra_svn_baton_t *b = baton;  SVN_ERR(svn_ra_svn_write_cstring(b->conn, b->pool, ""));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_apply_textdelta(void *file_baton,                                           const char *base_checksum,                                           apr_pool_t *pool,                                           svn_txdelta_window_handler_t *wh,                                           void **wh_baton){  ra_svn_baton_t *b = file_baton;  svn_stream_t *diff_stream;  /* Tell the other side we're starting a text delta. */  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "apply-textdelta", "c(?c)",                               b->token, base_checksum));  /* Transform the window stream to an svndiff stream.  Reuse the   * file baton for the stream handler, since it has all the   * needed information. */  diff_stream = svn_stream_create(b, pool);  svn_stream_set_write(diff_stream, ra_svn_svndiff_handler);  svn_stream_set_close(diff_stream, ra_svn_svndiff_close_handler);  if (svn_ra_svn_has_capability(b->conn, SVN_RA_SVN_CAP_SVNDIFF1))    svn_txdelta_to_svndiff2(wh, wh_baton, diff_stream, 1, pool);  else    svn_txdelta_to_svndiff2(wh, wh_baton, diff_stream, 0, pool);  return SVN_NO_ERROR;}  static svn_error_t *ra_svn_change_file_prop(void *file_baton,                                            const char *name,                                            const svn_string_t *value,                                            apr_pool_t *pool){  ra_svn_baton_t *b = file_baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "change-file-prop", "cc(?s)",                               b->token, name, value));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_close_file(void *file_baton,                                      const char *text_checksum,                                      apr_pool_t *pool){  ra_svn_baton_t *b = file_baton;  SVN_ERR(svn_ra_svn_write_cmd(b->conn, pool, "close-file", "c(?c)",                               b->token, text_checksum));  SVN_ERR(svn_ra_svn_read_cmd_response(b->conn, pool, ""));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_close_edit(void *edit_baton, apr_pool_t *pool){  ra_svn_edit_baton_t *eb = edit_baton;  SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "close-edit", ""));  SVN_ERR(svn_ra_svn_read_cmd_response(eb->conn, pool, ""));  if (eb->callback)    SVN_ERR(eb->callback(eb->callback_baton));  return SVN_NO_ERROR;}static svn_error_t *ra_svn_abort_edit(void *edit_baton, apr_pool_t *pool){  ra_svn_edit_baton_t *eb = edit_baton;  SVN_ERR(svn_ra_svn_write_cmd(eb->conn, pool, "abort-edit", ""));  SVN_ERR(svn_ra_svn_read_cmd_response(eb->conn, pool, ""));  return SVN_NO_ERROR;}void svn_ra_svn_get_editor(const svn_delta_editor_t **editor,                           void **edit_baton, svn_ra_svn_conn_t *conn,                           apr_pool_t *pool, svn_ra_svn_edit_callback callback,                           void *callback_baton){  svn_delta_editor_t *ra_svn_editor;  ra_svn_edit_baton_t *eb;  if (svn_ra_svn_has_capability(conn, SVN_RA_SVN_CAP_EDIT_PIPELINE))    {      svn_ra_svn__get_editorp(editor, edit_baton, conn, pool, callback,                              callback_baton);      return;    }  eb = apr_palloc(pool, sizeof(*eb));  eb->conn = conn;  eb->callback = callback;  eb->callback_baton = callback_baton;  eb->next_token = 0;  ra_svn_editor = svn_delta_default_editor(pool);  ra_svn_editor->set_target_revision = ra_svn_target_rev;  ra_svn_editor->open_root = ra_svn_open_root;  ra_svn_editor->delete_entry = ra_svn_delete_entry;  ra_svn_editor->add_directory = ra_svn_add_dir;  ra_svn_editor->open_directory = ra_svn_open_dir;  ra_svn_editor->change_dir_prop = ra_svn_change_dir_prop;  ra_svn_editor->close_directory = ra_svn_close_dir;  ra_svn_editor->add_file = ra_svn_add_file;  ra_svn_editor->open_file = ra_svn_open_file;  ra_svn_editor->apply_textdelta = ra_svn_apply_textdelta;  ra_svn_editor->change_file_prop = ra_svn_change_file_prop;  ra_svn_editor->close_file = ra_svn_close_file;  ra_svn_editor->close_edit = ra_svn_close_edit;  ra_svn_editor->abort_edit = ra_svn_abort_edit;  *editor = ra_svn_editor;  *edit_baton = eb;}/* --- DRIVING AN EDITOR --- */static apr_status_t clear_token_err(void *arg){  ra_svn_token_entry_t *entry = arg;  svn_error_clear(entry->err);  return APR_SUCCESS;}/* Store a token entry.  The token string will be copied into pool. */static ra_svn_token_entry_t *store_token(ra_svn_driver_state_t *ds,                                         void *baton, const char *token,                                         apr_pool_t *pool){  ra_svn_token_entry_t *entry;  entry = apr_palloc(pool, sizeof(*entry));  entry->token = apr_pstrdup(pool, token);  entry->baton = baton;  entry->err = NULL;  entry->pool = pool;  apr_hash_set(ds->tokens, entry->token, APR_HASH_KEY_STRING, entry);  apr_pool_cleanup_register(pool, entry, clear_token_err,                            apr_pool_cleanup_null);  return entry;}static svn_error_t *lookup_token(ra_svn_driver_state_t *ds, const char *token,                                 ra_svn_token_entry_t **entry,                                 apr_pool_t *pool){  *entry = apr_hash_get(ds->tokens, token, APR_HASH_KEY_STRING);  if (!*entry)    return svn_error_create(SVN_ERR_RA_SVN_MALFORMED_DATA, NULL,                            _("Invalid file or dir token during edit"));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -