J. David Ibáñez 8e40dbd314 Make doc strings look fine from the interpreter
Basically add a new-line character since "help(...)" does not wrap
lines automatically.
2013-02-09 23:46:37 +01:00

556 lines
17 KiB
C

/*
* Copyright 2010-2012 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 <string.h>
#include <structmember.h>
#include <pygit2/error.h>
#include <pygit2/types.h>
#include <pygit2/utils.h>
#include <pygit2/oid.h>
#include <pygit2/signature.h>
#include <pygit2/reference.h>
extern PyObject *GitError;
extern PyTypeObject RefLogEntryType;
void RefLogIter_dealloc(RefLogIter *self)
{
Py_XDECREF(self->reference);
git_reflog_free(self->reflog);
PyObject_GC_Del(self);
}
PyObject* RefLogIter_iternext(PyObject *self)
{
RefLogIter *p = (RefLogIter *) self;
const git_reflog_entry *entry;
char oid_old[40], oid_new[40];
if (p->i < p->size) {
RefLogEntry *py_entry;
git_signature *signature;
entry = git_reflog_entry_byindex(p->reflog, p->i);
py_entry = (RefLogEntry*) PyType_GenericNew(&RefLogEntryType, NULL,
NULL);
git_oid_fmt(oid_old, git_reflog_entry_id_old(entry));
git_oid_fmt(oid_new, git_reflog_entry_id_new(entry));
py_entry->oid_new = PyUnicode_FromStringAndSize(oid_new, 40);
py_entry->oid_old = PyUnicode_FromStringAndSize(oid_old, 40);
py_entry->message = strdup(git_reflog_entry_message(entry));
signature = git_signature_dup(
git_reflog_entry_committer(entry)
);
if(signature != NULL)
py_entry->committer = build_signature(
(Object*)py_entry, signature, "utf-8"
);
++(p->i);
return (PyObject*) py_entry;
}
PyErr_SetNone(PyExc_StopIteration);
return NULL;
}
PyDoc_STRVAR(RefLogIterType__doc__, "Internal reflog iterator object.");
PyTypeObject RefLogIterType = {
PyVarObject_HEAD_INIT(NULL, 0)
"_libgit2.RefLogIter", /* tp_name */
sizeof(RefLogIter), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)RefLogIter_dealloc, /* 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 */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
RefLogIterType__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
PyObject_SelfIter, /* tp_iter */
(iternextfunc)RefLogIter_iternext /* tp_iternext */
};
void
Reference_dealloc(Reference *self)
{
git_reference_free(self->reference);
PyObject_Del(self);
}
PyDoc_STRVAR(Reference_delete__doc__,
"delete()\n"
"\n"
"Delete this reference. It will no longer be valid!");
PyObject *
Reference_delete(Reference *self, PyObject *args)
{
int err;
CHECK_REFERENCE(self);
/* Delete the reference */
err = git_reference_delete(self->reference);
if (err < 0)
return Error_set(err);
self->reference = NULL; /* Invalidate the pointer */
Py_RETURN_NONE;
}
PyDoc_STRVAR(Reference_rename__doc__,
"rename(new_name)\n"
"\n"
"Rename the reference.");
PyObject *
Reference_rename(Reference *self, PyObject *py_name)
{
char *c_name;
int err;
CHECK_REFERENCE(self);
/* Get the C name */
c_name = py_path_to_c_str(py_name);
if (c_name == NULL)
return NULL;
/* Rename */
err = git_reference_rename(self->reference, c_name, 0);
free(c_name);
if (err < 0)
return Error_set(err);
Py_RETURN_NONE;
}
PyDoc_STRVAR(Reference_reload__doc__,
"reload()\n"
"\n"
"Reload the reference from the file-system.");
PyObject *
Reference_reload(Reference *self)
{
int err;
CHECK_REFERENCE(self);
err = git_reference_reload(self->reference);
if (err < 0) {
self->reference = NULL;
return Error_set(err);
}
Py_RETURN_NONE;
}
PyDoc_STRVAR(Reference_resolve__doc__,
"resolve() -> Reference\n"
"\n"
"Resolve a symbolic reference and return a direct reference.");
PyObject *
Reference_resolve(Reference *self, PyObject *args)
{
git_reference *c_reference;
int err;
CHECK_REFERENCE(self);
/* Direct: reload */
if (git_reference_type(self->reference) == GIT_REF_OID) {
err = git_reference_reload(self->reference);
if (err < 0) {
self->reference = NULL;
return Error_set(err);
}
Py_INCREF(self);
return (PyObject *)self;
}
/* Symbolic: resolve */
err = git_reference_resolve(&c_reference, self->reference);
if (err < 0)
return Error_set(err);
return wrap_reference(c_reference);
}
PyDoc_STRVAR(Reference_target__doc__, "Target.");
PyObject *
Reference_target__get__(Reference *self)
{
const char * c_name;
CHECK_REFERENCE(self);
/* Get the target */
if (GIT_REF_OID == git_reference_type(self->reference)) {
return git_oid_to_py_str(git_reference_target(self->reference));
} else {
c_name = git_reference_symbolic_target(self->reference);
if (c_name == NULL) {
PyErr_SetString(PyExc_ValueError, "no target available");
return NULL;
}
}
/* Make a PyString and return it */
return to_path(c_name);
}
int
Reference_target__set__(Reference *self, PyObject *py_name)
{
char *c_name;
int err;
CHECK_REFERENCE_INT(self);
/* Get the C name */
c_name = py_path_to_c_str(py_name);
if (c_name == NULL)
return -1;
/* Set the new target */
err = git_reference_symbolic_set_target(self->reference, c_name);
free(c_name);
if (err < 0) {
Error_set(err);
return -1;
}
return 0;
}
PyDoc_STRVAR(Reference_name__doc__, "The full name of a reference.");
PyObject *
Reference_name__get__(Reference *self)
{
CHECK_REFERENCE(self);
return to_path(git_reference_name(self->reference));
}
PyDoc_STRVAR(Reference_oid__doc__, "Object id.");
PyObject *
Reference_oid__get__(Reference *self)
{
const git_oid *oid;
CHECK_REFERENCE(self);
/* Get the oid (only for "direct" references) */
oid = git_reference_target(self->reference);
if (oid == NULL) {
PyErr_SetString(PyExc_ValueError,
"oid is only available if the reference is direct "
"(i.e. not symbolic)");
return NULL;
}
/* Convert and return it */
return git_oid_to_python(oid->id);
}
int
Reference_oid__set__(Reference *self, PyObject *py_hex)
{
git_oid oid;
int err;
CHECK_REFERENCE_INT(self);
/* Get the oid */
err = py_str_to_git_oid_expand(git_reference_owner(self->reference),
py_hex, &oid);
if (err < 0) {
Error_set(err);
return -1;
}
/* Set the oid */
err = git_reference_set_target(self->reference, &oid);
if (err < 0) {
Error_set(err);
return -1;
}
return 0;
}
PyDoc_STRVAR(Reference_hex__doc__, "Hex oid.");
PyObject *
Reference_hex__get__(Reference *self)
{
const git_oid *oid;
CHECK_REFERENCE(self);
/* Get the oid (only for "direct" references) */
oid = git_reference_target(self->reference);
if (oid == NULL) {
PyErr_SetString(PyExc_ValueError,
"oid is only available if the reference is direct "
"(i.e. not symbolic)");
return NULL;
}
/* Convert and return it */
return git_oid_to_py_str(oid);
}
PyDoc_STRVAR(Reference_type__doc__,
"Type (GIT_REF_OID, GIT_REF_SYMBOLIC or GIT_REF_PACKED).");
PyObject *
Reference_type__get__(Reference *self)
{
git_ref_t c_type;
CHECK_REFERENCE(self);
c_type = git_reference_type(self->reference);
return PyInt_FromLong(c_type);
}
PyDoc_STRVAR(Reference_log__doc__,
"log() -> RefLogIter\n"
"\n"
"Retrieves the current reference log.");
PyObject *
Reference_log(Reference *self)
{
RefLogIter *iter;
CHECK_REFERENCE(self);
iter = PyObject_New(RefLogIter, &RefLogIterType);
if (iter) {
iter->reference = self;
git_reflog_read(&iter->reflog, self->reference);
iter->size = git_reflog_entrycount(iter->reflog);
iter->i = 0;
Py_INCREF(self);
Py_INCREF(iter);
}
return (PyObject*)iter;
}
static int
RefLogEntry_init(RefLogEntry *self, PyObject *args, PyObject *kwds)
{
self->oid_old = Py_None;
self->oid_new = Py_None;
self->message = "";
self->committer = Py_None;
return 0;
}
static void
RefLogEntry_dealloc(RefLogEntry *self)
{
Py_XDECREF(self->oid_old);
Py_XDECREF(self->oid_new);
Py_XDECREF(self->committer);
free(self->message);
PyObject_Del(self);
}
PyMemberDef RefLogEntry_members[] = {
MEMBER(RefLogEntry, oid_new, T_OBJECT, "New oid."),
MEMBER(RefLogEntry, oid_old, T_OBJECT, "Old oid."),
MEMBER(RefLogEntry, message, T_STRING, "Message."),
MEMBER(RefLogEntry, committer, T_OBJECT, "Committer."),
{NULL}
};
PyDoc_STRVAR(RefLogEntry__doc__, "Reference log object.");
PyTypeObject RefLogEntryType = {
PyVarObject_HEAD_INIT(NULL, 0)
"_pygit2.RefLogEntry", /* tp_name */
sizeof(RefLogEntry), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)RefLogEntry_dealloc, /* 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 */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
RefLogEntry__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
0, /* tp_methods */
RefLogEntry_members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
(initproc)RefLogEntry_init, /* tp_init */
0, /* tp_alloc */
0, /* tp_new */
};
PyMethodDef Reference_methods[] = {
METHOD(Reference, delete, METH_NOARGS),
METHOD(Reference, rename, METH_O),
METHOD(Reference, reload, METH_NOARGS),
METHOD(Reference, resolve, METH_NOARGS),
METHOD(Reference, log, METH_NOARGS),
{NULL}
};
PyGetSetDef Reference_getseters[] = {
GETTER(Reference, name),
GETSET(Reference, oid),
GETTER(Reference, hex),
GETSET(Reference, target),
GETTER(Reference, type),
{NULL}
};
PyDoc_STRVAR(Reference__doc__, "Reference.");
PyTypeObject ReferenceType = {
PyVarObject_HEAD_INIT(NULL, 0)
"_pygit2.Reference", /* tp_name */
sizeof(Reference), /* tp_basicsize */
0, /* tp_itemsize */
(destructor)Reference_dealloc, /* 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 */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
Reference__doc__, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Reference_methods, /* tp_methods */
0, /* tp_members */
Reference_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 */
};
PyObject *
wrap_reference(git_reference * c_reference)
{
Reference *py_reference=NULL;
py_reference = PyObject_New(Reference, &ReferenceType);
if (py_reference)
py_reference->reference = c_reference;
return (PyObject *)py_reference;
}