/* -*- Mode: C; c-basic-offset: 4 -*- * pygtk- Python bindings for the GTK toolkit. * Copyright (C) 2006 Johannes Hoelzl * * pygoptioncontext.c: GOptionContext wrapper * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, see . */ #include #include "pygoptioncontext.h" #include "pygi-error.h" #include "pygi-util.h" #include "pygi-basictype.h" PYGI_DEFINE_TYPE("gi._gi.OptionContext", PyGOptionContext_Type, PyGOptionContext) /** * pyg_option_group_transfer_group: * @group: a GOptionGroup wrapper * * This is used to transfer the GOptionGroup to a GOptionContext. After this * is called, the calle must handle the release of the GOptionGroup. * * When #NULL is returned, the GOptionGroup was already transfered. * * Returns: Either #NULL or the wrapped GOptionGroup. */ static GOptionGroup * pyglib_option_group_transfer_group(PyObject *obj) { PyGOptionGroup *self = (PyGOptionGroup*)obj; if (self->is_in_context) return NULL; self->is_in_context = TRUE; /* Here we increase the reference count of the PyGOptionGroup, because now * the GOptionContext holds an reference to us (it is the userdata passed * to g_option_group_new(). * * The GOptionGroup is freed with the GOptionContext. * * We set it here because if we would do this in the init method we would * hold two references and the PyGOptionGroup would never be freed. */ Py_INCREF(self); return self->group; } /** * pyg_option_context_new: * @context: a GOptionContext * * Returns: A new GOptionContext wrapper. */ PyObject * pyg_option_context_new (GOptionContext *context) { PyGOptionContext *self; self = (PyGOptionContext *)PyObject_NEW(PyGOptionContext, &PyGOptionContext_Type); if (self == NULL) return NULL; self->context = context; self->main_group = NULL; return (PyObject *)self; } static int pyg_option_context_init(PyGOptionContext *self, PyObject *args, PyObject *kwargs) { char *parameter_string; if (!PyArg_ParseTuple(args, "s:gi._gi.GOptionContext.__init__", ¶meter_string)) return -1; self->context = g_option_context_new(parameter_string); return 0; } static void pyg_option_context_dealloc(PyGOptionContext *self) { Py_CLEAR(self->main_group); if (self->context != NULL) { GOptionContext *tmp = self->context; self->context = NULL; g_option_context_free(tmp); } PyObject_Del(self); } static PyObject * pyg_option_context_parse(PyGOptionContext *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "argv", NULL }; PyObject *arg; PyObject *new_argv, *argv; Py_ssize_t argv_length, pos; gint argv_length_int; char **argv_content, **original; GError *error = NULL; gboolean result; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.parse", kwlist, &argv)) return NULL; if (!PyList_Check(argv)) { PyErr_SetString(PyExc_TypeError, "GOptionContext.parse expects a list of strings."); return NULL; } argv_length = PyList_Size(argv); if (argv_length == -1) { PyErr_SetString(PyExc_TypeError, "GOptionContext.parse expects a list of strings."); return NULL; } argv_content = g_new(char*, argv_length + 1); argv_content[argv_length] = NULL; for (pos = 0; pos < argv_length; pos++) { arg = PyList_GetItem(argv, pos); argv_content[pos] = g_strdup(PyUnicode_AsUTF8 (arg)); if (argv_content[pos] == NULL) { g_strfreev(argv_content); return NULL; } } original = g_strdupv(argv_content); g_assert(argv_length <= G_MAXINT); argv_length_int = (gint)argv_length; Py_BEGIN_ALLOW_THREADS; result = g_option_context_parse(self->context, &argv_length_int, &argv_content, &error); Py_END_ALLOW_THREADS; argv_length = argv_length_int; if (!result) { g_strfreev(argv_content); g_strfreev(original); pygi_error_check(&error); return NULL; } new_argv = PyList_New(g_strv_length(argv_content)); for (pos = 0; pos < argv_length; pos++) { arg = PyUnicode_FromString (argv_content[pos]); PyList_SetItem(new_argv, pos, arg); } g_strfreev(original); g_strfreev(argv_content); return new_argv; } static PyObject * pyg_option_context_set_help_enabled(PyGOptionContext *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "help_enable", NULL }; PyObject *help_enabled; if (! PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.set_help_enabled", kwlist, &help_enabled)) return NULL; g_option_context_set_help_enabled(self->context, PyObject_IsTrue(help_enabled)); Py_INCREF(Py_None); return Py_None; } static PyObject * pyg_option_context_get_help_enabled(PyGOptionContext *self) { return pygi_gboolean_to_py (g_option_context_get_help_enabled(self->context)); } static PyObject * pyg_option_context_set_ignore_unknown_options(PyGOptionContext *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "ignore_unknown_options", NULL }; PyObject *ignore_unknown_options; if (! PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.set_ignore_unknown_options", kwlist, &ignore_unknown_options)) return NULL; g_option_context_set_ignore_unknown_options(self->context, PyObject_IsTrue(ignore_unknown_options)); Py_INCREF(Py_None); return Py_None; } static PyObject * pyg_option_context_get_ignore_unknown_options(PyGOptionContext *self) { return pygi_gboolean_to_py ( g_option_context_get_ignore_unknown_options(self->context)); } static PyObject * pyg_option_context_set_main_group(PyGOptionContext *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "group", NULL }; GOptionGroup *g_group; PyObject *group; if (! PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.set_main_group", kwlist, &group)) return NULL; if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) { PyErr_SetString(PyExc_TypeError, "GOptionContext.set_main_group expects a GOptionGroup."); return NULL; } g_group = pyglib_option_group_transfer_group(group); if (g_group == NULL) { PyErr_SetString(PyExc_RuntimeError, "Group is already in a OptionContext."); return NULL; } g_option_context_set_main_group(self->context, g_group); Py_INCREF(group); self->main_group = (PyGOptionGroup*) group; Py_INCREF(Py_None); return Py_None; } static PyObject * pyg_option_context_get_main_group(PyGOptionContext *self) { if (self->main_group == NULL) { Py_INCREF(Py_None); return Py_None; } Py_INCREF(self->main_group); return (PyObject*) self->main_group; } static PyObject * pyg_option_context_add_group(PyGOptionContext *self, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "group", NULL }; GOptionGroup *g_group; PyObject *group; if (! PyArg_ParseTupleAndKeywords(args, kwargs, "O:GOptionContext.add_group", kwlist, &group)) return NULL; if (PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) { PyErr_SetString(PyExc_TypeError, "GOptionContext.add_group expects a GOptionGroup."); return NULL; } g_group = pyglib_option_group_transfer_group(group); if (g_group == NULL) { PyErr_SetString(PyExc_RuntimeError, "Group is already in a OptionContext."); return NULL; } Py_INCREF(group); g_option_context_add_group(self->context, g_group); Py_INCREF(Py_None); return Py_None; } static PyObject* pyg_option_context_richcompare(PyObject *self, PyObject *other, int op) { if (Py_TYPE(self) == Py_TYPE(other) && Py_TYPE(self) == &PyGOptionContext_Type) return pyg_ptr_richcompare(((PyGOptionContext*)self)->context, ((PyGOptionContext*)other)->context, op); else { Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } } static PyObject * pyg_option_get_context(PyGOptionContext *self) { return PyCapsule_New (self->context, "goption.context", NULL); } static PyMethodDef pyg_option_context_methods[] = { { "parse", (PyCFunction)pyg_option_context_parse, METH_VARARGS | METH_KEYWORDS }, { "set_help_enabled", (PyCFunction)pyg_option_context_set_help_enabled, METH_VARARGS | METH_KEYWORDS }, { "get_help_enabled", (PyCFunction)pyg_option_context_get_help_enabled, METH_NOARGS }, { "set_ignore_unknown_options", (PyCFunction)pyg_option_context_set_ignore_unknown_options, METH_VARARGS | METH_KEYWORDS }, { "get_ignore_unknown_options", (PyCFunction)pyg_option_context_get_ignore_unknown_options, METH_NOARGS }, { "set_main_group", (PyCFunction)pyg_option_context_set_main_group, METH_VARARGS | METH_KEYWORDS }, { "get_main_group", (PyCFunction)pyg_option_context_get_main_group, METH_NOARGS }, { "add_group", (PyCFunction)pyg_option_context_add_group, METH_VARARGS | METH_KEYWORDS }, { "_get_context", (PyCFunction)pyg_option_get_context, METH_NOARGS }, { NULL, NULL, 0 }, }; /** * Returns 0 on success, or -1 and sets an exception. */ int pygi_option_context_register_types(PyObject *d) { PyGOptionContext_Type.tp_dealloc = (destructor)pyg_option_context_dealloc; PyGOptionContext_Type.tp_richcompare = pyg_option_context_richcompare; PyGOptionContext_Type.tp_flags = Py_TPFLAGS_DEFAULT; PyGOptionContext_Type.tp_methods = pyg_option_context_methods; PyGOptionContext_Type.tp_init = (initproc)pyg_option_context_init; PyGOptionContext_Type.tp_alloc = PyType_GenericAlloc; PyGOptionContext_Type.tp_new = PyType_GenericNew; if (PyType_Ready(&PyGOptionContext_Type)) return -1; PyDict_SetItemString(d, "OptionContext", (PyObject *)&PyGOptionContext_Type); return 0; }