#include <stdbool.h>
#include <apr_md5.h>
#include <apr_sha1.h>
+#include <fcntl.h>
#include "util.h"
#include "editor.h"
#define T_BOOL T_BYTE
#endif
+typedef struct {
+ PyObject_HEAD
+ svn_lock_t lock;
+ apr_pool_t *pool;
+} LockObject;
+
+#if ONLY_SINCE_SVN(1, 7)
+typedef struct {
+ PyObject_VAR_HEAD
+ apr_pool_t *pool;
+ svn_wc_context_t *context;
+} ContextObject;
static PyTypeObject Context_Type;
+#endif
#if ONLY_BEFORE_SVN(1, 5)
struct svn_wc_committed_queue_t
{
- apr_pool_t *pool;
- apr_array_header_t *queue;
- svn_boolean_t have_recursive;
+ apr_pool_t *pool;
+ apr_array_header_t *queue;
+ svn_boolean_t have_recursive;
};
typedef struct
{
- const char *path;
- svn_wc_adm_access_t *adm_access;
- svn_boolean_t recurse;
- svn_boolean_t remove_lock;
- apr_array_header_t *wcprop_changes;
- unsigned char *digest;
+ const char *path;
+ svn_wc_adm_access_t *adm_access;
+ svn_boolean_t recurse;
+ svn_boolean_t remove_lock;
+ apr_array_header_t *wcprop_changes;
+ unsigned char *digest;
} committed_queue_item_t;
svn_wc_committed_queue_t *svn_wc_committed_queue_create(apr_pool_t *pool)
{
- svn_wc_committed_queue_t *q;
+ svn_wc_committed_queue_t *q;
- q = apr_palloc(pool, sizeof(*q));
- q->pool = pool;
- q->queue = apr_array_make(pool, 1, sizeof(committed_queue_item_t *));
- q->have_recursive = FALSE;
+ q = apr_palloc(pool, sizeof(*q));
+ q->pool = pool;
+ q->queue = apr_array_make(pool, 1, sizeof(committed_queue_item_t *));
+ q->have_recursive = FALSE;
- return q;
+ return q;
}
svn_error_t *svn_wc_queue_committed(svn_wc_committed_queue_t **queue,
#endif
typedef struct {
- PyObject_VAR_HEAD
- apr_pool_t *pool;
- svn_wc_committed_queue_t *queue;
+ PyObject_VAR_HEAD
+ apr_pool_t *pool;
+ svn_wc_committed_queue_t *queue;
} CommittedQueueObject;
svn_wc_committed_queue_t *PyObject_GetCommittedQueue(PyObject *obj)
}
#if ONLY_SINCE_SVN(1, 5)
-static svn_error_t *py_ra_report3_set_path(void *baton, const char *path, svn_revnum_t revision, svn_depth_t depth, int start_empty, const char *lock_token, apr_pool_t *pool)
+static svn_error_t *py_ra_report3_set_path(void *baton, const char *path,
+ svn_revnum_t revision,
+ svn_depth_t depth, int start_empty,
+ const char *lock_token, apr_pool_t *pool)
{
- PyObject *self = (PyObject *)baton, *py_lock_token, *ret;
- PyGILState_STATE state = PyGILState_Ensure();
- if (lock_token == NULL) {
- py_lock_token = Py_None;
- Py_INCREF(py_lock_token);
- } else {
- py_lock_token = PyBytes_FromString(lock_token);
- }
- ret = PyObject_CallMethod(self, "set_path", "slbOi", path, revision, start_empty, py_lock_token, depth);
- Py_DECREF(py_lock_token);
- CB_CHECK_PYRETVAL(ret);
- Py_DECREF(ret);
- PyGILState_Release(state);
- return NULL;
+ PyObject *self = (PyObject *)baton, *py_lock_token, *ret;
+ PyGILState_STATE state = PyGILState_Ensure();
+ if (lock_token == NULL) {
+ py_lock_token = Py_None;
+ Py_INCREF(py_lock_token);
+ } else {
+ py_lock_token = PyBytes_FromString(lock_token);
+ }
+ ret = PyObject_CallMethod(self, "set_path", "slbOi", path, revision,
+ start_empty, py_lock_token, depth);
+ Py_DECREF(py_lock_token);
+ CB_CHECK_PYRETVAL(ret);
+ Py_DECREF(ret);
+ PyGILState_Release(state);
+ return NULL;
}
-static svn_error_t *py_ra_report3_link_path(void *report_baton, const char *path, const char *url, svn_revnum_t revision, svn_depth_t depth, int start_empty, const char *lock_token, apr_pool_t *pool)
+static svn_error_t *py_ra_report3_link_path(void *report_baton,
+ const char *path, const char *url,
+ svn_revnum_t revision,
+ svn_depth_t depth, int start_empty,
+ const char *lock_token, apr_pool_t *pool)
{
- PyObject *self = (PyObject *)report_baton, *ret, *py_lock_token;
- PyGILState_STATE state = PyGILState_Ensure();
- if (lock_token == NULL) {
- py_lock_token = Py_None;
- Py_INCREF(py_lock_token);
- } else {
- py_lock_token = PyBytes_FromString(lock_token);
- }
- ret = PyObject_CallMethod(self, "link_path", "sslbOi", path, url, revision, start_empty, py_lock_token, depth);
- Py_DECREF(py_lock_token);
- CB_CHECK_PYRETVAL(ret);
- Py_DECREF(ret);
- PyGILState_Release(state);
- return NULL;
+ PyObject *self = (PyObject *)report_baton, *ret, *py_lock_token;
+ PyGILState_STATE state = PyGILState_Ensure();
+ if (lock_token == NULL) {
+ py_lock_token = Py_None;
+ Py_INCREF(py_lock_token);
+ } else {
+ py_lock_token = PyBytes_FromString(lock_token);
+ }
+ ret = PyObject_CallMethod(self, "link_path", "sslbOi", path, url, revision,
+ start_empty, py_lock_token, depth);
+ Py_DECREF(py_lock_token);
+ CB_CHECK_PYRETVAL(ret);
+ Py_DECREF(ret);
+ PyGILState_Release(state);
+ return NULL;
}
#endif
-static svn_error_t *py_ra_report2_set_path(void *baton, const char *path, svn_revnum_t revision, int start_empty, const char *lock_token, apr_pool_t *pool)
+static svn_error_t *py_ra_report2_set_path(void *baton, const char *path,
+ svn_revnum_t revision,
+ int start_empty, const char *lock_token,
+ apr_pool_t *pool)
{
- PyObject *self = (PyObject *)baton, *py_lock_token, *ret;
- PyGILState_STATE state = PyGILState_Ensure();
- if (lock_token == NULL) {
- py_lock_token = Py_None;
- Py_INCREF(py_lock_token);
- } else {
- py_lock_token = PyBytes_FromString(lock_token);
- }
- ret = PyObject_CallMethod(self, "set_path", "slbOi", path, revision, start_empty, py_lock_token, svn_depth_infinity);
- CB_CHECK_PYRETVAL(ret);
- Py_DECREF(ret);
- PyGILState_Release(state);
- return NULL;
+ PyObject *self = (PyObject *)baton, *py_lock_token, *ret;
+ PyGILState_STATE state = PyGILState_Ensure();
+ if (lock_token == NULL) {
+ py_lock_token = Py_None;
+ Py_INCREF(py_lock_token);
+ } else {
+ py_lock_token = PyBytes_FromString(lock_token);
+ }
+ ret = PyObject_CallMethod(self, "set_path", "slbOi", path, revision,
+ start_empty, py_lock_token, svn_depth_infinity);
+ CB_CHECK_PYRETVAL(ret);
+ Py_DECREF(ret);
+ PyGILState_Release(state);
+ return NULL;
}
-static svn_error_t *py_ra_report2_link_path(void *report_baton, const char *path, const char *url, svn_revnum_t revision, int start_empty, const char *lock_token, apr_pool_t *pool)
+static svn_error_t *py_ra_report2_link_path(void *report_baton,
+ const char *path, const char *url,
+ svn_revnum_t revision,
+ int start_empty,
+ const char *lock_token,
+ apr_pool_t *pool)
{
- PyObject *self = (PyObject *)report_baton, *ret, *py_lock_token;
- PyGILState_STATE state = PyGILState_Ensure();
- if (lock_token == NULL) {
- py_lock_token = Py_None;
- Py_INCREF(py_lock_token);
- } else {
- py_lock_token = PyBytes_FromString(lock_token);
- }
- ret = PyObject_CallMethod(self, "link_path", "sslbOi", path, url, revision, start_empty, py_lock_token, svn_depth_infinity);
- CB_CHECK_PYRETVAL(ret);
- Py_DECREF(ret);
- PyGILState_Release(state);
- return NULL;
+ PyObject *self = (PyObject *)report_baton, *ret, *py_lock_token;
+ PyGILState_STATE state = PyGILState_Ensure();
+ if (lock_token == NULL) {
+ py_lock_token = Py_None;
+ Py_INCREF(py_lock_token);
+ } else {
+ py_lock_token = PyBytes_FromString(lock_token);
+ }
+ ret = PyObject_CallMethod(self, "link_path", "sslbOi", path, url, revision,
+ start_empty, py_lock_token, svn_depth_infinity);
+ CB_CHECK_PYRETVAL(ret);
+ Py_DECREF(ret);
+ PyGILState_Release(state);
+ return NULL;
}
-static svn_error_t *py_ra_report_delete_path(void *baton, const char *path, apr_pool_t *pool)
+static svn_error_t *py_ra_report_delete_path(void *baton, const char *path,
+ apr_pool_t *pool)
{
- PyObject *self = (PyObject *)baton, *ret;
- PyGILState_STATE state = PyGILState_Ensure();
- ret = PyObject_CallMethod(self, "delete_path", "s", path);
- CB_CHECK_PYRETVAL(ret);
- Py_DECREF(ret);
- PyGILState_Release(state);
- return NULL;
+ PyObject *self = (PyObject *)baton, *ret;
+ PyGILState_STATE state = PyGILState_Ensure();
+ ret = PyObject_CallMethod(self, "delete_path", "s", path);
+ CB_CHECK_PYRETVAL(ret);
+ Py_DECREF(ret);
+ PyGILState_Release(state);
+ return NULL;
}
static svn_error_t *py_ra_report_finish(void *baton, apr_pool_t *pool)
{
- PyObject *self = (PyObject *)baton, *ret;
- PyGILState_STATE state = PyGILState_Ensure();
- ret = PyObject_CallMethod(self, "finish", "");
- CB_CHECK_PYRETVAL(ret);
- Py_DECREF(ret);
- PyGILState_Release(state);
- return NULL;
+ PyObject *self = (PyObject *)baton, *ret;
+ PyGILState_STATE state = PyGILState_Ensure();
+ ret = PyObject_CallMethod(self, "finish", "");
+ CB_CHECK_PYRETVAL(ret);
+ Py_DECREF(ret);
+ PyGILState_Release(state);
+ return NULL;
}
static svn_error_t *py_ra_report_abort(void *baton, apr_pool_t *pool)
{
- PyObject *self = (PyObject *)baton, *ret;
- PyGILState_STATE state = PyGILState_Ensure();
- ret = PyObject_CallMethod(self, "abort", "");
- CB_CHECK_PYRETVAL(ret);
- Py_DECREF(ret);
- PyGILState_Release(state);
- return NULL;
+ PyObject *self = (PyObject *)baton, *ret;
+ PyGILState_STATE state = PyGILState_Ensure();
+ ret = PyObject_CallMethod(self, "abort", "");
+ CB_CHECK_PYRETVAL(ret);
+ Py_DECREF(ret);
+ PyGILState_Release(state);
+ return NULL;
}
#if ONLY_SINCE_SVN(1, 5)
const svn_ra_reporter3_t py_ra_reporter3 = {
- py_ra_report3_set_path,
- py_ra_report_delete_path,
- py_ra_report3_link_path,
- py_ra_report_finish,
- py_ra_report_abort,
+ py_ra_report3_set_path,
+ py_ra_report_delete_path,
+ py_ra_report3_link_path,
+ py_ra_report_finish,
+ py_ra_report_abort,
};
#endif
const svn_ra_reporter2_t py_ra_reporter2 = {
- py_ra_report2_set_path,
- py_ra_report_delete_path,
- py_ra_report2_link_path,
- py_ra_report_finish,
- py_ra_report_abort,
+ py_ra_report2_set_path,
+ py_ra_report_delete_path,
+ py_ra_report2_link_path,
+ py_ra_report_finish,
+ py_ra_report_abort,
};
return;
if (notify->err != NULL) {
+ PyGILState_STATE state = PyGILState_Ensure();
PyObject *excval = PyErr_NewSubversionException(notify->err);
ret = PyObject_CallFunction(func, "O", excval);
Py_DECREF(excval);
Py_XDECREF(ret);
/* If ret was NULL, the cancel func should abort the operation. */
+ PyGILState_Release(state);
}
}
bool py_dict_to_wcprop_changes(PyObject *dict, apr_pool_t *pool, apr_array_header_t **ret)
svn_error_t *wc_validator3(void *baton, const char *uuid, const char *url, const char *root_url, apr_pool_t *pool)
{
PyObject *py_validator = baton, *ret;
+ PyGILState_STATE state;
if (py_validator == Py_None) {
return NULL;
}
-
+ state = PyGILState_Ensure();
ret = PyObject_CallFunction(py_validator, "sss", uuid, url, root_url);
if (ret == NULL) {
+ PyGILState_Release(state);
return py_svn_error();
}
Py_DECREF(ret);
+ PyGILState_Release(state);
return NULL;
}
svn_error_t *wc_validator2(void *baton, const char *uuid, const char *url, svn_boolean_t root, apr_pool_t *pool)
{
PyObject *py_validator = baton, *ret;
+ PyGILState_STATE state;
if (py_validator == Py_None) {
return NULL;
}
+ state = PyGILState_Ensure();
ret = PyObject_CallFunction(py_validator, "ssO", uuid, url, Py_None);
if (ret == NULL) {
+ PyGILState_Release(state);
return py_svn_error();
}
Py_DECREF(ret);
+ PyGILState_Release(state);
return NULL;
}
if (pool == NULL)
return NULL;
- path = py_object_to_svn_dirent(py_path, pool);
+ path = py_object_to_svn_abspath(py_path, pool);
if (path == NULL) {
apr_pool_destroy(pool);
return NULL;
apr_pool_t *temp_pool;
PyObject *py_path;
#if ONLY_SINCE_SVN(1, 6)
- apr_pool_t *stream_pool;
StreamObject *ret;
+ apr_pool_t *stream_pool;
svn_stream_t *stream;
#else
+#if PY_MAJOR_VERSION >= 3
+ int fd;
+#endif
PyObject *ret;
const char *pristine_path;
#endif
apr_pool_destroy(stream_pool);
return NULL;
}
+#else
+ temp_pool = Pool(NULL);
+ if (temp_pool == NULL) {
+ return NULL;
+ }
+#endif
- path = py_object_to_svn_dirent(py_path, temp_pool);
+ path = py_object_to_svn_abspath(py_path, temp_pool);
if (path == NULL) {
apr_pool_destroy(temp_pool);
return NULL;
}
+#if ONLY_SINCE_SVN(1, 6)
RUN_SVN_WITH_POOL(stream_pool, svn_wc_get_pristine_contents(&stream, path, stream_pool, temp_pool));
apr_pool_destroy(temp_pool);
if (temp_pool == NULL)
return NULL;
RUN_SVN_WITH_POOL(temp_pool, svn_wc_get_pristine_copy_path(path, &pristine_path, temp_pool));
+#if PY_MAJOR_VERSION >= 3
+ fd = open(pristine_path, O_RDONLY);
+ if (fd < 0) {
+ PyErr_SetFromErrno(PyExc_IOError);
+ apr_pool_destroy(temp_pool);
+ return NULL;
+ }
+ ret = PyFile_FromFd(fd, pristine_path, "rb", -1, NULL, NULL, NULL, true);
+#else
ret = PyFile_FromString((char *)pristine_path, "rb");
+#endif
apr_pool_destroy(temp_pool);
return ret;
#endif
static PyObject *ensure_adm(PyObject *self, PyObject *args, PyObject *kwargs)
{
const char *path;
- char *uuid, *url;
+ char *uuid, *url = NULL;
PyObject *py_path;
- char *repos=NULL;
- svn_revnum_t rev=-1;
+ char *repos = NULL;
+ long rev = -1;
apr_pool_t *pool;
char *kwnames[] = { "path", "uuid", "url", "repos", "rev", "depth", NULL };
- svn_depth_t depth = svn_depth_infinity;
+ int depth = svn_depth_infinity;
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oss|sli", kwnames,
&py_path, &uuid, &url, &repos, &rev, &depth))
}
static PyMethodDef wc_methods[] = {
- { "check_wc", check_wc, METH_VARARGS, "check_wc(path) -> version\n"
- "Check whether path contains a Subversion working copy\n"
- "return the workdir version"},
- { "cleanup", (PyCFunction)cleanup_wc, METH_VARARGS|METH_KEYWORDS, "cleanup(path, diff3_cmd=None)\n" },
- { "ensure_adm", (PyCFunction)ensure_adm, METH_KEYWORDS|METH_VARARGS,
- "ensure_adm(path, uuid, url, repos=None, rev=None)" },
- { "get_adm_dir", (PyCFunction)get_adm_dir, METH_NOARGS,
- "get_adm_dir() -> name" },
- { "set_adm_dir", (PyCFunction)set_adm_dir, METH_VARARGS,
- "set_adm_dir(name)" },
- { "get_pristine_copy_path", get_pristine_copy_path, METH_VARARGS,
- "get_pristine_copy_path(path) -> path" },
- { "get_pristine_contents", get_pristine_contents, METH_VARARGS,
- "get_pristine_contents(path) -> stream" },
- { "is_adm_dir", is_adm_dir, METH_VARARGS,
- "is_adm_dir(name) -> bool" },
- { "is_normal_prop", is_normal_prop, METH_VARARGS,
- "is_normal_prop(name) -> bool" },
- { "is_entry_prop", is_entry_prop, METH_VARARGS,
- "is_entry_prop(name) -> bool" },
- { "is_wc_prop", is_wc_prop, METH_VARARGS,
- "is_wc_prop(name) -> bool" },
- { "revision_status", (PyCFunction)revision_status, METH_KEYWORDS|METH_VARARGS, "revision_status(wc_path, trail_url=None, committed=False) -> (min_rev, max_rev, switched, modified)" },
- { "version", (PyCFunction)version, METH_NOARGS,
- "version() -> (major, minor, patch, tag)\n\n"
- "Version of libsvn_wc currently used."
- },
- { "api_version", (PyCFunction)api_version, METH_NOARGS,
- "api_version() -> (major, minor, patch, tag)\n\n"
- "Version of libsvn_wc Subvertpy was compiled against."
- },
- { "match_ignore_list", (PyCFunction)match_ignore_list, METH_VARARGS,
- "match_ignore_list(str, patterns) -> bool" },
- { "get_actual_target", (PyCFunction)get_actual_target, METH_VARARGS,
- "get_actual_target(path) -> (anchor, target)" },
- { NULL, }
+ { "check_wc", check_wc, METH_VARARGS, "check_wc(path) -> version\n"
+ "Check whether path contains a Subversion working copy\n"
+ "return the workdir version"},
+ { "cleanup", (PyCFunction)cleanup_wc,
+ METH_VARARGS|METH_KEYWORDS, "cleanup(path, diff3_cmd=None)\n" },
+ { "ensure_adm", (PyCFunction)ensure_adm, METH_KEYWORDS|METH_VARARGS,
+ "ensure_adm(path, uuid, url, repos=None, rev=None)" },
+ { "get_adm_dir", (PyCFunction)get_adm_dir, METH_NOARGS,
+ "get_adm_dir() -> name" },
+ { "set_adm_dir", (PyCFunction)set_adm_dir, METH_VARARGS,
+ "set_adm_dir(name)" },
+ { "get_pristine_copy_path", get_pristine_copy_path, METH_VARARGS,
+ "get_pristine_copy_path(path) -> path" },
+ { "get_pristine_contents", get_pristine_contents, METH_VARARGS,
+ "get_pristine_contents(path) -> stream" },
+ { "is_adm_dir", is_adm_dir, METH_VARARGS,
+ "is_adm_dir(name) -> bool" },
+ { "is_normal_prop", is_normal_prop, METH_VARARGS,
+ "is_normal_prop(name) -> bool" },
+ { "is_entry_prop", is_entry_prop, METH_VARARGS,
+ "is_entry_prop(name) -> bool" },
+ { "is_wc_prop", is_wc_prop, METH_VARARGS,
+ "is_wc_prop(name) -> bool" },
+ { "revision_status", (PyCFunction)revision_status,
+ METH_KEYWORDS|METH_VARARGS,
+ "revision_status(wc_path, trail_url=None, committed=False)"
+ "-> (min_rev, max_rev, switched, modified)" },
+ { "version", (PyCFunction)version, METH_NOARGS,
+ "version() -> (major, minor, patch, tag)\n\n"
+ "Version of libsvn_wc currently used."
+ },
+ { "api_version", (PyCFunction)api_version, METH_NOARGS,
+ "api_version() -> (major, minor, patch, tag)\n\n"
+ "Version of libsvn_wc Subvertpy was compiled against." },
+ { "match_ignore_list", (PyCFunction)match_ignore_list, METH_VARARGS,
+ "match_ignore_list(str, patterns) -> bool" },
+ { "get_actual_target", (PyCFunction)get_actual_target, METH_VARARGS,
+ "get_actual_target(path) -> (anchor, target)" },
+ { NULL, }
};
static void committed_queue_dealloc(PyObject *self)
static PyObject *committed_queue_queue(CommittedQueueObject *self, PyObject *args, PyObject *kwargs)
{
- char *path;
+ const char *path;
PyObject *admobj;
- PyObject *py_wcprop_changes = Py_None;
- svn_wc_adm_access_t *adm;
+ PyObject *py_wcprop_changes = Py_None, *py_path;
+ svn_wc_adm_access_t *adm = NULL;
bool remove_lock = false, remove_changelist = false;
char *md5_digest = NULL, *sha1_digest = NULL;
bool recurse = false;
- apr_pool_t *temp_pool;
apr_array_header_t *wcprop_changes;
int md5_digest_len, sha1_digest_len;
+#if ONLY_SINCE_SVN(1, 7)
+ svn_wc_context_t *context = NULL;
+#endif
char *kwnames[] = { "path", "adm", "recurse", "wcprop_changes", "remove_lock", "remove_changelist", "md5_digest", "sha1_digest", NULL };
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!|bObbz#z#", kwnames,
- &path, &Adm_Type, &admobj,
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|bObbz#z#", kwnames,
+ &py_path, &admobj,
&recurse, &py_wcprop_changes, &remove_lock,
&remove_changelist, &md5_digest, &md5_digest_len,
&sha1_digest, &sha1_digest_len))
return NULL;
- temp_pool = Pool(NULL);
- if (temp_pool == NULL)
- return NULL;
-
if (!py_dict_to_wcprop_changes(py_wcprop_changes, self->pool, &wcprop_changes)) {
- apr_pool_destroy(temp_pool);
return NULL;
}
- path = apr_pstrdup(self->pool, path);
+ path = py_object_to_svn_abspath(py_path, self->pool);
if (path == NULL) {
- PyErr_NoMemory();
return NULL;
}
if (md5_digest != NULL) {
if (md5_digest_len != APR_MD5_DIGESTSIZE) {
PyErr_SetString(PyExc_ValueError, "Invalid size for md5 digest");
- apr_pool_destroy(temp_pool);
- return NULL;
- }
- md5_digest = apr_pstrdup(temp_pool, md5_digest);
- if (md5_digest == NULL) {
- PyErr_NoMemory();
return NULL;
}
}
if (sha1_digest != NULL) {
if (sha1_digest_len != APR_SHA1_DIGESTSIZE) {
PyErr_SetString(PyExc_ValueError, "Invalid size for sha1 digest");
- apr_pool_destroy(temp_pool);
- return NULL;
- }
- sha1_digest = apr_pstrdup(temp_pool, sha1_digest);
- if (sha1_digest == NULL) {
- PyErr_NoMemory();
return NULL;
}
}
- adm = PyObject_GetAdmAccess(admobj);
+ if (PyObject_IsInstance(admobj, (PyObject *)&Adm_Type)) {
+ adm = PyObject_GetAdmAccess(admobj);
+#if ONLY_SINCE_SVN(1, 7)
+ } else if (PyObject_IsInstance(admobj, (PyObject *)&Context_Type)) {
+ context = ((ContextObject*)admobj)->context;
+#endif
+ } else {
+ PyErr_SetString(PyExc_TypeError, "Second arguments needs to be Adm or Context");
+ return NULL;
+ }
+#if ONLY_SINCE_SVN(1, 7)
+ if (adm != NULL) {
+#endif
#if ONLY_SINCE_SVN(1, 6)
{
- svn_checksum_t svn_checksum, *svn_checksum_p = &svn_checksum;
+ svn_checksum_t *svn_checksum_p;
- if (sha1_digest != NULL) {
- svn_checksum.digest = (unsigned char *)sha1_digest;
- svn_checksum.kind = svn_checksum_sha1;
- } else if (md5_digest != NULL) {
- svn_checksum.digest = (unsigned char *)md5_digest;
- svn_checksum.kind = svn_checksum_md5;
+ if (md5_digest != NULL) {
+ svn_checksum_p = apr_palloc(self->pool, sizeof(svn_checksum_t));
+ svn_checksum_p->digest = apr_pmemdup(
+ self->pool, (unsigned char *)md5_digest, APR_MD5_DIGESTSIZE);
+ svn_checksum_p->kind = svn_checksum_md5;
} else {
svn_checksum_p = NULL;
}
- RUN_SVN_WITH_POOL(temp_pool,
+ RUN_SVN(
svn_wc_queue_committed2(self->queue, path, adm, recurse?TRUE:FALSE,
wcprop_changes, remove_lock?TRUE:FALSE, remove_changelist?TRUE:FALSE,
- svn_checksum_p, temp_pool));
+ svn_checksum_p, self->pool));
}
#else
- RUN_SVN_WITH_POOL(temp_pool,
+ RUN_SVN(
svn_wc_queue_committed(&self->queue, path, adm, recurse?TRUE:FALSE,
wcprop_changes, remove_lock?TRUE:FALSE, remove_changelist?TRUE:FALSE,
- (unsigned char *)md5_digest, temp_pool));
+ (unsigned char *)md5_digest, self->pool));
#endif
+#if ONLY_SINCE_SVN(1, 7)
+ } else {
+ svn_checksum_t *svn_checksum_p;
- apr_pool_destroy(temp_pool);
+ if (sha1_digest != NULL) {
+ svn_checksum_p = apr_palloc(self->pool, sizeof(svn_checksum_t));
+ svn_checksum_p->digest = apr_pmemdup(
+ self->pool, (unsigned char *)sha1_digest, APR_SHA1_DIGESTSIZE);
+ svn_checksum_p->kind = svn_checksum_sha1;
+ } else {
+ svn_checksum_p = NULL;
+ }
+ RUN_SVN(
+ svn_wc_queue_committed3(self->queue, context, path, recurse?TRUE:FALSE,
+ wcprop_changes, remove_lock?TRUE:FALSE, remove_changelist?TRUE:FALSE,
+ svn_checksum_p, self->pool));
+ }
+#endif
Py_RETURN_NONE;
}
committed_queue_init, /* newfunc tp_new; */
};
-#if ONLY_SINCE_SVN(1, 7)
+svn_lock_t *py_object_to_svn_lock(PyObject *py_lock, apr_pool_t *pool)
+{
+ LockObject* lockobj = (LockObject *)py_lock;
+ if (!PyObject_IsInstance(py_lock, (PyObject *)&Lock_Type)) {
+ PyErr_SetString(PyExc_TypeError, "Expected Lock object");
+ return NULL;
+ }
+ return &lockobj->lock;
+}
-typedef struct {
- PyObject_VAR_HEAD
- apr_pool_t *pool;
- svn_wc_context_t *context;
-} ContextObject;
+#if ONLY_SINCE_SVN(1, 7)
+static PyTypeObject Context_Type;
static PyObject *py_wc_context_locked(PyObject *self, PyObject *args)
{
apr_pool_destroy(pool);
+#if PY_MAJOR_VERSION >= 3
+ return PyLong_FromLong(wc_format);
+#else
return PyInt_FromLong(wc_format);
+#endif
+}
+
+static PyObject *py_wc_context_text_modified_p2(PyObject *self, PyObject *args)
+{
+ PyObject* py_path;
+ const char *path;
+ apr_pool_t *pool;
+ svn_wc_context_t *wc_context = ((ContextObject *)self)->context;
+ svn_boolean_t modified;
+
+ if (!PyArg_ParseTuple(args, "O", &py_path))
+ return NULL;
+
+ pool = Pool(NULL);
+
+ path = py_object_to_svn_abspath(py_path, pool);
+ if (path == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ RUN_SVN_WITH_POOL(pool, svn_wc_text_modified_p2(&modified, wc_context,
+ path, FALSE, pool));
+
+ apr_pool_destroy(pool);
+
+ return PyBool_FromLong(modified);
+}
+
+static PyObject *py_wc_context_props_modified_p2(PyObject *self, PyObject *args)
+{
+ PyObject* py_path;
+ const char *path;
+ apr_pool_t *pool;
+ svn_wc_context_t *wc_context = ((ContextObject *)self)->context;
+ svn_boolean_t modified;
+
+ if (!PyArg_ParseTuple(args, "O", &py_path))
+ return NULL;
+
+ pool = Pool(NULL);
+
+ path = py_object_to_svn_abspath(py_path, pool);
+ if (path == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ RUN_SVN_WITH_POOL(pool, svn_wc_props_modified_p2(&modified, wc_context,
+ path, pool));
+
+ apr_pool_destroy(pool);
+
+ return PyBool_FromLong(modified);
}
+static PyObject *py_wc_context_conflicted(PyObject *self, PyObject *args)
+{
+ PyObject* py_path;
+ const char *path;
+ apr_pool_t *pool;
+ svn_wc_context_t *wc_context = ((ContextObject *)self)->context;
+ svn_boolean_t text_conflicted, props_conflicted, tree_conflicted;
+
+ if (!PyArg_ParseTuple(args, "O", &py_path))
+ return NULL;
+
+ pool = Pool(NULL);
+
+ path = py_object_to_svn_abspath(py_path, pool);
+ if (path == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ RUN_SVN_WITH_POOL(pool, svn_wc_conflicted_p3(
+ &text_conflicted, &props_conflicted, &tree_conflicted, wc_context,
+ path, pool));
+
+ apr_pool_destroy(pool);
+
+ return Py_BuildValue("(bbb)", text_conflicted, props_conflicted, tree_conflicted);
+}
+
+static PyObject *py_wc_context_crawl_revisions(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyObject* py_path, *py_reporter;
+ const char *path;
+ apr_pool_t *pool;
+ svn_wc_context_t *wc_context = ((ContextObject *)self)->context;
+ char *kwnames[] = { "path", "reporter", "restore_files", "depth",
+ "honor_depth_exclude", "depth_compatibility_trick", "use_commit_times",
+ "cancel", "notify", NULL };
+ bool restore_files = false;
+ int depth = svn_depth_infinity;
+ bool honor_depth_exclude = true;
+ bool depth_compatibility_trick = false;
+ bool use_commit_times = false;
+ PyObject *notify = Py_None;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|bibbbOO", kwnames,
+ &py_path, &py_reporter, &restore_files,
+ &depth, &honor_depth_exclude,
+ &depth_compatibility_trick,
+ &use_commit_times, ¬ify)) {
+ return NULL;
+ }
+
+ pool = Pool(NULL);
+
+ path = py_object_to_svn_abspath(py_path, pool);
+ if (path == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ RUN_SVN_WITH_POOL(pool, svn_wc_crawl_revisions5(
+ wc_context, path, &py_ra_reporter3, py_reporter, restore_files,
+ depth, honor_depth_exclude, depth_compatibility_trick,
+ use_commit_times, py_cancel_check, NULL, py_wc_notify_func, notify, pool));
+
+ apr_pool_destroy(pool);
+
+ Py_RETURN_NONE;
+}
+
+static void context_done_handler(void *self)
+{
+ PyObject *selfobj = (PyObject *)self;
+
+ Py_DECREF(selfobj);
+}
+
+static PyObject *py_wc_context_get_update_editor(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ char *kwnames[] = {
+ "anchor_abspath", "target_basename", "use_commit_times", "depth",
+ "depth_is_sticky", "allow_unver_obstructions", "adds_as_modification",
+ "server_performs_filtering", "clean_checkout", "diff3_cmd",
+ "preserved_exts", "dirents_func", "conflict_func", "external_func",
+ "notify_func", NULL };
+ const svn_delta_editor_t *editor;
+ void *edit_baton;
+ const char *anchor_abspath;
+ char *target_basename;
+ char *diff3_cmd = NULL;
+ svn_wc_context_t *wc_context = ((ContextObject *)self)->context;
+ bool use_commit_times = false;
+ int depth = svn_depth_infinity;
+ bool depth_is_sticky = false;
+ bool allow_unver_obstructions = true;
+ bool adds_as_modification = false;
+ bool server_performs_filtering = false;
+ bool clean_checkout = false;
+ apr_array_header_t *preserved_exts = NULL;
+ PyObject *py_preserved_exts = Py_None;
+ PyObject *dirents_func = Py_None;
+ PyObject *conflict_func = Py_None;
+ PyObject *external_func = Py_None;
+ PyObject *notify_func = Py_None;
+ PyObject *py_anchor_abspath;
+ apr_pool_t *result_pool, *scratch_pool;
+ svn_error_t *err;
+ svn_revnum_t target_revision;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Os|bibbbbbzOOOOO", kwnames,
+ &py_anchor_abspath, &target_basename,
+ &use_commit_times, &depth,
+ &depth_is_sticky,
+ &allow_unver_obstructions,
+ &adds_as_modification,
+ &server_performs_filtering,
+ &clean_checkout, &py_preserved_exts,
+ &dirents_func, &conflict_func,
+ &external_func, ¬ify_func)) {
+ return NULL;
+ }
+
+ if (conflict_func != Py_None) {
+ // TODO
+ PyErr_SetString(PyExc_NotImplementedError,
+ "conflict_func is not currently supported");
+ return NULL;
+ }
+
+ if (external_func != Py_None) {
+ // TODO
+ PyErr_SetString(PyExc_NotImplementedError,
+ "external_func is not currently supported");
+ return NULL;
+ }
+
+ if (dirents_func != Py_None) {
+ // TODO
+ PyErr_SetString(PyExc_NotImplementedError,
+ "dirents_func is not currently supported");
+ return NULL;
+ }
+
+ scratch_pool = Pool(NULL);
+
+ anchor_abspath = py_object_to_svn_abspath(py_anchor_abspath, scratch_pool);
+
+ if (py_preserved_exts != Py_None) {
+ if (!string_list_to_apr_array(scratch_pool, py_preserved_exts, &preserved_exts)) {
+ apr_pool_destroy(scratch_pool);
+ return NULL;
+ }
+ }
+
+ result_pool = Pool(NULL);
+
+ Py_BEGIN_ALLOW_THREADS
+ err = svn_wc_get_update_editor4(
+ &editor, &edit_baton, &target_revision, wc_context,
+ anchor_abspath, target_basename, use_commit_times, depth,
+ depth_is_sticky, allow_unver_obstructions, adds_as_modification,
+ server_performs_filtering, clean_checkout, diff3_cmd,
+ preserved_exts, NULL, dirents_func, NULL, conflict_func, NULL,
+ external_func, py_cancel_check, NULL, py_wc_notify_func,
+ notify_func, result_pool, scratch_pool);
+ Py_END_ALLOW_THREADS
+
+ apr_pool_destroy(scratch_pool);
+
+ if (err != NULL) {
+ handle_svn_error(err);
+ svn_error_clear(err);
+ apr_pool_destroy(result_pool);
+ return NULL;
+ }
+
+ /* TODO: Also return target_revision ? */
+ Py_INCREF(self);
+ return new_editor_object(NULL, editor, edit_baton, result_pool, &Editor_Type,
+ context_done_handler, self, NULL);
+}
+
+static PyObject *py_wc_context_ensure_adm(PyObject *self, PyObject *args,
+ PyObject *kwargs)
+{
+ ContextObject *context_obj = (ContextObject *)self;
+ char *kwnames[] = {
+ "local_abspath", "url", "repos_root_url", "repos_uuid",
+ "revnum", "depth", NULL };
+ char *local_abspath;
+ char *url;
+ char *repos_root_url;
+ char *repos_uuid;
+ int revnum;
+ int depth = svn_depth_infinity;
+ apr_pool_t *pool;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssssi|i", kwnames,
+ &local_abspath, &url, &repos_root_url,
+ &repos_uuid, &revnum, &depth)) {
+ return NULL;
+ }
+
+ pool = Pool(NULL);
+
+ RUN_SVN_WITH_POOL(pool, svn_wc_ensure_adm4(context_obj->context,
+ local_abspath, url,
+ repos_root_url, repos_uuid,
+ revnum, depth, pool));
+
+ apr_pool_destroy(pool);
+
+ Py_RETURN_NONE;
+}
+
+typedef struct {
+ PyObject_VAR_HEAD
+ apr_pool_t *pool;
+ svn_wc_status3_t status;
+} Status3Object;
+
+static void status_dealloc(PyObject *self)
+{
+ apr_pool_t *pool = ((Status3Object *)self)->pool;
+ if (pool != NULL)
+ apr_pool_destroy(pool);
+ PyObject_Del(self);
+}
+
+static PyMemberDef status_members[] = {
+ { "kind", T_INT, offsetof(Status3Object, status.kind), READONLY,
+ "The kind of node as recorded in the working copy." },
+ { "depth", T_INT, offsetof(Status3Object, status.depth), READONLY,
+ "The depth of the node as recorded in the working copy." },
+ { "filesize", T_LONG, offsetof(Status3Object, status.filesize), READONLY,
+ "The actual size of the working file on disk, or SVN_INVALID_FILESIZE"
+ "if unknown (or if the item isn't a file at all)" },
+ { "versioned", T_BOOL, offsetof(Status3Object, status.versioned), READONLY,
+ "If the path is under version control, versioned is TRUE, "
+ "otherwise FALSE." },
+ { "repos_uuid", T_STRING, offsetof(Status3Object, status.repos_uuid), READONLY,
+ "UUID of repository" },
+ { "repos_root_url", T_STRING, offsetof(Status3Object, status.repos_root_url), READONLY,
+ "Repository root URL" },
+ { "repos_relpath", T_STRING, offsetof(Status3Object, status.repos_relpath), READONLY,
+ "Relative path in repository" },
+ /* TODO */
+ { NULL }
+};
+
+static PyTypeObject Status3_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "wc.Status", /* const char *tp_name; For printing, in format "<module>.<name>" */
+ sizeof(Status3Object),
+ 0,/* Py_ssize_t tp_basicsize, tp_itemsize; For allocation */
+
+ /* Methods to implement standard operations */
+
+ status_dealloc, /* destructor tp_dealloc; */
+ NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* cmpfunc tp_compare; */
+ NULL, /* reprfunc tp_repr; */
+
+ /* Method suites for standard classes */
+
+ NULL, /* PyNumberMethods *tp_as_number; */
+ NULL, /* PySequenceMethods *tp_as_sequence; */
+ NULL, /* PyMappingMethods *tp_as_mapping; */
+
+ /* More standard operations (here for binary compatibility) */
+
+ NULL, /* hashfunc tp_hash; */
+ NULL, /* ternaryfunc tp_call; */
+ NULL, /* reprfunc tp_str; */
+ NULL, /* getattrofunc tp_getattro; */
+ NULL, /* setattrofunc tp_setattro; */
+
+ /* Functions to access object as input/output buffer */
+ NULL, /* PyBufferProcs *tp_as_buffer; */
+
+ /* Flags to define presence of optional/expanded features */
+ 0, /* long tp_flags; */
+
+ NULL, /* const char *tp_doc; Documentation string */
+
+ /* Assigned meaning in release 2.0 */
+ /* call function for all accessible objects */
+ NULL, /* traverseproc tp_traverse; */
+
+ /* delete references to contained objects */
+ NULL, /* inquiry tp_clear; */
+
+ /* Assigned meaning in release 2.1 */
+ /* rich comparisons */
+ NULL, /* richcmpfunc tp_richcompare; */
+
+ /* weak reference enabler */
+ 0, /* Py_ssize_t tp_weaklistoffset; */
+
+ /* Added in release 2.2 */
+ /* Iterators */
+ NULL, /* getiterfunc tp_iter; */
+ NULL, /* iternextfunc tp_iternext; */
+
+ /* Attribute descriptor and subclassing stuff */
+ NULL, /* struct PyMethodDef *tp_methods; */
+ status_members, /* struct PyMemberDef *tp_members; */
+ NULL, /* struct PyGetSetDef *tp_getsetters; */
+};
+
+static PyObject *py_wc_status(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ ContextObject *context_obj = (ContextObject *)self;
+ char *kwnames[] = {"path", NULL};
+ PyObject *py_path;
+ Status3Object *ret;
+ const char *path;
+ apr_pool_t *scratch_pool, *result_pool;
+ svn_wc_status3_t* status;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_path)) {
+ return NULL;
+ }
+
+ result_pool = Pool(NULL);
+ if (result_pool == NULL) {
+ return NULL;
+ }
+ scratch_pool = Pool(result_pool);
+ if (scratch_pool == NULL) {
+ apr_pool_destroy(result_pool);
+ return NULL;
+ }
+
+ path = py_object_to_svn_abspath(py_path, scratch_pool);
+ if (path == NULL) {
+ apr_pool_destroy(result_pool);
+ return NULL;
+ }
+
+ RUN_SVN_WITH_POOL(result_pool,
+ svn_wc_status3(&status, context_obj->context, path,
+ result_pool, scratch_pool));
+
+ apr_pool_destroy(scratch_pool);
+
+ ret = PyObject_New(Status3Object, &Status3_Type);
+ if (ret == NULL) {
+ apr_pool_destroy(result_pool);
+ return NULL;
+ }
+ ret->pool = result_pool;
+ ret->status = *status;
+ return (PyObject *)ret;
+}
+
+static svn_error_t *py_status_receiver(void *baton, const char *local_abspath,
+ const svn_wc_status3_t *status,
+ apr_pool_t *scratch_pool)
+{
+ Status3Object *py_status;
+ PyObject *ret;
+ PyGILState_STATE state;
+
+ if (baton == Py_None)
+ return NULL;
+
+ state = PyGILState_Ensure();
+
+ py_status = PyObject_New(Status3Object, &Status3_Type);
+ if (py_status == NULL) {
+ PyGILState_Release(state);
+ return py_svn_error();
+ }
+ py_status->pool = Pool(NULL);
+ py_status->status = *svn_wc_dup_status3(status, py_status->pool);
+
+ ret = PyObject_CallFunction((PyObject *)baton, "sO", local_abspath, py_status);
+ Py_DECREF(py_status);
+
+ if (ret == NULL) {
+ PyGILState_Release(state);
+ return py_svn_error();
+ }
+
+ Py_DECREF(ret);
+ PyGILState_Release(state);
+
+ return NULL;
+}
+
+static PyObject *py_wc_walk_status(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ ContextObject *context_obj = (ContextObject *)self;
+ char *kwnames[] = {"path", "receiver", "depth", "get_all", "no_ignore",
+ "ignore_text_mode", "ignore_patterns", NULL};
+ PyObject *py_path;
+ const char *path;
+ int depth = svn_depth_infinity;
+ bool get_all = true;
+ bool no_ignore = false;
+ bool ignore_text_mode = false;
+ PyObject *py_ignore_patterns = Py_None;
+ PyObject *status_func;
+ apr_array_header_t *ignore_patterns;
+ apr_pool_t *pool;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|ibbbOO", kwnames,
+ &py_path, &status_func, &depth, &get_all, &no_ignore,
+ &ignore_text_mode, &py_ignore_patterns)) {
+ return NULL;
+ }
+
+ pool = Pool(NULL);
+
+ path = py_object_to_svn_abspath(py_path, pool);
+ if (path == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ if (py_ignore_patterns == Py_None) {
+ ignore_patterns = NULL;
+ } else {
+ if (!string_list_to_apr_array(pool, py_ignore_patterns, &ignore_patterns)) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+ }
+
+ RUN_SVN_WITH_POOL(pool,
+ svn_wc_walk_status(context_obj->context, path, depth,
+ get_all, no_ignore, ignore_text_mode,
+ ignore_patterns, py_status_receiver,
+ status_func, py_cancel_check, NULL,
+ pool));
+
+ apr_pool_destroy(pool);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_wc_add_lock(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ ContextObject *context_obj = (ContextObject *)self;
+ PyObject *py_path, *py_lock;
+ svn_lock_t *lock;
+ char *kwnames[] = { "path", "lock", NULL };
+ const char *path;
+ apr_pool_t *scratch_pool;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO!", kwnames, &py_path, &Lock_Type,
+ &py_lock)) {
+ return NULL;
+ }
+
+ scratch_pool = Pool(NULL);
+ if (scratch_pool == NULL) {
+ return NULL;
+ }
+
+ path = py_object_to_svn_abspath(py_path, scratch_pool);
+ if (path == NULL) {
+ apr_pool_destroy(scratch_pool);
+ return NULL;
+ }
+
+ lock = py_object_to_svn_lock(py_lock, scratch_pool);
+ if (lock == NULL) {
+ apr_pool_destroy(scratch_pool);
+ return NULL;
+ }
+
+ RUN_SVN_WITH_POOL(scratch_pool,
+ svn_wc_add_lock2(context_obj->context, path, lock, scratch_pool));
+
+ apr_pool_destroy(scratch_pool);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_wc_remove_lock(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ ContextObject *context_obj = (ContextObject *)self;
+ char *kwnames[] = { "path", NULL };
+ PyObject *py_path;
+ const char *path;
+ apr_pool_t *scratch_pool;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_path)) {
+ return NULL;
+ }
+
+ scratch_pool = Pool(NULL);
+
+ path = py_object_to_svn_abspath(py_path, scratch_pool);
+ if (path == NULL) {
+ apr_pool_destroy(scratch_pool);
+ return NULL;
+ }
+
+ RUN_SVN_WITH_POOL(scratch_pool,
+ svn_wc_remove_lock2(context_obj->context, path,
+ scratch_pool));
+
+ apr_pool_destroy(scratch_pool);
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_wc_add_from_disk(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ ContextObject *context_obj = (ContextObject *)self;
+ char *kwnames[] = {"path", "props", "skip_checks", "notify", NULL };
+ PyObject *py_path;
+ const char *path;
+ bool skip_checks = false;
+ PyObject *py_props = Py_None;
+ PyObject *notify_func = Py_None;
+ apr_pool_t *pool;
+ apr_hash_t *props;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|ObO", kwnames,
+ &py_path, &py_props, &skip_checks, ¬ify_func)) {
+ return NULL;
+ }
+
+ pool = Pool(NULL);
+ if (pool == NULL) {
+ return NULL;
+ }
+
+ path = py_object_to_svn_abspath(py_path, pool);
+ if (path == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ if (py_props == Py_None) {
+ props = NULL;
+ } else {
+ props = prop_dict_to_hash(pool, py_props);
+ if (props == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+ }
+
+#if ONLY_SINCE_SVN(1, 9)
+ RUN_SVN_WITH_POOL(
+ pool, svn_wc_add_from_disk3(
+ context_obj->context, path, props, skip_checks,
+ notify_func == Py_None?NULL:py_wc_notify_func,
+ notify_func, pool));
+#else
+ if (props != NULL) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "props argument only supported on svn >= 1.9");
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ if (skip_checks) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "skip_checks argument only supported on svn >= 1.9");
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+ RUN_SVN_WITH_POOL(
+ pool, svn_wc_add_from_disk(
+ context_obj->context, path,
+ notify_func == Py_None?NULL:py_wc_notify_func,
+ notify_func, pool));
+#endif
+
+ apr_pool_destroy(pool);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *py_wc_get_prop_diffs(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ ContextObject *context_obj = (ContextObject *)self;
+ PyObject *py_path, *py_orig_props, *py_propchanges;
+ apr_pool_t *pool;
+ char *kwnames[] = {"path", NULL};
+ apr_hash_t *original_props;
+ apr_array_header_t *propchanges;
+ const char *path;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_path)) {
+ return NULL;
+ }
+
+ pool = Pool(NULL);
+
+ path = py_object_to_svn_abspath(py_path, pool);
+ if (path == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ RUN_SVN_WITH_POOL(pool, svn_wc_get_prop_diffs2(&propchanges,
+ &original_props,
+ context_obj->context,
+ path, pool, pool));
+
+ py_orig_props = prop_hash_to_dict(original_props);
+ if (py_orig_props == NULL) {
+ apr_pool_destroy(pool);
+ return NULL;
+ }
+
+ py_propchanges = propchanges_to_list(propchanges);
+ if (py_propchanges == NULL) {
+ apr_pool_destroy(pool);
+ Py_DECREF(py_propchanges);
+ return NULL;
+ }
+
+ apr_pool_destroy(pool);
+
+ return Py_BuildValue("NN", py_orig_props, py_propchanges);
+}
+
+static PyObject *py_wc_context_process_committed_queue(PyObject *self, PyObject *args)
+{
+ apr_pool_t *temp_pool;
+ ContextObject *contextobj = (ContextObject *)self;
+ svn_revnum_t revnum;
+ char *date, *author;
+ PyObject *py_queue;
+
+ if (!PyArg_ParseTuple(args, "O!lss", &CommittedQueue_Type, &py_queue,
+ &revnum, &date, &author))
+ return NULL;
+
+ temp_pool = Pool(NULL);
+ if (temp_pool == NULL)
+ return NULL;
+
+ svn_wc_committed_queue_t *committed_queue = PyObject_GetCommittedQueue(py_queue);
+
+ RUN_SVN_WITH_POOL(temp_pool,
+ svn_wc_process_committed_queue2(committed_queue,
+ contextobj->context,
+ revnum, date, author,
+ py_cancel_check, NULL,
+ temp_pool));
+
+ apr_pool_destroy(temp_pool);
+
+ Py_RETURN_NONE;
+}
+
+
+
static PyMethodDef context_methods[] = {
- { "locked", py_wc_context_locked, METH_VARARGS, "locked(path) -> (locked_here, locked)\n"
- "Check whether a patch is locked."},
- { "check_wc", py_wc_context_check_wc, METH_VARARGS, "check_wc(path) -> wc_format\n"
+ { "locked", py_wc_context_locked, METH_VARARGS,
+ "locked(path) -> (locked_here, locked)\n"
+ "Check whether a patch is locked."},
+ { "check_wc", py_wc_context_check_wc, METH_VARARGS,
+ "check_wc(path) -> wc_format\n"
"Check format version of a working copy." },
+ { "text_modified", py_wc_context_text_modified_p2, METH_VARARGS,
+ "text_modified(path) -> bool\n"
+ "Check whether text of a file is modified against base." },
+ { "props_modified", py_wc_context_props_modified_p2, METH_VARARGS,
+ "props_modified(path) -> bool\n"
+ "Check whether props of a file are modified against base." },
+ { "conflicted", py_wc_context_conflicted, METH_VARARGS,
+ "conflicted(path) -> (text_conflicted, prop_conflicted, "
+ "tree_conflicted)\n"
+ "Check whether a path is conflicted." },
+ { "crawl_revisions", (PyCFunction)py_wc_context_crawl_revisions,
+ METH_VARARGS|METH_KEYWORDS,
+ "crawl_revisions(path, reporter, restore_files, depth, "
+ "honor_depth_exclude, depth_compatibility_trick, "
+ "use_commit_time, notify)\n"
+ "Do a depth-first crawl of the working copy." },
+ { "get_update_editor",
+ (PyCFunction)py_wc_context_get_update_editor,
+ METH_VARARGS|METH_KEYWORDS,
+ "get_update_editor(anchor_abspath, target_basename, use_commit_time, "
+ "depth, depth_is_sticky, allow_unver_obstructions, "
+ "adds_as_modification, server_performs_filtering, clean_checkout, "
+ "diff3_cmd, dirent_func=None, conflict_func=None, "
+ "external_func=None) -> target_revnum" },
+ { "ensure_adm",
+ (PyCFunction)py_wc_context_ensure_adm,
+ METH_VARARGS|METH_KEYWORDS,
+ "ensure_adm(local_abspath, url, repos_root_url, repos_uuid, revnum, depth)" },
+ { "process_committed_queue",
+ (PyCFunction)py_wc_context_process_committed_queue,
+ METH_VARARGS|METH_KEYWORDS,
+ "" },
+ { "status",
+ (PyCFunction)py_wc_status,
+ METH_VARARGS|METH_KEYWORDS,
+ "status(path) -> status" },
+ { "walk_status",
+ (PyCFunction)py_wc_walk_status,
+ METH_VARARGS|METH_KEYWORDS,
+ "walk_status(path, receiver, depth=DEPTH_INFINITY, get_all=True, "
+ "no_ignore=False, ignore_text_mode=False, ignore_patterns=None)\n" },
+ { "add_lock",
+ (PyCFunction)py_wc_add_lock,
+ METH_VARARGS|METH_KEYWORDS,
+ "add_lock(path, lock)" },
+ { "remove_lock",
+ (PyCFunction)py_wc_remove_lock,
+ METH_VARARGS|METH_KEYWORDS,
+ "remove_lock(path)" },
+ { "add_from_disk",
+ (PyCFunction)py_wc_add_from_disk,
+ METH_VARARGS|METH_KEYWORDS,
+ "add_from_disk(local_abspath, props=None, skip_checks=False, notify=None)" },
+ { "get_prop_diffs",
+ (PyCFunction)py_wc_get_prop_diffs,
+ METH_VARARGS|METH_KEYWORDS,
+ "get_prop_diffs(path) -> (changes orig_props)" },
{ NULL }
};
#endif
+static void lock_dealloc(PyObject *self)
+{
+ LockObject *lockself = (LockObject *)self;
+
+ apr_pool_destroy(lockself->pool);
+
+ PyObject_Del(self);
+}
+
+static PyObject *lock_init(PyTypeObject *type, PyObject *args, PyObject *kwargs)
+{
+ char *kwnames[] = { "token", NULL };
+ LockObject *ret;
+ char *token = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|z", kwnames, &token))
+ return NULL;
+
+ ret = PyObject_New(LockObject, &Lock_Type);
+ if (ret == NULL)
+ return NULL;
+
+ ret->pool = Pool(NULL);
+ if (ret->pool == NULL)
+ return NULL;
+ ret->lock = *svn_lock_create(ret->pool);
+ if (token != NULL) {
+ ret->lock.token = apr_pstrdup(ret->pool, token);
+ }
+
+ return (PyObject *)ret;
+}
+
+static PyObject *lock_get_path(PyObject *self, void *closure) {
+ LockObject *lock_obj = (LockObject *)self;
+
+ if (lock_obj->lock.path == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ return PyUnicode_FromString(lock_obj->lock.path);
+}
+
+static int lock_set_path(PyObject *self, PyObject *value, void *closure) {
+ LockObject *lock_obj = (LockObject *)self;
+ char *path;
+
+ path = PyBytes_AsString(value);
+ if (path == NULL) {
+ return -1;
+ }
+
+ lock_obj->lock.path = py_object_to_svn_string(value, lock_obj->pool);
+ return 0;
+}
+
+static PyObject *lock_get_token(PyObject *self, void *closure) {
+ LockObject *lock_obj = (LockObject *)self;
+
+ if (lock_obj->lock.token == NULL) {
+ Py_RETURN_NONE;
+ }
+
+ return PyBytes_FromString(lock_obj->lock.token);
+}
+
+static int lock_set_token(PyObject *self, PyObject *value, void *closure) {
+ LockObject *lock_obj = (LockObject *)self;
+ char *token;
+
+ token = PyBytes_AsString(value);
+ if (token == NULL) {
+ PyErr_SetNone(PyExc_TypeError);
+ return -1;
+ }
+
+ lock_obj->lock.token = apr_pstrdup(lock_obj->pool, PyBytes_AsString(value));
+ return 0;
+}
+
+static PyGetSetDef lock_getsetters[] = {
+ { "path", lock_get_path, lock_set_path,
+ "the path this lock applies to"},
+ { "token", lock_get_token, lock_set_token,
+ "unique URI representing lock"},
+ { NULL },
+};
+
+PyTypeObject Lock_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "wc.Lock", /* const char *tp_name; For printing, in format "<module>.<name>" */
+ sizeof(LockObject),
+ 0,/* Py_ssize_t tp_basicsize, tp_itemsize; For allocation */
+
+ /* Methods to implement standard operations */
+
+ .tp_dealloc = lock_dealloc, /* destructor tp_dealloc; */
+
+ .tp_doc = "Lock", /* const char *tp_doc; Documentation string */
+
+ .tp_methods = NULL, /* struct PyMethodDef *tp_methods; */
+
+ .tp_new = lock_init, /* tp_new tp_new */
+
+ .tp_getset = lock_getsetters,
+};
+
static PyObject *
moduleinit(void)
{
if (PyType_Ready(&Entry_Type) < 0)
return NULL;
- if (PyType_Ready(&Status_Type) < 0)
+ if (PyType_Ready(&Status2_Type) < 0)
return NULL;
if (PyType_Ready(&Adm_Type) < 0)
if (PyType_Ready(&CommittedQueue_Type) < 0)
return NULL;
+#if ONLY_SINCE_SVN(1, 7)
+ if (PyType_Ready(&Status3_Type) < 0)
+ return NULL;
+#endif
+
+ if (PyType_Ready(&Lock_Type) < 0)
+ return NULL;
+
apr_initialize();
#if PY_MAJOR_VERSION >= 3
PyModule_AddObject(mod, "Adm", (PyObject *)&Adm_Type);
Py_INCREF(&Adm_Type);
+ PyModule_AddObject(mod, "Lock", (PyObject *)&Lock_Type);
+ Py_INCREF(&Lock_Type);
+
PyModule_AddObject(mod, "CommittedQueue", (PyObject *)&CommittedQueue_Type);
Py_INCREF(&CommittedQueue_Type);