diff options
Diffstat (limited to 'subvertpy/util.c')
-rw-r--r-- | subvertpy/util.c | 452 |
1 files changed, 307 insertions, 145 deletions
diff --git a/subvertpy/util.c b/subvertpy/util.c index 49c68899..5d679838 100644 --- a/subvertpy/util.c +++ b/subvertpy/util.c @@ -44,10 +44,21 @@ void PyErr_SetAprStatus(apr_status_t status) #if ONLY_BEFORE_SVN(1, 7) const char * -svn_uri_canonicalize(const char *uri, +_svn_uri_canonicalize(const char *uri, apr_pool_t *result_pool) { - return svn_path_canonicalize(uri, result_pool); + uri = svn_path_canonicalize(uri, result_pool); + + if (uri == NULL) { + return NULL; + } + + uri = svn_path_uri_decode(uri, result_pool); + if (uri == NULL) { + return NULL; + } + + return svn_path_uri_autoescape(uri, result_pool); } const char * @@ -57,85 +68,132 @@ svn_relpath_canonicalize(const char *relpath, return svn_path_canonicalize(relpath, result_pool); } +const char * +svn_dirent_canonicalize(const char *dirent, + apr_pool_t *result_pool) +{ + return svn_path_canonicalize(dirent, result_pool); +} + #endif -const char *py_object_to_svn_dirent(PyObject *obj, apr_pool_t *pool) +const char *py_object_to_svn_path_or_url(PyObject *obj, apr_pool_t *pool) { - const char *ret; - PyObject *bytes_obj = NULL; + const char *ret; + + if (PyUnicode_Check(obj)) { + obj = PyUnicode_AsUTF8String(obj); + if (obj == NULL) { + return NULL; + } + } else { + Py_INCREF(obj); + } - if (PyUnicode_Check(obj)) { - bytes_obj = obj = PyUnicode_AsUTF8String(obj); - if (obj == NULL) { - return NULL; - } - } + if (!PyBytes_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "URIs need to be UTF-8 bytestrings or unicode strings"); + Py_DECREF(obj); + return NULL; + } - if (PyBytes_Check(obj)) { -#if ONLY_SINCE_SVN(1, 7) - ret = svn_dirent_canonicalize(PyBytes_AsString(obj), pool); -#else - ret = svn_path_canonicalize(PyBytes_AsString(obj), pool); -#endif - Py_XDECREF(bytes_obj); - return ret; - } else { - PyErr_SetString(PyExc_TypeError, - "URIs need to be UTF-8 bytestrings or unicode strings"); - Py_XDECREF(bytes_obj); - return NULL; - } + ret = PyBytes_AsString(obj); + if (svn_path_is_url(ret)) { + ret = svn_uri_canonicalize(ret, pool); + } else { + ret = svn_dirent_canonicalize(ret, pool); + } + + Py_DECREF(obj); + return ret; } -char *py_object_to_svn_string(PyObject *obj, apr_pool_t *pool) +const char *py_object_to_svn_abspath(PyObject *obj, apr_pool_t *pool) { - char *ret; - PyObject *bytes_obj = NULL; + const char *ret; + + if (PyUnicode_Check(obj)) { + obj = PyUnicode_AsUTF8String(obj); + if (obj == NULL) { + return NULL; + } + } else { + Py_INCREF(obj); + } - if (PyUnicode_Check(obj)) { - bytes_obj = obj = PyUnicode_AsUTF8String(obj); - if (obj == NULL) { - return NULL; - } - } + if (!PyBytes_Check(obj)) { + PyErr_SetString(PyExc_TypeError, + "URIs need to be UTF-8 bytestrings or unicode strings"); + Py_DECREF(obj); + return NULL; + } - if (PyBytes_Check(obj)) { - ret = apr_pstrdup(pool, PyBytes_AsString(obj)); - Py_XDECREF(bytes_obj); - return ret; - } else { - PyErr_SetString(PyExc_TypeError, - "URIs need to be UTF-8 bytestrings or unicode strings"); - Py_XDECREF(bytes_obj); - return NULL; - } + ret = PyBytes_AsString(obj); + ret = apr_pstrdup(pool, ret); + Py_DECREF(obj); + if (ret == NULL) { + return NULL; + } + if (svn_dirent_is_absolute(ret)) { + return svn_dirent_canonicalize(ret, pool); + } else { + const char *absolute; + RUN_SVN(svn_dirent_get_absolute(&absolute, ret, pool)) + return svn_dirent_canonicalize(absolute, pool); + } } -const char *py_object_to_svn_uri(PyObject *obj, apr_pool_t *pool) +const char *py_object_to_svn_dirent(PyObject *obj, apr_pool_t *pool) { - const char *ret; - PyObject *bytes_obj = NULL; + const char *ret; + + if (PyUnicode_Check(obj)) { + obj = PyUnicode_AsUTF8String(obj); + if (obj == NULL) { + return NULL; + } + } else { + Py_INCREF(obj); + } - if (PyUnicode_Check(obj)) { - bytes_obj = obj = PyUnicode_AsUTF8String(obj); - if (obj == NULL) { - return NULL; - } - } + if (PyBytes_Check(obj)) { + ret = svn_dirent_canonicalize(PyBytes_AsString(obj), pool); + Py_DECREF(obj); + return ret; + } else { + PyErr_SetString(PyExc_TypeError, + "URIs need to be UTF-8 bytestrings or unicode strings"); + Py_DECREF(obj); + return NULL; + } +} - if (PyBytes_Check(obj)) { - ret = svn_uri_canonicalize(PyBytes_AsString(obj), pool); - Py_XDECREF(bytes_obj); - return ret; - } else { - PyErr_SetString(PyExc_TypeError, - "URIs need to be UTF-8 bytestrings or unicode strings"); - Py_XDECREF(bytes_obj); - return NULL; - } +char *py_object_to_svn_string(PyObject *obj, apr_pool_t *pool) +{ + char *ret; + + if (PyUnicode_Check(obj)) { + obj = PyUnicode_AsUTF8String(obj); + if (obj == NULL) { + return NULL; + } + } else { + Py_INCREF(obj); + } + + if (PyBytes_Check(obj)) { + ret = apr_pstrdup(pool, PyBytes_AsString(obj)); + Py_DECREF(obj); + return ret; + } else { + PyErr_SetString(PyExc_TypeError, + "URIs need to be UTF-8 bytestrings or unicode strings"); + Py_DECREF(obj); + return NULL; + } } -const char *py_object_to_svn_relpath(PyObject *obj, apr_pool_t *pool) +const char *py_object_to_svn_uri(PyObject *obj, apr_pool_t *pool) { const char *ret; @@ -145,72 +203,97 @@ const char *py_object_to_svn_relpath(PyObject *obj, apr_pool_t *pool) return NULL; } } else { - Py_INCREF(obj); - } + Py_INCREF(obj); + } if (PyBytes_Check(obj)) { - ret = svn_relpath_canonicalize(PyBytes_AsString(obj), pool); + ret = svn_uri_canonicalize(PyBytes_AsString(obj), pool); Py_DECREF(obj); return ret; } else { PyErr_SetString(PyExc_TypeError, - "relative paths need to be UTF-8 bytestrings or unicode strings"); + "URIs need to be UTF-8 bytestrings or unicode strings"); Py_DECREF(obj); return NULL; } } +const char *py_object_to_svn_relpath(PyObject *obj, apr_pool_t *pool) +{ + const char *ret; + + if (PyUnicode_Check(obj)) { + obj = PyUnicode_AsUTF8String(obj); + if (obj == NULL) { + return NULL; + } + } else { + Py_INCREF(obj); + } + + if (PyBytes_Check(obj)) { + ret = svn_relpath_canonicalize(PyBytes_AsString(obj), pool); + Py_DECREF(obj); + return ret; + } else { + PyErr_SetString(PyExc_TypeError, + "relative paths need to be UTF-8 bytestrings or unicode strings"); + Py_DECREF(obj); + return NULL; + } +} + apr_pool_t *Pool(apr_pool_t *parent) { - apr_status_t status; - apr_pool_t *ret; - ret = NULL; - status = apr_pool_create(&ret, parent); - if (status != 0) { - PyErr_SetAprStatus(status); - return NULL; - } - return ret; + apr_status_t status; + apr_pool_t *ret; + ret = NULL; + status = apr_pool_create(&ret, parent); + if (status != 0) { + PyErr_SetAprStatus(status); + return NULL; + } + return ret; } PyTypeObject *PyErr_GetSubversionExceptionTypeObject(void) { - PyObject *coremod, *excobj; - coremod = PyImport_ImportModule("subvertpy"); + PyObject *coremod, *excobj; + coremod = PyImport_ImportModule("subvertpy"); - if (coremod == NULL) { - return NULL; - } + if (coremod == NULL) { + return NULL; + } - excobj = PyObject_GetAttrString(coremod, "SubversionException"); - Py_DECREF(coremod); + excobj = PyObject_GetAttrString(coremod, "SubversionException"); + Py_DECREF(coremod); - if (excobj == NULL) { - PyErr_BadInternalCall(); - return NULL; - } + if (excobj == NULL) { + PyErr_BadInternalCall(); + return NULL; + } - return (PyTypeObject *)excobj; + return (PyTypeObject *)excobj; } PyTypeObject *PyErr_GetGaiExceptionTypeObject(void) { - PyObject *socketmod, *excobj; - socketmod = PyImport_ImportModule("socket"); + PyObject *socketmod, *excobj; + socketmod = PyImport_ImportModule("socket"); - if (socketmod == NULL) { - return NULL; - } + if (socketmod == NULL) { + return NULL; + } - excobj = PyObject_GetAttrString(socketmod, "gaierror"); - Py_DECREF(socketmod); + excobj = PyObject_GetAttrString(socketmod, "gaierror"); + Py_DECREF(socketmod); - if (excobj == NULL) { - PyErr_BadInternalCall(); - return NULL; - } + if (excobj == NULL) { + PyErr_BadInternalCall(); + return NULL; + } - return (PyTypeObject *)excobj; + return (PyTypeObject *)excobj; } PyObject *PyErr_NewSubversionException(svn_error_t *error) @@ -229,9 +312,7 @@ PyObject *PyErr_NewSubversionException(svn_error_t *error) if (error->child != NULL) { PyTypeObject *cls = PyErr_GetSubversionExceptionTypeObject(); PyObject *args = PyErr_NewSubversionException(error->child); - child = cls->tp_new(cls, args, NULL); - if (cls->tp_init != NULL) - cls->tp_init(child, args, NULL); + child = PyObject_CallObject((PyObject *)cls, args); Py_DECREF(cls); Py_DECREF(args); } else { @@ -240,7 +321,7 @@ PyObject *PyErr_NewSubversionException(svn_error_t *error) } #if ONLY_SINCE_SVN(1, 4) - message = svn_err_best_message(error, buf, sizeof(buf)); + message = svn_err_best_message(error, buf, sizeof(buf)-1); #else message = error->message; #endif @@ -436,14 +517,12 @@ PyObject *prop_hash_to_dict(apr_hash_t *props) py_key = Py_None; Py_INCREF(py_key); } else { - py_key = PyUnicode_FromString(key); + py_key = PyUnicode_FromStringAndSize(key, klen); } if (PyDict_SetItem(py_props, py_key, py_val) != 0) { Py_DECREF(py_key); Py_DECREF(py_val); - Py_DECREF(py_props); - apr_pool_destroy(pool); - return NULL; + goto fail_item; } Py_DECREF(py_key); Py_DECREF(py_val); @@ -478,17 +557,11 @@ apr_hash_t *prop_dict_to_hash(apr_pool_t *pool, PyObject *py_props) } while (PyDict_Next(py_props, &idx, &k, &v)) { - char *key; - if (PyUnicode_Check(k)) { - k = PyUnicode_AsUTF8String(k); - } else { - Py_INCREF(k); - } + char *key, *val; + Py_ssize_t val_size; - if (!PyBytes_Check(k)) { - PyErr_SetString(PyExc_TypeError, - "property name should be unicode or byte string"); - Py_DECREF(k); + key = py_object_to_svn_string(k, pool); + if (key == NULL) { return NULL; } @@ -498,39 +571,26 @@ apr_hash_t *prop_dict_to_hash(apr_pool_t *pool, PyObject *py_props) Py_INCREF(v); } - if (!PyBytes_Check(v)) { - PyErr_SetString(PyExc_TypeError, - "property value should be unicode or byte string"); - Py_DECREF(k); - Py_DECREF(v); + if (PyBytes_AsStringAndSize(v, &val, &val_size) == -1) { return NULL; } - key = apr_pmemdup(pool, PyBytes_AsString(k), PyBytes_Size(k)); - if (key == NULL) { - PyErr_SetString(PyExc_TypeError, - "property value should be unicode or byte string"); - Py_DECREF(k); - Py_DECREF(v); - return NULL; - } + val_string = svn_string_ncreate(val, val_size, pool); - val_string = svn_string_ncreate(PyBytes_AsString(v), - PyBytes_Size(v), pool); - apr_hash_set(hash_props, key, PyBytes_Size(k), val_string); - Py_DECREF(k); Py_DECREF(v); + + apr_hash_set(hash_props, key, strlen(key), val_string); } return hash_props; } #if PY_MAJOR_VERSION >= 3 -#define SOURCEPATH_FORMAT3 "(Czl)" -#define SOURCEPATH_FORMAT4 "(Czli)" +#define SOURCEPATH_FORMAT3 "(CNl)" +#define SOURCEPATH_FORMAT4 "(CNli)" #else -#define SOURCEPATH_FORMAT3 "(czl)" -#define SOURCEPATH_FORMAT4 "(czli)" +#define SOURCEPATH_FORMAT3 "(cNl)" +#define SOURCEPATH_FORMAT4 "(cNli)" #endif PyObject *pyify_changed_paths(apr_hash_t *changed_paths, bool node_kind, apr_pool_t *pool) @@ -551,13 +611,21 @@ PyObject *pyify_changed_paths(apr_hash_t *changed_paths, bool node_kind, apr_poo } for (idx = apr_hash_first(pool, changed_paths); idx != NULL; idx = apr_hash_next(idx)) { + PyObject *py_copyfrom_path, *py_key; + apr_hash_this(idx, (const void **)&key, &klen, (void **)&val); + if (val->copyfrom_path == NULL) { + py_copyfrom_path = Py_None; + Py_INCREF(Py_None); + } else { + py_copyfrom_path = PyUnicode_FromString(val->copyfrom_path); + } if (node_kind) { - pyval = Py_BuildValue(SOURCEPATH_FORMAT4, val->action, val->copyfrom_path, + pyval = Py_BuildValue(SOURCEPATH_FORMAT4, val->action, py_copyfrom_path, val->copyfrom_rev, svn_node_unknown); } else { - pyval = Py_BuildValue(SOURCEPATH_FORMAT3, val->action, val->copyfrom_path, + pyval = Py_BuildValue(SOURCEPATH_FORMAT3, val->action, py_copyfrom_path, val->copyfrom_rev); } if (pyval == NULL) { @@ -570,11 +638,21 @@ PyObject *pyify_changed_paths(apr_hash_t *changed_paths, bool node_kind, apr_poo Py_DECREF(py_changed_paths); return NULL; } - if (PyDict_SetItemString(py_changed_paths, key, pyval) != 0) { + + py_key = PyUnicode_FromString(key); + if (py_key == NULL) { + Py_DECREF(pyval); + Py_DECREF(py_changed_paths); + return NULL; + } + + if (PyDict_SetItem(py_changed_paths, py_key, pyval) != 0) { Py_DECREF(py_changed_paths); + Py_DECREF(py_key); Py_DECREF(pyval); return NULL; } + Py_DECREF(py_key); Py_DECREF(pyval); } } @@ -601,8 +679,15 @@ PyObject *pyify_changed_paths2(apr_hash_t *changed_paths, apr_pool_t *pool) } for (idx = apr_hash_first(pool, changed_paths); idx != NULL; idx = apr_hash_next(idx)) { + PyObject *py_key, *py_copyfrom_path; apr_hash_this(idx, (const void **)&key, &klen, (void **)&val); - pyval = Py_BuildValue(SOURCEPATH_FORMAT4, val->action, val->copyfrom_path, + if (val->copyfrom_path == NULL) { + py_copyfrom_path = Py_None; + Py_INCREF(Py_None); + } else { + py_copyfrom_path = PyUnicode_FromString(val->copyfrom_path); + } + pyval = Py_BuildValue(SOURCEPATH_FORMAT4, val->action, py_copyfrom_path, val->copyfrom_rev, val->node_kind); if (pyval == NULL) { Py_DECREF(py_changed_paths); @@ -614,11 +699,20 @@ PyObject *pyify_changed_paths2(apr_hash_t *changed_paths, apr_pool_t *pool) Py_DECREF(pyval); return NULL; } - if (PyDict_SetItemString(py_changed_paths, key, pyval) != 0) { + py_key = PyUnicode_FromString(key); + if (py_key == NULL) { + Py_DECREF(py_changed_paths); Py_DECREF(pyval); + return NULL; + } + + if (PyDict_SetItem(py_changed_paths, py_key, pyval) != 0) { + Py_DECREF(pyval); + Py_DECREF(py_key); Py_DECREF(py_changed_paths); return NULL; } + Py_DECREF(py_key); Py_DECREF(pyval); } } @@ -840,6 +934,7 @@ static apr_hash_t *get_default_config(void) pool = Pool(NULL); RUN_SVN_WITH_POOL(pool, svn_config_get_config(&default_config, NULL, pool)); + /* TODO(jelmer): Deal with pool */ initialised = true; } @@ -1068,3 +1163,70 @@ PyTypeObject Stream_Type = { .tp_new = stream_init, /* tp_new tp_new */ }; + +PyObject *dirent_hash_to_dict(apr_hash_t *dirents, unsigned int dirent_fields, apr_pool_t *temp_pool) +{ + svn_dirent_t *dirent; + apr_ssize_t klen; + const char *key; + apr_hash_index_t *idx; + PyObject *py_dirents = PyDict_New(); + + if (py_dirents == NULL) { + return NULL; + } + idx = apr_hash_first(temp_pool, dirents); + while (idx != NULL) { + PyObject *item, *pykey; + apr_hash_this(idx, (const void **)&key, &klen, (void **)&dirent); + item = py_dirent(dirent, dirent_fields); + if (item == NULL) { + Py_DECREF(py_dirents); + return NULL; + } + if (key == NULL) { + pykey = Py_None; + Py_INCREF(pykey); + } else { + pykey = PyUnicode_FromStringAndSize(key, klen); + } + if (PyDict_SetItem(py_dirents, pykey, item) != 0) { + Py_DECREF(item); + Py_DECREF(pykey); + Py_DECREF(py_dirents); + return NULL; + } + Py_DECREF(pykey); + Py_DECREF(item); + idx = apr_hash_next(idx); + } + return py_dirents; +} + +PyObject *propchanges_to_list(const apr_array_header_t *propchanges) +{ + int i; + svn_prop_t el; + PyObject *py_propchanges = PyList_New(propchanges->nelts); + PyObject *pyval; + if (py_propchanges == NULL) { + return NULL; + } + for (i = 0; i < propchanges->nelts; i++) { + el = APR_ARRAY_IDX(propchanges, i, svn_prop_t); + if (el.value != NULL) + pyval = Py_BuildValue("(sz#)", el.name, el.value->data, el.value->len); + else + pyval = Py_BuildValue("(sO)", el.name, Py_None); + if (pyval == NULL) { + Py_DECREF(py_propchanges); + return NULL; + } + if (PyList_SetItem(py_propchanges, i, pyval) != 0) { + Py_DECREF(py_propchanges); + return NULL; + } + } + + return py_propchanges; +} |