libgit-thin: pygit: Uses python's 2.2 attribute handling
[git/libgit-gsoc.git] / libgit-thin / pygit / pygit.c
blob53e1b9c614f3f14e396e1ee318690ea913bb5846
1 #include <Python.h>
2 #include "structmember.h"
4 #include <libgit-thin.h>
6 #define UNUSED(x) (x = x)
8 PyMODINIT_FUNC initpygit(void);
10 typedef struct {
11 PyObject_HEAD
12 PyObject *path;
13 } GitRepoObject;
15 static PyObject *
16 repo_read_obj(PyObject *args,
17 int (*read_obj)(unsigned char *sha1, void **buf, size_t *len))
19 int err;
20 void *buf;
21 PyObject *ret;
22 const char *hex;
23 unsigned char sha1[GIT_SHA1_SIZE];
25 if (!PyArg_ParseTuple(args, "s", &hex))
26 return NULL;
28 err = git_hex_to_sha1(hex, sha1);
29 if (err)
30 return PyErr_SetFromErrno(PyExc_TypeError);
32 err = read_obj(sha1, &buf, NULL);
33 if (err)
34 return PyErr_SetFromErrno(PyExc_ValueError);
36 ret = PyString_FromString((char *) buf);
37 free(buf);
39 return ret;
42 static PyObject *
43 pygit_repo_read_commit(GitRepoObject *self, PyObject *args)
45 UNUSED(self);
46 return repo_read_obj(args, git_repo_commit_read);
49 static PyObject *
50 pygit_repo_read_blob(GitRepoObject *self, PyObject *args)
52 UNUSED(self);
53 return repo_read_obj(args, git_repo_blob_read);
56 static PyMethodDef git_repo_methods[] = {
57 {"read_commit", (PyCFunction) pygit_repo_read_commit,
58 METH_VARARGS, NULL},
59 {"read_blob", (PyCFunction) pygit_repo_read_blob,
60 METH_VARARGS, NULL},
61 {NULL, NULL, 0, NULL}
64 static PyMemberDef git_repo_members[] = {
65 {"path", T_OBJECT_EX, offsetof(GitRepoObject, path), 0,
66 "repository's path"},
67 {NULL, 0, 0, 0, NULL}
70 static void
71 git_repo_dealloc(GitRepoObject *self)
73 Py_XDECREF(self->path);
74 self->ob_type->tp_free((PyObject*) self);
77 static PyTypeObject Git_Repo_Type = {
78 PyObject_HEAD_INIT(NULL)
79 0, /* ob_size */
80 "pygit.repo", /* tp_name */
81 sizeof(GitRepoObject), /* tp_basicsize */
82 0, /* tp_itemsize */
83 (destructor)git_repo_dealloc, /* tp_dealloc */
84 0, /* tp_print */
85 0, /* tp_getattr */
86 0, /* tp_setattr */
87 0, /* tp_compare */
88 0, /* tp_repr */
89 0, /* tp_as_number */
90 0, /* tp_as_sequence */
91 0, /* tp_as_mapping */
92 0, /* tp_hash */
93 0, /* tp_call */
94 0, /* tp_str */
95 0, /* tp_getattro */
96 0, /* tp_setattro */
97 0, /* tp_as_buffer */
98 Py_TPFLAGS_DEFAULT, /* tp_flags */
99 0, /* tp_doc */
100 0, /* tp_traverse */
101 0, /* tp_clear */
102 0, /* tp_richcompare */
103 0, /* tp_weaklistoffset */
104 0, /* tp_iter */
105 0, /* tp_iternext */
106 git_repo_methods, /* tp_methods */
107 git_repo_members, /* tp_members */
108 0, /* tp_getset */
109 0, /* tp_base */
110 0, /* tp_dict */
111 0, /* tp_descr_get */
112 0, /* tp_descr_set */
113 0, /* tp_dictoffset */
114 0, /* tp_init */
115 0, /* tp_alloc */
116 0, /* tp_new */
119 static PyObject *
120 pygit_open(PyObject *self, PyObject *args)
122 int err;
123 const char *dir;
124 GitRepoObject *m;
126 UNUSED(self);
128 if (!PyArg_ParseTuple(args, "s", &dir))
129 return NULL;
131 err = git_repo_open(dir);
132 if (err) {
133 PyErr_SetFromErrno(PyExc_IOError);
134 return NULL;
137 m = PyObject_New(GitRepoObject, &Git_Repo_Type);
138 if (!m)
139 return NULL;
141 err = PyType_Ready(&Git_Repo_Type);
142 if (err) {
143 PyObject_DEL(m);
144 return NULL;
147 m->path = PyString_FromString(dir);
148 if (!m->path) {
149 PyObject_DEL(m);
150 return NULL;
153 return (PyObject *) m;
156 static PyMethodDef pygit_methods[] = {
157 { "open", pygit_open, METH_VARARGS, "Open a GIT repository" },
158 { NULL, NULL, 0, NULL}
161 PyMODINIT_FUNC
162 initpygit(void)
164 (void) Py_InitModule("pygit", pygit_methods);