1 |
|
|
/** |
2 |
|
|
* handle.c : wrapper class around alpm_handle_t |
3 |
|
|
* |
4 |
|
|
* Copyright (c) 2011 Rémy Oudompheng <remy@archlinux.org> |
5 |
|
|
* |
6 |
|
|
* This file is part of pyalpm. |
7 |
|
|
* |
8 |
|
|
* pyalpm is free software: you can redistribute it and/or modify |
9 |
|
|
* it under the terms of the GNU General Public License as published by |
10 |
|
|
* the Free Software Foundation, either version 3 of the License, or |
11 |
|
|
* (at your option) any later version. |
12 |
|
|
* |
13 |
|
|
* pyalpm is distributed in the hope that it will be useful, |
14 |
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 |
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 |
|
|
* GNU General Public License for more details. |
17 |
|
|
* |
18 |
|
|
* You should have received a copy of the GNU General Public License |
19 |
|
|
* along with pyalpm. If not, see <http://www.gnu.org/licenses/>. |
20 |
|
|
* |
21 |
|
|
*/ |
22 |
|
|
|
23 |
|
|
#include <pyconfig.h> |
24 |
|
|
#include <alpm.h> |
25 |
|
|
#include <Python.h> |
26 |
|
|
|
27 |
|
|
#include "handle.h" |
28 |
|
|
#include "package.h" |
29 |
|
|
#include "db.h" |
30 |
|
|
#include "options.h" |
31 |
|
|
#include "util.h" |
32 |
|
|
|
33 |
|
|
PyTypeObject AlpmHandleType; |
34 |
|
|
|
35 |
|
108 |
static PyObject *pyalpm_handle_from_pmhandle(void* data) { |
36 |
|
108 |
alpm_handle_t *handle = (alpm_handle_t*)data; |
37 |
|
108 |
AlpmHandle *self; |
38 |
|
108 |
self = (AlpmHandle*)AlpmHandleType.tp_alloc(&AlpmHandleType, 0); |
39 |
✗✓ |
108 |
if (self == NULL) { |
40 |
|
|
PyErr_SetString(PyExc_RuntimeError, "unable to create pyalpm.Handle object"); |
41 |
|
|
return NULL; |
42 |
|
|
} |
43 |
|
|
|
44 |
|
108 |
self->c_data = handle; |
45 |
|
|
/* memset(self->py_callbacks, 0, N_CALLBACKS * sizeof(PyObject*)); */ |
46 |
|
108 |
return (PyObject *)self; |
47 |
|
|
} |
48 |
|
|
|
49 |
|
|
/*pyalpm functions*/ |
50 |
|
111 |
PyObject* pyalpm_initialize(PyTypeObject *subtype, PyObject *args, PyObject *kwargs) |
51 |
|
|
{ |
52 |
|
111 |
const char *root; |
53 |
|
111 |
const char *dbpath; |
54 |
|
111 |
alpm_handle_t *h; |
55 |
|
111 |
enum _alpm_errno_t errcode = 0; |
56 |
✓✗ |
111 |
if(!PyArg_ParseTuple(args, "ss", &root, &dbpath)) { |
57 |
|
|
return NULL; |
58 |
|
|
} |
59 |
|
|
|
60 |
|
111 |
h = alpm_initialize(root, dbpath, &errcode); |
61 |
✓✓ |
111 |
if (h) { |
62 |
|
108 |
return pyalpm_handle_from_pmhandle((void*)h); |
63 |
|
|
} else { |
64 |
|
3 |
RET_ERR("could not create a libalpm handle", errcode, NULL); |
65 |
|
|
} |
66 |
|
|
} |
67 |
|
|
|
68 |
|
|
/* Database getters/setters */ |
69 |
|
|
|
70 |
|
39 |
static PyObject* pyalpm_get_localdb(PyObject *self, PyObject *dummy) { |
71 |
|
39 |
alpm_handle_t *handle = ALPM_HANDLE(self); |
72 |
|
39 |
return pyalpm_db_from_pmdb(alpm_get_localdb(handle)); |
73 |
|
|
} |
74 |
|
|
|
75 |
|
24 |
static PyObject* pyalpm_get_syncdbs(PyObject *self, PyObject *dummy) { |
76 |
|
24 |
alpm_handle_t *handle = ALPM_HANDLE(self); |
77 |
|
24 |
return alpmlist_to_pylist(alpm_get_syncdbs(handle), |
78 |
|
|
pyalpm_db_from_pmdb); |
79 |
|
|
} |
80 |
|
|
|
81 |
|
27 |
static PyObject* pyalpm_register_syncdb(PyObject *self, PyObject *args) { |
82 |
|
27 |
alpm_handle_t *handle = ALPM_HANDLE(self); |
83 |
|
27 |
const char *dbname; |
84 |
|
27 |
alpm_db_t *result; |
85 |
|
27 |
int pgp_level; |
86 |
|
|
|
87 |
✓✓ |
27 |
if (!PyArg_ParseTuple(args, "si", &dbname, &pgp_level)) { |
88 |
|
6 |
PyErr_Format(PyExc_TypeError, "%s() takes a string and an integer", __func__); |
89 |
|
6 |
return NULL; |
90 |
|
|
} |
91 |
|
|
|
92 |
|
21 |
result = alpm_register_syncdb(handle, dbname, pgp_level); |
93 |
✓✓ |
21 |
if (! result) { |
94 |
|
3 |
PyErr_Format(alpm_error, "unable to register sync database %s", dbname); |
95 |
|
3 |
return NULL; |
96 |
|
|
} |
97 |
|
|
|
98 |
|
18 |
return pyalpm_db_from_pmdb(result); |
99 |
|
|
} |
100 |
|
|
|
101 |
|
3 |
static PyObject* pyalpm_set_pkgreason(PyObject* self, PyObject* args) { |
102 |
|
3 |
alpm_handle_t *handle = ALPM_HANDLE(self); |
103 |
|
3 |
alpm_pkg_t *pmpkg = NULL; |
104 |
|
3 |
PyObject *pkg = NULL; |
105 |
|
3 |
alpm_pkgreason_t reason; |
106 |
|
3 |
int ret; |
107 |
✓✗ |
3 |
if (!PyArg_ParseTuple(args, "O!i:set_pkgreason", &AlpmPackageType, &pkg, &reason)) { |
108 |
|
|
return NULL; |
109 |
|
|
} |
110 |
|
3 |
pmpkg = ALPM_PACKAGE(pkg); |
111 |
|
3 |
ret = alpm_pkg_set_reason(pmpkg, reason); |
112 |
|
|
|
113 |
✓✗ |
3 |
if (ret == -1) RET_ERR("failed setting install reason", alpm_errno(handle), NULL); |
114 |
|
|
Py_RETURN_NONE; |
115 |
|
|
} |
116 |
|
|
|
117 |
|
|
/* String attributes get/setters */ |
118 |
|
|
struct _alpm_str_getset { |
119 |
|
|
const char *(*getter)(alpm_handle_t *); |
120 |
|
|
int (*setter)(alpm_handle_t *, const char *); |
121 |
|
|
}; |
122 |
|
|
|
123 |
|
9 |
static PyObject *_get_string_attr(PyObject *self, const struct _alpm_str_getset *closure) { |
124 |
|
9 |
alpm_handle_t *handle = ALPM_HANDLE(self); |
125 |
|
9 |
const char *str = closure->getter(handle); |
126 |
✗✓ |
9 |
if(str == NULL) |
127 |
|
|
RET_ERR("failed getting option value", alpm_errno(handle), NULL); |
128 |
|
9 |
return Py_BuildValue("s", str); |
129 |
|
|
} |
130 |
|
|
|
131 |
|
9 |
static int _set_string_attr(PyObject *self, PyObject *value, const struct _alpm_str_getset *closure) { |
132 |
|
9 |
alpm_handle_t *handle = ALPM_HANDLE(self); |
133 |
|
9 |
char *path = NULL; |
134 |
|
9 |
int ret; |
135 |
✓✓ |
9 |
if (PyBytes_Check(value)) { |
136 |
|
3 |
path = strdup(PyBytes_AS_STRING(value)); |
137 |
✓✓ |
6 |
} else if (PyUnicode_Check(value)) { |
138 |
|
3 |
PyObject* utf8 = PyUnicode_AsUTF8String(value); |
139 |
|
3 |
path = strdup(PyBytes_AS_STRING(utf8)); |
140 |
✗✓ |
3 |
Py_DECREF(utf8); |
141 |
|
|
} else { |
142 |
|
3 |
PyErr_SetString(PyExc_TypeError, "logfile path must be a string"); |
143 |
|
3 |
return -1; |
144 |
|
|
} |
145 |
|
|
|
146 |
|
6 |
ret = closure->setter(handle, path); |
147 |
|
6 |
free(path); |
148 |
✗✓ |
6 |
if (ret == -1) RET_ERR("failed setting option value", alpm_errno(handle), -1); |
149 |
|
|
return 0; |
150 |
|
|
} |
151 |
|
|
|
152 |
|
|
static struct _alpm_str_getset root_getset = { alpm_option_get_root, NULL }; |
153 |
|
|
static struct _alpm_str_getset dbpath_getset = { alpm_option_get_dbpath, NULL }; |
154 |
|
|
static struct _alpm_str_getset lockfile_getset = { alpm_option_get_lockfile, NULL }; |
155 |
|
|
static struct _alpm_str_getset logfile_getset = { alpm_option_get_logfile, alpm_option_set_logfile }; |
156 |
|
|
static struct _alpm_str_getset gpgdir_getset = { alpm_option_get_gpgdir, alpm_option_set_gpgdir }; |
157 |
|
|
static struct _alpm_str_getset arch_getset = { alpm_option_get_arch, alpm_option_set_arch }; |
158 |
|
|
|
159 |
|
|
/* Callback attributes get/setters */ |
160 |
|
|
typedef int (*alpm_cb_setter)(alpm_handle_t*, void*); |
161 |
|
|
struct _alpm_cb_getset { |
162 |
|
|
alpm_cb_setter setter; |
163 |
|
|
void *cb_wrapper; |
164 |
|
|
pyalpm_callback_id id; |
165 |
|
|
}; |
166 |
|
|
|
167 |
|
|
void pyalpm_eventcb(alpm_event_t event, void* data1, void *data2); |
168 |
|
|
void pyalpm_questioncb(alpm_question_t question, |
169 |
|
|
void* data1, void *data2, void* data3, int* retcode); |
170 |
|
|
void pyalpm_progresscb(alpm_progress_t op, |
171 |
|
|
const char* target_name, int percentage, size_t n_targets, size_t cur_target); |
172 |
|
|
|
173 |
|
|
static struct _alpm_cb_getset cb_getsets[N_CALLBACKS] = { |
174 |
|
|
{ (alpm_cb_setter)alpm_option_set_logcb, pyalpm_logcb, CB_LOG }, |
175 |
|
|
{ (alpm_cb_setter)alpm_option_set_dlcb, pyalpm_dlcb, CB_DOWNLOAD }, |
176 |
|
|
{ (alpm_cb_setter)alpm_option_set_fetchcb, pyalpm_fetchcb, CB_FETCH }, |
177 |
|
|
{ (alpm_cb_setter)alpm_option_set_totaldlcb, pyalpm_totaldlcb, CB_TOTALDL }, |
178 |
|
|
{ (alpm_cb_setter)alpm_option_set_eventcb, pyalpm_eventcb, CB_EVENT }, |
179 |
|
|
{ (alpm_cb_setter)alpm_option_set_questioncb, pyalpm_questioncb, CB_QUESTION }, |
180 |
|
|
{ (alpm_cb_setter)alpm_option_set_progresscb, pyalpm_progresscb, CB_PROGRESS }, |
181 |
|
|
}; |
182 |
|
|
|
183 |
|
|
/** Callback options |
184 |
|
|
* We use Python callable objects as callbacks: they are |
185 |
|
|
* stored in static variables, and the reference count is |
186 |
|
|
* increased accordingly. |
187 |
|
|
* |
188 |
|
|
* These Python functions are wrapped into C functions |
189 |
|
|
* that are passed to libalpm. |
190 |
|
|
*/ |
191 |
|
|
PyObject *global_py_callbacks[N_CALLBACKS]; |
192 |
|
|
|
193 |
|
6 |
static PyObject* _get_cb_attr(PyObject *self, const struct _alpm_cb_getset *closure) { |
194 |
|
|
/* AlpmHandle *it = self; */ |
195 |
|
6 |
PyObject *pycb = global_py_callbacks[closure->id]; |
196 |
✓✓ |
6 |
if (pycb == NULL) Py_RETURN_NONE; |
197 |
|
3 |
Py_INCREF(pycb); |
198 |
|
3 |
return pycb; |
199 |
|
|
} |
200 |
|
|
|
201 |
|
12 |
static int _set_cb_attr(PyObject *self, PyObject *value, const struct _alpm_cb_getset *closure) { |
202 |
|
12 |
AlpmHandle *it = (AlpmHandle *)self; |
203 |
✓✓ |
12 |
if (value == Py_None) { |
204 |
✗✓✗✗
|
3 |
Py_CLEAR(global_py_callbacks[closure->id]); |
205 |
|
3 |
closure->setter(it->c_data, NULL); |
206 |
✓✓ |
9 |
} else if (PyCallable_Check(value)) { |
207 |
✗✓✗✗
|
6 |
Py_CLEAR(global_py_callbacks[closure->id]); |
208 |
|
6 |
Py_INCREF(value); |
209 |
|
6 |
global_py_callbacks[closure->id] = value; |
210 |
|
6 |
closure->setter(it->c_data, closure->cb_wrapper); |
211 |
|
|
} else { |
212 |
|
3 |
PyErr_SetString(PyExc_TypeError, "value must be None or a function"); |
213 |
|
3 |
return -1; |
214 |
|
|
} |
215 |
|
|
|
216 |
|
|
return 0; |
217 |
|
|
} |
218 |
|
|
|
219 |
|
|
struct PyGetSetDef pyalpm_handle_getset[] = { |
220 |
|
|
/** filepaths */ |
221 |
|
|
{ "root", |
222 |
|
|
(getter)_get_string_attr, |
223 |
|
|
NULL, |
224 |
|
|
"system root directory", &root_getset } , |
225 |
|
|
{ "dbpath", |
226 |
|
|
(getter)_get_string_attr, |
227 |
|
|
NULL, |
228 |
|
|
"alpm database directory", &dbpath_getset } , |
229 |
|
|
{ "logfile", |
230 |
|
|
(getter)_get_string_attr, |
231 |
|
|
(setter)_set_string_attr, |
232 |
|
|
"alpm logfile path", &logfile_getset } , |
233 |
|
|
{ "lockfile", |
234 |
|
|
(getter)_get_string_attr, |
235 |
|
|
NULL, |
236 |
|
|
"alpm lockfile path", &lockfile_getset } , |
237 |
|
|
{ "gpgdir", |
238 |
|
|
(getter)_get_string_attr, |
239 |
|
|
(setter)_set_string_attr, |
240 |
|
|
"alpm GnuPG home directory", &gpgdir_getset } , |
241 |
|
|
|
242 |
|
|
/** strings */ |
243 |
|
|
{ "arch", |
244 |
|
|
(getter)_get_string_attr, |
245 |
|
|
(setter)_set_string_attr, |
246 |
|
|
"Target archichecture", &arch_getset } , |
247 |
|
|
|
248 |
|
|
/** booleans */ |
249 |
|
|
{ "usesyslog", |
250 |
|
|
(getter)option_get_usesyslog_alpm, |
251 |
|
|
(setter)option_set_usesyslog_alpm, |
252 |
|
|
"use syslog (an integer, 0 = False, 1 = True)", NULL } , |
253 |
|
|
{ "checkspace", |
254 |
|
|
(getter)option_get_checkspace_alpm, |
255 |
|
|
(setter)option_set_checkspace_alpm, |
256 |
|
|
"check disk space before transactions (an integer, 0 = False, 1 = True)", NULL } , |
257 |
|
|
|
258 |
|
|
/** lists */ |
259 |
|
|
{ "cachedirs", |
260 |
|
|
(getter)option_get_cachedirs_alpm, |
261 |
|
|
(setter)option_set_cachedirs_alpm, |
262 |
|
|
"list of package cache directories", NULL }, |
263 |
|
|
{ "noupgrades", |
264 |
|
|
(getter)option_get_noupgrades_alpm, |
265 |
|
|
(setter)option_set_noupgrades_alpm, |
266 |
|
|
"list of ...", NULL }, |
267 |
|
|
{ "noextracts", |
268 |
|
|
(getter)option_get_noextracts_alpm, |
269 |
|
|
(setter)option_set_noextracts_alpm, |
270 |
|
|
"list of ...", NULL }, |
271 |
|
|
{ "ignorepkgs", |
272 |
|
|
(getter)option_get_ignorepkgs_alpm, |
273 |
|
|
(setter)option_set_ignorepkgs_alpm, |
274 |
|
|
"list of ignored packages", NULL }, |
275 |
|
|
{ "ignoregrps", |
276 |
|
|
(getter)option_get_ignoregrps_alpm, |
277 |
|
|
(setter)option_set_ignoregrps_alpm, |
278 |
|
|
"list of ignored groups", NULL }, |
279 |
|
|
|
280 |
|
|
/** callbacks */ |
281 |
|
|
{ "logcb", |
282 |
|
|
(getter)_get_cb_attr, (setter)_set_cb_attr, |
283 |
|
|
"logging callback, with arguments (loglevel, format string, tuple)", |
284 |
|
|
&cb_getsets[CB_LOG] }, |
285 |
|
|
{ "dlcb", |
286 |
|
|
(getter)_get_cb_attr, (setter)_set_cb_attr, |
287 |
|
|
"download status callback (a function)\n" |
288 |
|
|
"args: filename :: str\n" |
289 |
|
|
" transferred :: int\n" |
290 |
|
|
" total :: int\n", |
291 |
|
|
&cb_getsets[CB_DOWNLOAD] }, |
292 |
|
|
{ "totaldlcb", |
293 |
|
|
(getter)_get_cb_attr, (setter)_set_cb_attr, |
294 |
|
|
"total download size callback: totaldlcb(total_size)", |
295 |
|
|
&cb_getsets[CB_TOTALDL] }, |
296 |
|
|
{ "fetchcb", |
297 |
|
|
(getter)_get_cb_attr, (setter)_set_cb_attr, |
298 |
|
|
"download function\n" |
299 |
|
|
"args: url :: string\n" |
300 |
|
|
" destination path :: string\n" |
301 |
|
|
" overwrite :: bool\n" |
302 |
|
|
"returns: 0 on success, 1 if file exists, -1 on error", |
303 |
|
|
&cb_getsets[CB_FETCH] }, |
304 |
|
|
{ "eventcb", |
305 |
|
|
(getter)_get_cb_attr, (setter)_set_cb_attr, |
306 |
|
|
" a function called when an event occurs\n" |
307 |
|
|
" -- args: (event ID, event string, (object 1, object 2))\n", |
308 |
|
|
&cb_getsets[CB_EVENT] }, |
309 |
|
|
{ "questioncb", |
310 |
|
|
(getter)_get_cb_attr, (setter)_set_cb_attr, |
311 |
|
|
" a function called to get user input\n", |
312 |
|
|
&cb_getsets[CB_QUESTION] }, |
313 |
|
|
{ "progresscb", |
314 |
|
|
(getter)_get_cb_attr, (setter)_set_cb_attr, |
315 |
|
|
" -- a function called to indicate progress\n" |
316 |
|
|
" -- args: (target name, percentage, number of targets, target number)\n", |
317 |
|
|
&cb_getsets[CB_PROGRESS] }, |
318 |
|
|
|
319 |
|
|
/** terminator */ |
320 |
|
|
{ NULL } |
321 |
|
|
}; |
322 |
|
|
|
323 |
|
|
static PyMethodDef pyalpm_handle_methods[] = { |
324 |
|
|
/* Transaction initialization */ |
325 |
|
|
{"init_transaction", (PyCFunction)pyalpm_trans_init, METH_VARARGS | METH_KEYWORDS, |
326 |
|
|
"Initializes a transaction.\n" |
327 |
|
|
"Arguments:\n" |
328 |
|
|
" nodeps, force, nosave, nodepversion, cascade, recurse,\n" |
329 |
|
|
" dbonly, alldeps, downloadonly, noscriptlet, noconflicts,\n" |
330 |
|
|
" needed, allexplicit, unneeded, recurseall, nolock\n" |
331 |
|
|
" -- the transaction options (booleans)\n" |
332 |
|
|
}, |
333 |
|
|
|
334 |
|
|
/* Package load */ |
335 |
|
|
{"load_pkg", (PyCFunction)pyalpm_package_load, METH_VARARGS | METH_KEYWORDS, |
336 |
|
|
"loads package information from a tarball"}, |
337 |
|
|
|
338 |
|
|
/* Database members */ |
339 |
|
|
{"register_syncdb", pyalpm_register_syncdb, METH_VARARGS, |
340 |
|
|
"registers the database with the given name\n" |
341 |
|
|
"returns the new database on success"}, |
342 |
|
|
{"get_localdb", pyalpm_get_localdb, METH_NOARGS, "returns an object representing the local DB"}, |
343 |
|
|
{"get_syncdbs", pyalpm_get_syncdbs, METH_NOARGS, "returns a list of sync DBs"}, |
344 |
|
|
{"set_pkgreason", pyalpm_set_pkgreason, METH_VARARGS, |
345 |
|
|
"set install reason for a package (PKG_REASON_DEPEND, PKG_REASON_EXPLICIT)\n"}, |
346 |
|
|
|
347 |
|
|
/* Option modifiers */ |
348 |
|
|
{"add_noupgrade", option_add_noupgrade_alpm, METH_VARARGS, "add a noupgrade package."}, |
349 |
|
|
{"remove_noupgrade", option_remove_noupgrade_alpm, METH_VARARGS, "removes a noupgrade package."}, |
350 |
|
|
|
351 |
|
|
{"add_cachedir", option_add_cachedir_alpm, METH_VARARGS, "adds a cachedir."}, |
352 |
|
|
{"remove_cachedir", option_remove_cachedir_alpm, METH_VARARGS, "removes a cachedir."}, |
353 |
|
|
|
354 |
|
|
{"add_noextract", option_add_noextract_alpm, METH_VARARGS, "add a noextract package."}, |
355 |
|
|
{"remove_noextract", option_remove_noextract_alpm, METH_VARARGS, "remove a noextract package."}, |
356 |
|
|
|
357 |
|
|
{"add_ignorepkg", option_add_ignorepkg_alpm, METH_VARARGS, "add an ignorepkg."}, |
358 |
|
|
{"remove_ignorepkg", option_remove_ignorepkg_alpm, METH_VARARGS, "remove an ignorepkg."}, |
359 |
|
|
|
360 |
|
|
{"add_ignoregrp", option_add_ignoregrp_alpm, METH_VARARGS, "add an ignoregrp."}, |
361 |
|
|
{"remove_ignoregrp", option_remove_ignoregrp_alpm, METH_VARARGS, "remove an ignoregrp."}, |
362 |
|
|
{NULL, NULL, 0, NULL}, |
363 |
|
|
}; |
364 |
|
|
|
365 |
|
108 |
static void pyalpm_dealloc(PyObject* self) { |
366 |
|
108 |
alpm_handle_t *handle = ALPM_HANDLE(self); |
367 |
|
108 |
int ret = alpm_release(handle); |
368 |
✗✓ |
108 |
if (ret == -1) { |
369 |
|
|
PyErr_Format(alpm_error, "unable to release alpm handle"); |
370 |
|
|
} |
371 |
|
108 |
handle = NULL; |
372 |
|
108 |
Py_TYPE(self)->tp_free((PyObject *)self); |
373 |
|
108 |
} |
374 |
|
|
|
375 |
|
|
PyTypeObject AlpmHandleType = { |
376 |
|
|
PyVarObject_HEAD_INIT(NULL, 0) |
377 |
|
|
"alpm.Handle", /*tp_name*/ |
378 |
|
|
sizeof(AlpmHandle), /*tp_basicsize*/ |
379 |
|
|
0, /*tp_itemsize*/ |
380 |
|
|
.tp_flags = Py_TPFLAGS_DEFAULT, |
381 |
|
|
.tp_doc = "An object wrapping a libalpm handle. Arguments: root path, DB path.", |
382 |
|
|
.tp_methods = pyalpm_handle_methods, |
383 |
|
|
.tp_getset = pyalpm_handle_getset, |
384 |
|
|
.tp_new = pyalpm_initialize, |
385 |
|
|
.tp_dealloc = (destructor) pyalpm_dealloc, |
386 |
|
|
}; |
387 |
|
|
|
388 |
|
|
/** Initializes Handle class in module */ |
389 |
|
3 |
int init_pyalpm_handle(PyObject *module) { |
390 |
|
3 |
PyObject *type; |
391 |
✓✗ |
3 |
if (PyType_Ready(&AlpmHandleType) < 0) |
392 |
|
|
return -1; |
393 |
|
3 |
type = (PyObject*)&AlpmHandleType; |
394 |
|
3 |
Py_INCREF(type); |
395 |
|
3 |
PyModule_AddObject(module, "Handle", type); |
396 |
|
|
|
397 |
|
3 |
PyModule_AddIntConstant(module, "LOG_ERROR", ALPM_LOG_ERROR); |
398 |
|
3 |
PyModule_AddIntConstant(module, "LOG_WARNING", ALPM_LOG_WARNING); |
399 |
|
3 |
PyModule_AddIntConstant(module, "LOG_DEBUG", ALPM_LOG_DEBUG); |
400 |
|
3 |
PyModule_AddIntConstant(module, "LOG_FUNCTION", ALPM_LOG_FUNCTION); |
401 |
|
|
|
402 |
|
3 |
return 0; |
403 |
|
|
} |
404 |
|
|
|
405 |
|
|
/* vim: set ts=2 sw=2 et: */ |