
We switch to a parameter list for both functions and add a return type. We also remove the indentation from the second line of the explanation which was causing Sphinx to return it as two lines instead of one continuous one. We also added return types. I am not sure of the type of the GIT_DIFF* flags so I have not included that.
260 lines
9.0 KiB
C
260 lines
9.0 KiB
C
/*
|
|
* Copyright 2010-2014 The pygit2 contributors
|
|
*
|
|
* This file is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License, version 2,
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* In addition to the permissions in the GNU General Public License,
|
|
* the authors give you unlimited permission to link the compiled
|
|
* version of this file into combinations with other programs,
|
|
* and to distribute those combinations without any restriction
|
|
* coming from the use of this file. (The General Public License
|
|
* restrictions do apply in other respects; for example, they cover
|
|
* modification of the file, and distribution when not linked into
|
|
* a combined executable.)
|
|
*
|
|
* This file is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#define PY_SSIZE_T_CLEAN
|
|
#include <Python.h>
|
|
#include "diff.h"
|
|
#include "error.h"
|
|
#include "utils.h"
|
|
#include "object.h"
|
|
#include "blob.h"
|
|
|
|
extern PyObject *GitError;
|
|
|
|
extern PyTypeObject BlobType;
|
|
|
|
PyDoc_STRVAR(Blob_diff__doc__,
|
|
"diff([blob, flag, old_as_path, new_as_path]) -> Patch\n"
|
|
"\n"
|
|
"Directly generate a :py:class:`pygit2.Patch` from the difference\n"
|
|
"between two blobs.\n"
|
|
"\n"
|
|
":param Blob blob: the :py:class:`~pygit2.Blob` to diff.\n"
|
|
"\n"
|
|
":param flag: a GIT_DIFF_* constant.\n"
|
|
"\n"
|
|
":param str old_as_path: treat old blob as if it had this filename.\n"
|
|
"\n"
|
|
":param str new_as_path: treat new blob as if it had this filename.\n"
|
|
"\n"
|
|
":rtype: Patch\n");
|
|
|
|
PyObject *
|
|
Blob_diff(Blob *self, PyObject *args, PyObject *kwds)
|
|
{
|
|
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
|
|
git_patch *patch;
|
|
char *old_as_path = NULL, *new_as_path = NULL;
|
|
Blob *py_blob = NULL;
|
|
int err;
|
|
char *keywords[] = {"blob", "flag", "old_as_path", "new_as_path", NULL};
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!Iss", keywords,
|
|
&BlobType, &py_blob, &opts.flags,
|
|
&old_as_path, &new_as_path))
|
|
return NULL;
|
|
|
|
err = git_patch_from_blobs(&patch, self->blob, old_as_path,
|
|
py_blob ? py_blob->blob : NULL, new_as_path,
|
|
&opts);
|
|
if (err < 0)
|
|
return Error_set(err);
|
|
|
|
return wrap_patch(patch);
|
|
}
|
|
|
|
|
|
PyDoc_STRVAR(Blob_diff_to_buffer__doc__,
|
|
"diff_to_buffer([buffer, flag, old_as_path, buffer_as_path]) -> Patch\n"
|
|
"\n"
|
|
"Directly generate a :py:class:`~pygit2.Patch` from the difference\n"
|
|
"between a blob and a buffer.\n"
|
|
"\n"
|
|
":param Blob buffer: Raw data for new side of diff.\n"
|
|
"\n"
|
|
":param flag: a GIT_DIFF_* constant.\n"
|
|
"\n"
|
|
":param str old_as_path: treat old blob as if it had this filename.\n"
|
|
"\n"
|
|
":param str buffer_as_path: treat buffer as if it had this filename.\n"
|
|
"\n"
|
|
":rtype: Patch\n");
|
|
|
|
PyObject *
|
|
Blob_diff_to_buffer(Blob *self, PyObject *args, PyObject *kwds)
|
|
{
|
|
git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
|
|
git_patch *patch;
|
|
char *old_as_path = NULL, *buffer_as_path = NULL;
|
|
const char *buffer = NULL;
|
|
Py_ssize_t buffer_len;
|
|
int err;
|
|
char *keywords[] = {"buffer", "flag", "old_as_path", "buffer_as_path",
|
|
NULL};
|
|
|
|
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|s#Iss", keywords,
|
|
&buffer, &buffer_len, &opts.flags,
|
|
&old_as_path, &buffer_as_path))
|
|
return NULL;
|
|
|
|
err = git_patch_from_blob_and_buffer(&patch, self->blob, old_as_path,
|
|
buffer, buffer_len, buffer_as_path,
|
|
&opts);
|
|
if (err < 0)
|
|
return Error_set(err);
|
|
|
|
return wrap_patch(patch);
|
|
}
|
|
|
|
static PyMethodDef Blob_methods[] = {
|
|
METHOD(Blob, diff, METH_VARARGS | METH_KEYWORDS),
|
|
METHOD(Blob, diff_to_buffer, METH_VARARGS | METH_KEYWORDS),
|
|
{NULL}
|
|
};
|
|
|
|
|
|
PyDoc_STRVAR(Blob_size__doc__, "Size.");
|
|
|
|
PyObject *
|
|
Blob_size__get__(Blob *self)
|
|
{
|
|
return PyLong_FromLongLong(git_blob_rawsize(self->blob));
|
|
}
|
|
|
|
|
|
PyDoc_STRVAR(Blob_is_binary__doc__, "True if binary data, False if not.");
|
|
|
|
PyObject *
|
|
Blob_is_binary__get__(Blob *self)
|
|
{
|
|
if (git_blob_is_binary(self->blob))
|
|
Py_RETURN_TRUE;
|
|
Py_RETURN_FALSE;
|
|
}
|
|
|
|
|
|
PyDoc_STRVAR(Blob_data__doc__,
|
|
"The contents of the blob, a bytes string. This is the same as\n"
|
|
"Blob.read_raw()");
|
|
|
|
PyGetSetDef Blob_getseters[] = {
|
|
GETTER(Blob, size),
|
|
GETTER(Blob, is_binary),
|
|
{"data", (getter)Object_read_raw, NULL, Blob_data__doc__, NULL},
|
|
{NULL}
|
|
};
|
|
|
|
static int
|
|
Blob_getbuffer(Blob *self, Py_buffer *view, int flags)
|
|
{
|
|
return PyBuffer_FillInfo(view, (PyObject *) self,
|
|
(void *) git_blob_rawcontent(self->blob),
|
|
git_blob_rawsize(self->blob), 1, flags);
|
|
}
|
|
|
|
#if PY_MAJOR_VERSION == 2
|
|
|
|
static Py_ssize_t
|
|
Blob_getreadbuffer(Blob *self, Py_ssize_t index, const void **ptr)
|
|
{
|
|
if (index != 0) {
|
|
PyErr_SetString(PyExc_SystemError,
|
|
"accessing non-existent blob segment");
|
|
return -1;
|
|
}
|
|
*ptr = (void *) git_blob_rawcontent(self->blob);
|
|
return git_blob_rawsize(self->blob);
|
|
}
|
|
|
|
static Py_ssize_t
|
|
Blob_getsegcount(Blob *self, Py_ssize_t *lenp)
|
|
{
|
|
if (lenp)
|
|
*lenp = git_blob_rawsize(self->blob);
|
|
|
|
return 1;
|
|
}
|
|
|
|
static PyBufferProcs Blob_as_buffer = {
|
|
(readbufferproc)Blob_getreadbuffer,
|
|
NULL, /* bf_getwritebuffer */
|
|
(segcountproc)Blob_getsegcount,
|
|
NULL, /* charbufferproc */
|
|
(getbufferproc)Blob_getbuffer,
|
|
};
|
|
|
|
#else
|
|
|
|
static PyBufferProcs Blob_as_buffer = {
|
|
(getbufferproc)Blob_getbuffer,
|
|
};
|
|
|
|
#endif /* python 2 vs python 3 buffers */
|
|
|
|
PyDoc_STRVAR(Blob__doc__, "Blob object.\n"
|
|
"\n"
|
|
"Blobs implement the buffer interface, which means you can get access\n"
|
|
"to its data via `memoryview(blob)` without the need to create a copy."
|
|
);
|
|
|
|
PyTypeObject BlobType = {
|
|
PyVarObject_HEAD_INIT(NULL, 0)
|
|
"_pygit2.Blob", /* tp_name */
|
|
sizeof(Blob), /* tp_basicsize */
|
|
0, /* tp_itemsize */
|
|
0, /* tp_dealloc */
|
|
0, /* tp_print */
|
|
0, /* tp_getattr */
|
|
0, /* tp_setattr */
|
|
0, /* tp_compare */
|
|
0, /* tp_repr */
|
|
0, /* tp_as_number */
|
|
0, /* tp_as_sequence */
|
|
0, /* tp_as_mapping */
|
|
0, /* tp_hash */
|
|
0, /* tp_call */
|
|
0, /* tp_str */
|
|
0, /* tp_getattro */
|
|
0, /* tp_setattro */
|
|
&Blob_as_buffer, /* tp_as_buffer */
|
|
#if PY_MAJOR_VERSION == 2
|
|
Py_TPFLAGS_DEFAULT | /* tp_flags */
|
|
Py_TPFLAGS_HAVE_GETCHARBUFFER |
|
|
Py_TPFLAGS_HAVE_NEWBUFFER,
|
|
#else
|
|
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
|
#endif
|
|
Blob__doc__, /* tp_doc */
|
|
0, /* tp_traverse */
|
|
0, /* tp_clear */
|
|
0, /* tp_richcompare */
|
|
0, /* tp_weaklistoffset */
|
|
0, /* tp_iter */
|
|
0, /* tp_iternext */
|
|
Blob_methods, /* tp_methods */
|
|
0, /* tp_members */
|
|
Blob_getseters, /* tp_getset */
|
|
0, /* tp_base */
|
|
0, /* tp_dict */
|
|
0, /* tp_descr_get */
|
|
0, /* tp_descr_set */
|
|
0, /* tp_dictoffset */
|
|
0, /* tp_init */
|
|
0, /* tp_alloc */
|
|
0, /* tp_new */
|
|
};
|