Add gitlab CI tests
[pygobject.git] / gi / pygoptiongroup.c
blobe91ca05a7c1d2bfa3e80288c61c84131ad922b42
1 /* -*- Mode: C; c-basic-offset: 4 -*-
2 * pygobject - Python bindings for the GLib, GObject and GIO
3 * Copyright (C) 2006 Johannes Hoelzl
5 * pygoptiongroup.c: GOptionContext and GOptionGroup wrapper
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
25 #include <pyglib.h>
26 #include "pygoptiongroup.h"
27 #include "pygi-error.h"
29 PYGLIB_DEFINE_TYPE("gi._gi.OptionGroup", PyGOptionGroup_Type, PyGOptionGroup)
31 /**
32 * pyg_option_group_new:
33 * @group: a GOptionGroup
35 * The returned GOptionGroup can't be used to set any hooks, translation domains
36 * or add entries. It's only intend is, to use for GOptionContext.add_group().
38 * Returns: the GOptionGroup wrapper.
40 PyObject *
41 pyg_option_group_new (GOptionGroup *group)
43 PyGOptionGroup *self;
45 self = (PyGOptionGroup *)PyObject_NEW(PyGOptionGroup,
46 &PyGOptionGroup_Type);
47 if (self == NULL)
48 return NULL;
50 self->group = group;
51 self->other_owner = TRUE;
52 self->is_in_context = FALSE;
54 return (PyObject *)self;
57 static gboolean
58 check_if_owned(PyGOptionGroup *self)
60 if (self->other_owner)
62 PyErr_SetString(PyExc_ValueError, "The GOptionGroup was not created by "
63 "gi._gi.OptionGroup(), so operation is not possible.");
64 return TRUE;
66 return FALSE;
69 static void
70 destroy_g_group(PyGOptionGroup *self)
72 PyGILState_STATE state;
73 state = PyGILState_Ensure();
75 self->group = NULL;
76 Py_CLEAR(self->callback);
77 g_slist_foreach(self->strings, (GFunc) g_free, NULL);
78 g_slist_free(self->strings);
79 self->strings = NULL;
81 if (self->is_in_context)
83 Py_DECREF(self);
86 PyGILState_Release(state);
89 static int
90 pyg_option_group_init(PyGOptionGroup *self, PyObject *args, PyObject *kwargs)
92 static char *kwlist[] = { "name", "description", "help_description",
93 "callback", NULL };
94 char *name, *description, *help_description;
95 PyObject *callback;
97 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zzzO:GOptionGroup.__init__",
98 kwlist, &name, &description,
99 &help_description, &callback))
100 return -1;
102 self->group = g_option_group_new(name, description, help_description,
103 self, (GDestroyNotify) destroy_g_group);
104 self->other_owner = FALSE;
105 self->is_in_context = FALSE;
107 Py_INCREF(callback);
108 self->callback = callback;
110 return 0;
113 static void
114 pyg_option_group_dealloc(PyGOptionGroup *self)
116 if (!self->other_owner && !self->is_in_context)
118 GOptionGroup *tmp = self->group;
119 self->group = NULL;
120 if (tmp) {
121 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
122 g_option_group_free(tmp);
123 G_GNUC_END_IGNORE_DEPRECATIONS
127 PyObject_Del(self);
130 static gboolean
131 arg_func(const gchar *option_name,
132 const gchar *value,
133 PyGOptionGroup *self,
134 GError **error)
136 PyObject *ret;
137 PyGILState_STATE state;
138 gboolean no_error;
140 state = PyGILState_Ensure();
141 if (value == NULL)
142 ret = PyObject_CallFunction(self->callback, "sOO",
143 option_name, Py_None, self);
144 else
145 ret = PyObject_CallFunction(self->callback, "ssO",
146 option_name, value, self);
148 if (ret != NULL)
150 Py_DECREF(ret);
151 no_error = TRUE;
152 } else
153 no_error = pygi_gerror_exception_check(error) != -1;
155 PyGILState_Release(state);
156 return no_error;
159 static PyObject *
160 pyg_option_group_add_entries(PyGOptionGroup *self, PyObject *args,
161 PyObject *kwargs)
163 static char *kwlist[] = { "entries", NULL };
164 gssize entry_count, pos;
165 PyObject *entry_tuple, *list;
166 GOptionEntry *entries;
168 if (check_if_owned(self))
169 return NULL;
171 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionGroup.add_entries",
172 kwlist, &list))
173 return NULL;
175 if (!PyList_Check(list))
177 PyErr_SetString(PyExc_TypeError,
178 "GOptionGroup.add_entries expected a list of entries");
179 return NULL;
182 entry_count = PyList_Size(list);
183 if (entry_count == -1)
185 PyErr_SetString(PyExc_TypeError,
186 "GOptionGroup.add_entries expected a list of entries");
187 return NULL;
190 entries = g_new0(GOptionEntry, entry_count + 1);
191 for (pos = 0; pos < entry_count; pos++)
193 gchar *long_name, *description, *arg_description;
194 entry_tuple = PyList_GetItem(list, pos);
195 if (!PyTuple_Check(entry_tuple))
197 PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries "
198 "expected a list of entries");
199 g_free(entries);
200 return NULL;
202 if (!PyArg_ParseTuple(entry_tuple, "scisz",
203 &long_name,
204 &(entries[pos].short_name),
205 &(entries[pos].flags),
206 &description,
207 &arg_description))
209 PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries "
210 "expected a list of entries");
211 g_free(entries);
212 return NULL;
214 long_name = g_strdup(long_name);
215 self->strings = g_slist_prepend(self->strings, long_name);
216 entries[pos].long_name = long_name;
218 description = g_strdup(description);
219 self->strings = g_slist_prepend(self->strings, description);
220 entries[pos].description = description;
222 arg_description = g_strdup(arg_description);
223 self->strings = g_slist_prepend(self->strings, arg_description);
224 entries[pos].arg_description = arg_description;
226 entries[pos].arg = G_OPTION_ARG_CALLBACK;
227 entries[pos].arg_data = arg_func;
230 g_option_group_add_entries(self->group, entries);
232 g_free(entries);
234 Py_INCREF(Py_None);
235 return Py_None;
239 static PyObject *
240 pyg_option_group_set_translation_domain(PyGOptionGroup *self,
241 PyObject *args,
242 PyObject *kwargs)
244 static char *kwlist[] = { "domain", NULL };
245 char *domain;
247 if (check_if_owned(self))
248 return NULL;
250 if (self->group == NULL)
252 PyErr_SetString(PyExc_RuntimeError,
253 "The corresponding GOptionGroup was already freed, "
254 "probably through the release of GOptionContext");
255 return NULL;
258 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
259 "z:GOptionGroup.set_translate_domain",
260 kwlist, &domain))
261 return NULL;
263 g_option_group_set_translation_domain(self->group, domain);
265 Py_INCREF(Py_None);
266 return Py_None;
269 static PyObject*
270 pyg_option_group_richcompare(PyObject *self, PyObject *other, int op)
272 if (Py_TYPE(self) == Py_TYPE(other) &&
273 Py_TYPE(self) == &PyGOptionGroup_Type) {
274 return _pyglib_generic_ptr_richcompare(((PyGOptionGroup*)self)->group,
275 ((PyGOptionGroup*)other)->group,
276 op);
277 } else {
278 Py_INCREF(Py_NotImplemented);
279 return Py_NotImplemented;
283 static PyMethodDef pyg_option_group_methods[] = {
284 { "add_entries", (PyCFunction)pyg_option_group_add_entries, METH_VARARGS | METH_KEYWORDS },
285 { "set_translation_domain", (PyCFunction)pyg_option_group_set_translation_domain, METH_VARARGS | METH_KEYWORDS },
286 { NULL, NULL, 0 },
289 void
290 pyglib_option_group_register_types(PyObject *d)
292 PyGOptionGroup_Type.tp_dealloc = (destructor)pyg_option_group_dealloc;
293 PyGOptionGroup_Type.tp_richcompare = pyg_option_group_richcompare;
294 PyGOptionGroup_Type.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
295 PyGOptionGroup_Type.tp_methods = pyg_option_group_methods;
296 PyGOptionGroup_Type.tp_init = (initproc)pyg_option_group_init;
297 PYGLIB_REGISTER_TYPE(d, PyGOptionGroup_Type, "OptionGroup");