[gnome-python] Bug 507174 – Convert from popt to GOption
- From: Gustavo J. A. M. Carneiro <gjc src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnome-python] Bug 507174 – Convert from popt to GOption
- Date: Sun, 26 Apr 2009 07:23:30 -0400 (EDT)
commit d62b041db415ff2e072bc55b064f6c3e7696f7af
Author: Tristan Hill <stan saticed me uk>
Date: Sun Apr 26 12:22:22 2009 +0100
Bug 507174 â?? Convert from popt to GOption
---
Makefile.am | 3 +-
configure.ac | 4 +
examples/popt/goption.py | 36 +++++++
gnome/gnome.override | 239 +++++++++++++++++++++++++++++-----------------
wscript | 2 +
5 files changed, 197 insertions(+), 87 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index a49edad..55649f9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -64,7 +64,8 @@ EXTRA_DIST = \
examples/vfs/pygvfsmethod/README \
examples/vfs/pygvfsmethod/pyfs.conf \
examples/vfs/pygvfsmethod/pyfs.py \
- examples/popt/popt.py
+ examples/popt/popt.py \
+ examples/popt/goption.py
$(srcdir)/ChangeLog:
diff --git a/configure.ac b/configure.ac
index 5a02895..62e9ca4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -24,6 +24,7 @@ m4_define(gconf_required_version, 2.11.1)
m4_define(bonobo_activation_required_version, 2.8.0)
m4_define(libbonobo_required_version, 2.8.0)
m4_define(libbonoboui_required_version, 2.8.0)
+m4_define(pyobject_required_version, 2.15.0)
AC_INIT(gnome-python, gnome_python_version,
[http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-python])
@@ -69,6 +70,9 @@ AM_CHECK_PYTHON_HEADERS(,[AC_MSG_ERROR(could not find Python headers or library)
dnl make the python compiler used globally
CC="$PYTHON_CC"
+dnl check for pygobject
+PKG_CHECK_MODULES(PYGOBJECT, pygobject-2.0 >= pygobject_required_version)
+
dnl check for pygtk
PKG_CHECK_MODULES(PYGTK, pygtk-2.0 >= pygtk_required_version)
AC_SUBST(PYGTK_CFLAGS)
diff --git a/examples/popt/goption.py b/examples/popt/goption.py
new file mode 100644
index 0000000..6541ebb
--- /dev/null
+++ b/examples/popt/goption.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+
+"""
+http://live.gnome.org/GnomeGoals/PoptGOption
+
+Since GNOME 2.10, GLib provides GOption, a commandline option parser.
+The help output of your program will be much nicer :-) And it will enable us to
+slowly get rid of popt (even if libgnome will still have to depend on it for
+compatibility reasons).
+
+"""
+
+import sys
+
+import glib
+import gnome
+
+def callback(name, value, group):
+ if name == "--example":
+ print "example got %s" % value
+ elif name in ("-o", "--option"):
+ print "option"
+ else:
+ print "remaining:", value
+
+group = glib.OptionGroup(None, None, None, callback)
+group.add_entries([("example", "\0", 0, "An example option",
+ "option"),
+ ("option", "o", glib.OPTION_FLAG_NO_ARG, "An option",
+ None),
+ (glib.OPTION_REMAINING, "\0", 0, "", None),
+ ])
+context = glib.OptionContext("argument")
+context.set_main_group(group)
+
+prog = gnome.init("myprog", "1.0", argv=sys.argv, option_context=context)
diff --git a/gnome/gnome.override b/gnome/gnome.override
index 0a67618..ba7c42d 100644
--- a/gnome/gnome.override
+++ b/gnome/gnome.override
@@ -278,6 +278,117 @@ popt_build_table(PyObject *table)
return NULL;
}
+static PyTypeObject *
+get_option_context_type()
+{
+ PyObject *module;
+ PyTypeObject *type;
+ if ((module = PyImport_ImportModule("glib")) != NULL) {
+ type = (PyTypeObject *)PyObject_GetAttrString(module, "OptionContext");
+ Py_DECREF(module);
+ if (type == NULL) {
+ PyErr_SetString(PyExc_ImportError,
+ "cannot import OptionContext from glib");
+ return NULL;
+ } else
+ return type;
+ } else {
+ PyErr_SetString(PyExc_ImportError, "could not import glib");
+ return NULL;
+ }
+}
+
+static int
+build_gnome_init_params(PyObject *py_properties,
+ struct poptOption *popt_table, int flags,
+ PyObject *option_context,
+ PyObject **py_properties_items, Py_ssize_t *nparams,
+ GParameter **params_ptr)
+{
+ Py_ssize_t py_properties_len = -1;
+ PyObject *items = NULL;
+ if (py_properties) {
+ *py_properties_items = items = PyMapping_Items(py_properties);
+ if (!items)
+ return 0;
+ *nparams = py_properties_len = PyList_GET_SIZE(items);
+ } else
+ *nparams = 0;
+ if (popt_table)
+ *nparams += 2;
+ if (option_context)
+ *nparams += 1;
+
+ GParameter *params = NULL;
+ if (*nparams) {
+ params = g_new0(GParameter, *nparams);
+ if (!params) {
+ PyErr_NoMemory();
+ return 0;
+ }
+ }
+ Py_ssize_t i = 0;
+ if (py_properties) {
+ PyObject *item, *key, *val;
+ GType type;
+ for (; i < py_properties_len; ++i) {
+ item = PyList_GET_ITEM(items, i);
+ key = PyTuple_GET_ITEM(item, 0);
+ val = PyTuple_GET_ITEM(item, 1);
+ type = pyg_type_from_object((PyObject *) val->ob_type);
+ if (type == 0)
+ goto error;
+ params[i].name = PyString_AsString(key);
+ g_value_init(¶ms[i].value, type);
+ if (pyg_value_from_pyobject(¶ms[i].value, val))
+ goto error;
+ continue;
+ error:
+ {
+ int j;
+ for (j = 0; j < i; ++j)
+ g_value_unset(¶ms[j].value);
+ g_free(params);
+ Py_DECREF(items);
+ return 0;
+ }
+ }
+ }
+ if (popt_table) {
+ params[i].name = GNOME_PARAM_POPT_TABLE;
+ g_value_init(¶ms[i].value, G_TYPE_POINTER);
+ g_value_set_pointer(¶ms[i].value, popt_table);
+ i++;
+ params[i].name = GNOME_PARAM_POPT_FLAGS;
+ g_value_init(¶ms[i].value, G_TYPE_INT);
+ g_value_set_int(¶ms[i].value, flags);
+ }
+ if (option_context) {
+ params[i].name = GNOME_PARAM_GOPTION_CONTEXT;
+ g_value_init(¶ms[i].value, G_TYPE_POINTER);
+ PyObject* context = PyObject_CallMethod(option_context, "_get_context", NULL);
+ g_value_set_pointer(¶ms[0].value, PyCObject_AsVoidPtr(context));
+ Py_DECREF(context);
+ }
+
+ *params_ptr = params;
+ return 1;
+}
+
+static void
+free_gnome_init_params(PyObject *py_properties_items, Py_ssize_t nparams,
+ GParameter *params)
+{
+ Py_XDECREF(py_properties_items);
+ if (nparams)
+ {
+ Py_ssize_t i;
+ for (i = 0; i < nparams; ++i)
+ g_value_unset(¶ms[i].value);
+ g_free(params);
+ }
+}
+
static PyObject *
_wrap_gnome_program_init(PyObject *self,
PyObject *args,
@@ -285,13 +396,13 @@ _wrap_gnome_program_init(PyObject *self,
{
static char *kwlist[] = { "app_id", "app_version", "module_info",
"argv", "popt_table", "popt_flags",
- "properties", NULL };
+ "option_context", "properties", NULL };
gchar *app_id;
gchar *app_version;
PyObject *av = NULL;
int argc;
char **argv, **leftover_args;
- int i, len;
+ int i;
GnomeModuleInfo *moduleinfo;
GnomeProgram *program;
struct sigaction sa;
@@ -301,22 +412,32 @@ _wrap_gnome_program_init(PyObject *self,
PyObject *m = NULL;
PyObject *argdict, *py_leftover_args;
PyObject *tmpobj;
+ PyObject *option_context = NULL;
PyObject *py_properties = NULL;
PyObject *py_properties_items = NULL;
GParameter *params;
- int nparams;
+ Py_ssize_t nparams;
poptContext ctx = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwargs,
- "ss|OO!O!iO!:gnome.program_init", kwlist,
- &app_id, &app_version, &m,
- &PyList_Type, &av,
- &PyList_Type, &table,
+ PyTypeObject *py_goption_context_type = get_option_context_type();
+ if (!py_goption_context_type) {
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "ss|OO!O!iO!O!:gnome.program_init",
+ kwlist,
+ &app_id, &app_version, &m,
+ &PyList_Type, &av,
+ &PyList_Type, &table,
&flags,
+ py_goption_context_type, &option_context,
&PyDict_Type, &py_properties)) {
return NULL;
}
+ Py_DECREF(py_goption_context_type);
+
if (m == NULL) {
moduleinfo = (GnomeModuleInfo *) libgnome_module_info_get();
} else {
@@ -329,92 +450,40 @@ _wrap_gnome_program_init(PyObject *self,
}
}
- if (table != NULL) {
- popt_table = popt_build_table(table);
- if (popt_table == NULL)
- return NULL;
- }
-
if (av == NULL) {
/* ... use argc and argv from sys */
av = PySys_GetObject("argv");
}
+ argc = PyList_Size(av);
+ argv = g_new(char *, argc);
+ if (!argv)
+ return PyErr_NoMemory();
+ for (i = 0; i < argc; i++)
+ argv[i] = PyString_AsString(PyList_GetItem(av, i));
- if (py_properties)
- {
- PyObject *items, *item, *key, *val;
- py_properties_items = items = PyMapping_Items(py_properties);
- if (!items)
+ if (table != NULL) {
+ popt_table = popt_build_table(table);
+ if (!popt_table)
return NULL;
- len = PyList_GET_SIZE(items);
- nparams = popt_table? len + 2 : len;
- params = g_new0(GParameter, nparams);
- for (i = 0; i < len; ++i) {
- GType type;
- item = PyList_GET_ITEM(items, i);
- key = PyTuple_GET_ITEM(item, 0);
- val = PyTuple_GET_ITEM(item, 1);
- type = pyg_type_from_object((PyObject *) val->ob_type);
- if (type == 0)
- goto error;
- params[i].name = PyString_AsString(key);
- g_value_init(¶ms[i].value, type);
- if (pyg_value_from_pyobject(¶ms[i].value, val))
- goto error;
- continue;
- error:
- {
- int j;
- for (j = 0; j < i; ++j)
- g_value_unset(¶ms[j].value);
- g_free(params);
- Py_DECREF(items);
- if (popt_table)
- popt_destroy_table(popt_table);
- return NULL;
- }
- }
- } else {
- if (popt_table) {
- nparams = 2;
- params = g_new0(GParameter, nparams);
- i = 0;
- } else {
- nparams = 0;
- params = NULL;
- i = 0;
- }
}
- if (popt_table) {
- params[i].name = GNOME_PARAM_POPT_TABLE;
- g_value_init(¶ms[i].value, G_TYPE_POINTER);
- g_value_set_pointer(¶ms[i].value, popt_table);
- i++;
- params[i].name = GNOME_PARAM_POPT_FLAGS;
- g_value_init(¶ms[i].value, G_TYPE_INT);
- g_value_set_int(¶ms[i].value, flags);
+ if (!build_gnome_init_params(py_properties, popt_table, flags,
+ option_context,
+ &py_properties_items, &nparams, ¶ms)) {
+ if (popt_table)
+ popt_destroy_table(popt_table);
+ return NULL;
}
- argc = PyList_Size(av);
- argv = g_new(char *, argc);
- for (i = 0; i < argc; i++)
- argv[i] = PyString_AsString(PyList_GetItem(av, i));
-
memset(&sa, 0, sizeof(sa));
sigaction(SIGCHLD, NULL, &sa);
-
- /* --- */
program = gnome_program_init_paramv(GNOME_TYPE_PROGRAM,
- app_id, app_version,
+ app_id, app_version,
moduleinfo, argc, argv,
- nparams, params);
+ (guint) nparams, params);
- Py_XDECREF(py_properties_items);
- for (i = 0; i < nparams; ++i)
- g_value_unset(¶ms[i].value);
- g_free(params);
+ free_gnome_init_params(py_properties_items, nparams, params);
if (!program) {
PyErr_SetString(PyExc_RuntimeError,
@@ -431,12 +500,11 @@ _wrap_gnome_program_init(PyObject *self,
setlocale(LC_NUMERIC, "C");
#endif
- if (popt_table)
- {
+ if (popt_table) {
/* get argdict, store in object for later use */
argdict = (PyObject *) popt_table[0].descrip;
Py_INCREF(argdict);
- g_object_set_data_full(G_OBJECT(program),
+ g_object_set_data_full(G_OBJECT(program),
"gnome-python-popt-argdict",
argdict, __py_object_free);
@@ -445,8 +513,7 @@ _wrap_gnome_program_init(PyObject *self,
leftover_args = (char **) poptGetArgs(ctx);
py_leftover_args = PyList_New(0);
if (!py_leftover_args) {
- PyErr_NoMemory();
- return NULL;
+ return PyErr_NoMemory();
}
if (leftover_args) {
for (i = 0; leftover_args[i]; i++) {
@@ -463,7 +530,7 @@ _wrap_gnome_program_init(PyObject *self,
Py_DECREF(tmpobj);
}
}
- g_object_set_data_full(G_OBJECT(program),
+ g_object_set_data_full(G_OBJECT(program),
"gnome-python-popt-leftover-args",
py_leftover_args, __py_object_free);
@@ -473,11 +540,11 @@ _wrap_gnome_program_init(PyObject *self,
#if (defined(HAVE_PRCTL) && defined(PR_SET_NAME)) || defined(HAVE_SETPROCTITLE)
if (argv && argv[0]) {
#if defined(HAVE_PRCTL) && defined(PR_SET_NAME)
- if (prctl(PR_SET_NAME, (unsigned long) argv[0], 0, 0, 0)) {
+ if (prctl(PR_SET_NAME, (unsigned long) argv[0], 0, 0, 0)) {
g_warning("prctl() failed");
}
#elif defined(HAVE_SETPROCTITLE)
- setproctitle("-%s", argv[0]);
+ setproctitle("-%s", argv[0]);
#endif
}
#endif
diff --git a/wscript b/wscript
index 26cfccf..c1a0baa 100644
--- a/wscript
+++ b/wscript
@@ -81,6 +81,8 @@ def configure(conf):
conf.pkg_check_modules('PYGTK', 'pygtk-2.0 >= %s' % ('.'.join([str(x) for x in pygtk_version]),))
conf.env['PYGTK_DEFSDIR'] = conf.pkg_check_module_variable('pygtk-2.0', 'defsdir')
+ conf.pkg_check_modules('PYGOBJECT', 'pygobject-2.0 >= 2.17.0', mandatory=True)
+
if not conf.find_program('pygobject-codegen-2.0', var='CODEGEN'):
if not conf.find_program('pygtk-codegen-2.0', var='CODEGEN'):
Params.fatal("Could not find pygobject/pygtk codegen")
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]