Re: Bug 307312: gnome_program_init () should support GOption



I fixed a bug in my libgnome patch concerning error handling of
goption_context_parse. So now it will inform the user of incorrect options and
tell them to type --help. So please use this libgnome patch instead of the old one.

Pawel Sliwowski

On Sun, 2005-06-19 at 14:41 +0000, Pawel Sliwowski wrote:
> Almost forgot, these patches are depends on the patch from Bug 302632:
> no way to have a no-arg G_OPTION_ARG_CALLBACK; which has been committed.
> So you need update glib.
> 
> Pawel Sliwowski
> 
> On Sun, 2005-06-19 at 14:17 +0000, Pawel Sliwowski wrote:
> > Here is a patch set, which enables the use of goption to libgnome. This
> > should help move away from libgnome and popt for gnome apps. I used
> > expansion1 in GnomeModuleInfo to get GOptionGroup from all the modules.
> > 
> > There are 4 new GNOME PARMS
> > - PARM_GOPTION_CONTEXT (readonly) - GOption Context
> > - PARM_GOPTION_TABLE - The Applications GOptionEntry
> > - PARM_GOPTION_NAME - The name to add to help
> > - PARM_GOPTION_ENABLE - tell libgnome to use goption (default is FALSE)
> > 
> > I needed to patch libgnome,libgnomeui,libbonobo and libbonobui.
> > 
> > I also added a test case for people that want to try it out.
> > 
> > The help output look like this with goption enable:
> > 
> > Usage:
> >   test [OPTION...] - Test
> > 
> > Help Options:
> >   -?, --help                       Show help options
> >   --help-all                       Show all help options
> >   --help-gtk                       Show GTK+ Options
> >   --help-bonbo_activation          Show Bonobo Activation Options
> >   --help-libgnome                  Show Gnome Library Options
> >   --help-gnome-client              Show Session management Options
> >   --help-libgnomeui                Show GNOME GUI Library Options
> > 
> > Application Options:
> >   --encoding                       Set the character encoding to be used to open  the files listed on the command line
> >   --quit                           Quit an existing instance of gedit
> >   --new-window                     Create a new toplevel window in an existing i nstance of gedit
> >   --new-document                   Create a new document in an existing instance  of gedit
> >   --display=DISPLAY                X display to use
> > 
> > 
> > 
? compile.log
? depcomp
? gtk-doc.make
? libgnome-zip
? stamp-h1
? doc/reference/version.xml
? libgnome/stamp-libgnometypebuiltins.h
Index: libgnome/gnome-init.c
===================================================================
RCS file: /cvs/gnome/libgnome/libgnome/gnome-init.c,v
retrieving revision 1.110
diff -u -r1.110 gnome-init.c
--- libgnome/gnome-init.c	28 Mar 2005 15:45:07 -0000	1.110
+++ libgnome/gnome-init.c	20 Jun 2005 20:16:45 -0000
@@ -36,6 +36,7 @@
 #include <sys/stat.h>
 
 #include <glib.h>
+#include <glib/goption.h>
 #include <glib/gstdio.h>
 #include "gnome-i18nP.h"
 
@@ -146,6 +147,9 @@
 		bonobo_activation_pre_args_parse, bonobo_activation_post_args_parse,
 		bonobo_activation_popt_options
 	};
+
+	module_info.expansion1 = (gpointer) bonobo_activation_get_goption_group();
+
 	if (module_info.version == NULL) {
 		module_info.version = g_strdup_printf
 			("%d.%d.%d",
@@ -263,6 +267,67 @@
 	}
 }
 
+static gboolean
+libgnome_goption_epeaker (const gchar *option_name,
+			const gchar *value,
+			gpointer data,
+			GError **error)
+{
+	GValue setvalue = { 0 };
+	g_value_init (&setvalue, G_TYPE_STRING);
+	g_value_set_string (&setvalue, value);
+	g_object_set_property (G_OBJECT (gnome_program_get()),
+		GNOME_PARAM_ESPEAKER, &setvalue);
+	g_value_unset (&setvalue);
+	return TRUE;
+}
+
+static gboolean
+libgnome_goption_disable_sound (const gchar *option_name,
+			const gchar *value,
+			gpointer data,
+			GError **error)
+{
+	GValue setvalue = { 0 };
+	g_value_init (&setvalue, G_TYPE_BOOLEAN);
+	g_value_set_boolean (&setvalue, FALSE);
+	g_object_set_property (G_OBJECT (gnome_program_get()),
+		GNOME_PARAM_ENABLE_SOUND, &setvalue);
+	g_value_unset (&setvalue);
+	return TRUE;
+}
+
+static gboolean
+libgnome_goption_enable_sound (const gchar *option_name,
+			const gchar *value,
+			gpointer data,
+			GError **error)
+{
+	GValue setvalue = { 0 };
+	g_value_init (&setvalue, G_TYPE_BOOLEAN);
+	g_value_set_boolean (&setvalue, TRUE);
+	
+	g_object_set_property (G_OBJECT (gnome_program_get()),
+		GNOME_PARAM_ENABLE_SOUND, &setvalue);
+	
+	g_value_unset (&setvalue);
+	return TRUE;
+}
+
+static void 
+libgnome_goption_version (void)
+{
+	GnomeProgram *program;
+
+	program = gnome_program_get ();
+
+	g_print ("Gnome %s %s\n",
+		gnome_program_get_app_id (program),
+		gnome_program_get_app_version (program));
+	
+	exit(0);
+}
+
 static int
 safe_mkdir (const char *pathname, mode_t mode)
 {
@@ -423,6 +488,24 @@
 	  NULL, 0 , NULL, NULL}
 };
 
+static GOptionEntry gnomelib_goptions [] = {
+	{ "disable-sound", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,                                 
+	  libgnome_goption_disable_sound, N_("Disable sound server usage"), NULL},     
+
+	{ "enable-sound", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,                                  
+	  libgnome_goption_enable_sound, N_("Enable sound server usage"), NULL},       
+
+	{ "espeaker", '\0',0, G_OPTION_ARG_CALLBACK,                                    
+	  libgnome_goption_epeaker, N_("Host:port on which the sound server to use is"
+				 " running"),
+	  N_("HOSTNAME:PORT")},                                                 
+
+	{"version", '\0', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
+	 (GOptionArgFunc) libgnome_goption_version, VERSION, NULL},
+	
+	{ NULL }
+};
+
 #ifndef G_OS_WIN32
 
 static void
@@ -467,6 +550,12 @@
 		NULL, NULL, NULL, NULL
 	};
 	int i = 0;
+	
+	GOptionGroup * gnomelib_group;
+	gnomelib_group = g_option_group_new("libgnome",_("GNOME Library"),_("Show Gnome Library Options"), NULL, NULL);
+	g_option_group_add_entries(gnomelib_group, gnomelib_goptions);
+	g_option_group_set_translation_domain (gnomelib_group, GETTEXT_PACKAGE);
+	module_info.expansion1 = (gpointer) gnomelib_group;
 
 	if (module_info.requirements == NULL) {
 		static GnomeModuleRequirement req[4];
Index: libgnome/gnome-program.c
===================================================================
RCS file: /cvs/gnome/libgnome/libgnome/gnome-program.c,v
retrieving revision 1.77
diff -u -r1.77 gnome-program.c
--- libgnome/gnome-program.c	9 Jun 2005 08:57:30 -0000	1.77
+++ libgnome/gnome-program.c	20 Jun 2005 20:16:46 -0000
@@ -75,6 +75,9 @@
     /* Construction properties */
     int prop_popt_flags;
     struct poptOptions *prop_popt_table;
+    GOptionEntry *prop_goption_table;
+    gboolean prop_goption_enable;
+    gchar *prop_goption_name;
     gchar *prop_human_readable_name;
     gchar *prop_gnome_prefix;
     gchar *prop_gnome_libdir;
@@ -98,6 +101,7 @@
 
     /* valid-while: state == APP_PREINIT_DONE */
     poptContext arg_context;
+    GOptionContext *goption_context;
 
     /* valid-while: state == APP_PREINIT_DONE */
     GArray *top_options_table;
@@ -124,6 +128,10 @@
     PROP_POPT_TABLE,
     PROP_POPT_FLAGS,
     PROP_POPT_CONTEXT,
+    PROP_GOPTION_TABLE,
+    PROP_GOPTION_CONTEXT,
+    PROP_GOPTION_ENABLE,
+    PROP_GOPTION_NAME,
     PROP_LAST
 };
 
@@ -157,6 +165,15 @@
     program = GNOME_PROGRAM (object);
 
     switch (param_id) {
+    case PROP_GOPTION_ENABLE:
+	program->_priv->prop_goption_enable = g_value_get_boolean (value);
+	break;
+    case PROP_GOPTION_TABLE:
+	program->_priv->prop_goption_table = g_value_peek_pointer (value);
+	break;
+    case PROP_GOPTION_NAME:
+	program->_priv->prop_goption_name = g_value_dup_string (value);
+	break;
     case PROP_POPT_TABLE:
 	program->_priv->prop_popt_table = g_value_peek_pointer (value);
 	break;
@@ -256,6 +273,18 @@
     case PROP_POPT_CONTEXT:
 	g_value_set_pointer (value, program->_priv->arg_context);
 	break;
+    case PROP_GOPTION_CONTEXT:
+	g_value_set_pointer (value, program->_priv->goption_context);
+	break;
+    case PROP_GOPTION_NAME:
+	g_value_set_string (value, program->_priv->prop_goption_name);
+	break;
+    case PROP_GOPTION_TABLE:
+	g_value_set_pointer (value, program->_priv->prop_goption_table);
+	break;
+    case PROP_GOPTION_ENABLE:
+	g_value_set_boolean (value, program->_priv->prop_goption_enable);
+	break;
     case PROP_GNOME_PATH:
 	if (program->_priv->gnome_path)
 	    g_value_take_string (value, g_strjoinv (":", program->_priv->gnome_path));
@@ -458,6 +487,44 @@
 
     g_object_class_install_property
 	(object_class,
+	 PROP_GOPTION_TABLE,
+	 g_param_spec_pointer (GNOME_PARAM_GOPTION_TABLE,
+			       _("GOption Table"), 
+			       _("The table of options for goption"),
+			      (G_PARAM_READABLE | G_PARAM_WRITABLE |
+			       G_PARAM_CONSTRUCT_ONLY)));
+ 
+    g_object_class_install_property
+	(object_class,
+	 PROP_GOPTION_NAME,
+	 g_param_spec_string (GNOME_PARAM_GOPTION_NAME,
+			       _("GOption Name"), 
+			       _("The string displayed after programname [OPTION..]"),
+			       NULL,
+			      (G_PARAM_READABLE | G_PARAM_WRITABLE |
+			       G_PARAM_CONSTRUCT_ONLY)));
+
+    g_object_class_install_property
+	(object_class,
+	 PROP_GOPTION_ENABLE,
+	 g_param_spec_boolean (GNOME_PARAM_GOPTION_ENABLE,
+			       _("Enable GOption"), 
+			       _("To turn on goption parsing"),
+			       FALSE,
+			      (G_PARAM_READABLE | G_PARAM_WRITABLE |
+			       G_PARAM_CONSTRUCT_ONLY)));
+
+    g_object_class_install_property
+	(object_class,
+	 PROP_GOPTION_CONTEXT,
+	 g_param_spec_pointer (GNOME_PARAM_GOPTION_CONTEXT,
+			      _("Goption Context"), 
+			      _("The goption context pointer that GnomeProgram "
+				"is using"),
+			       (G_PARAM_READABLE)));
+
+    g_object_class_install_property
+	(object_class,
 	 PROP_HUMAN_READABLE_NAME,
 	 g_param_spec_string (GNOME_PARAM_HUMAN_READABLE_NAME,
 			      _("Human readable name"), 
@@ -613,7 +680,7 @@
     program->_priv->state = APP_CREATE_DONE;
 
     program->_priv->prop_enable_sound = TRUE;
-    
+
     for (i = 0; i < program_modules->len; i++) {
 	GnomeModuleInfo *a_module = g_ptr_array_index (program_modules, i);
 
@@ -640,6 +707,7 @@
 
 	/* no free */
 	self->_priv->prop_popt_table = NULL;
+	self->_priv->prop_goption_table = NULL;
 
 	g_free (self->_priv->prop_human_readable_name);
 	self->_priv->prop_human_readable_name = NULL;
@@ -662,6 +730,9 @@
 	g_free (self->_priv->prop_espeaker);
 	self->_priv->prop_espeaker = NULL;
 
+	g_free (self->_priv->prop_goption_name);
+	self->_priv->prop_goption_name = NULL;
+	
 	g_strfreev (self->_priv->gnome_path);
 	self->_priv->gnome_path = NULL;
 
@@ -679,6 +750,12 @@
 	}
 	self->_priv->arg_context = NULL;
 
+	if (self->_priv->goption_context != NULL) {
+		g_option_context_free(self->_priv->goption_context);
+		g_dataset_destroy (self->_priv->goption_context);
+	}
+	self->_priv->goption_context = NULL;
+
 	if (self->_priv->top_options_table != NULL)
 		g_array_free (self->_priv->top_options_table, TRUE);
 	self->_priv->top_options_table = NULL;
@@ -1275,9 +1352,9 @@
 		       int argc, char **argv)
 {
     GnomeModuleInfo *a_module;
-    poptContext argctx;
+    poptContext argctx=NULL;
     int i;
-
+    
     g_return_val_if_fail (program != NULL, NULL);
     g_return_val_if_fail (GNOME_IS_PROGRAM (program), NULL);
     g_return_val_if_fail (argv != NULL, NULL);
@@ -1340,8 +1417,31 @@
 	}
     }
 
-    /* 5. Create a top-level 'struct poptOption *' for use in arg-parsing. */
-    {
+    /* 5. Create a top-level 'struct poptOption *'/' for use in arg-parsing or GOptionContext
+     * with all the GOptionGroups*/
+    if (program->_priv->prop_goption_enable) {
+
+	program->_priv->goption_context = 
+		g_option_context_new (program->_priv->prop_goption_name);    
+	
+	if (program->_priv->prop_goption_table) {
+		g_option_context_add_main_entries (
+			program->_priv->goption_context,
+			program->_priv->prop_goption_table,
+			GETTEXT_PACKAGE);
+	}
+
+	for (i = 0; (a_module = g_ptr_array_index(program_modules, i)); i++) {
+		if (a_module->expansion1) {
+			g_option_context_add_group (
+					program->_priv->goption_context,
+					(GOptionGroup*) a_module->expansion1);
+
+		}
+	}
+
+    } else {
+
 	struct poptOption includer = {NULL, '\0', POPT_ARG_INCLUDE_TABLE,
 				      NULL, 0, NULL, NULL};
 	struct poptOption callback =
@@ -1386,16 +1486,15 @@
 	includer.descrip = _("Dynamic modules to load");
 	includer.argDescrip = _("MODULE1,MODULE2,...");
 	g_array_append_val (program->_priv->top_options_table, includer);
-    }
 
-    argctx = program->_priv->arg_context = poptGetContext
-	(program->_priv->app_id, argc, (const char **) argv,
-	 (struct poptOption *) program->_priv->top_options_table->data,
-	 program->_priv->prop_popt_flags);
-  
+    	argctx = program->_priv->arg_context = poptGetContext
+		(program->_priv->app_id, argc, (const char **) argv,
+		 (struct poptOption *) program->_priv->top_options_table->data,
+		 program->_priv->prop_popt_flags);
+    }
     /* 7. Cleanup/return */
     program->_priv->state = APP_PREINIT_DONE;
-
+    
     return argctx;
 }
 
@@ -1449,30 +1548,43 @@
 void
 gnome_program_parse_args (GnomeProgram *program)
 {
-    int nextopt;
-    poptContext ctx;
-
-    g_return_if_fail (program != NULL);
-    g_return_if_fail (GNOME_IS_PROGRAM (program));
+	g_return_if_fail (program != NULL);
+	g_return_if_fail (GNOME_IS_PROGRAM (program));
 
-    if (program->_priv->state != APP_PREINIT_DONE)
-	return;
+	if (program->_priv->state != APP_PREINIT_DONE)
+		return;
 
-    /* translate popt output by default */
+	if (program->_priv->prop_goption_enable) {
+		GError *goption_error=NULL;	
+		GOptionContext *gctx = program->_priv->goption_context;
+		gint argc = program->_priv->argc;
+		gchar **argv = program->_priv->argv;
+		if (!g_option_context_parse(gctx,&argc,&argv,&goption_error)) {
+			g_print("%s\nRun '%s --help' to see a full list of available command line options.\n", 
+					goption_error->message,
+					program->_priv->argv[0]);
+			exit (1);
+		}
+	} else {
+		/* translate popt output by default */
+		int nextopt;
+		poptContext ctx;
 #ifdef ENABLE_NLS
-    setlocale (LC_ALL, "");
+		setlocale (LC_ALL, "");
 #endif
-    ctx = program->_priv->arg_context;
-    while ((nextopt = poptGetNextOpt (ctx)) > 0 || nextopt == POPT_ERROR_BADOPT)
-	/* do nothing */ ;
-
-    if (nextopt != -1) {
-	g_print ("Error on option %s: %s.\nRun '%s --help' to see a full list of available command line options.\n",
-		 poptBadOption (ctx, 0),
-		 poptStrerror (nextopt),
-		 program->_priv->argv[0]);
-	exit (1);
-    }
+		ctx = program->_priv->arg_context;
+		while ((nextopt = poptGetNextOpt (ctx)) > 0 || nextopt == POPT_ERROR_BADOPT)
+			/* do nothing */ ;
+
+		if (nextopt != -1) {
+			g_print ("Error on option %s: %s.\nRun '%s --help' to see a full list of available command line options.\n",
+			poptBadOption (ctx, 0),
+			poptStrerror (nextopt),
+			program->_priv->argv[0]);
+			exit (1);
+		}
+	
+	}
 }
 
 static char *
@@ -1938,7 +2050,7 @@
                            int argc, char **argv,
                            guint nparams, GParameter *params)
 {
-    va_list args;
+    va_list args=NULL;
 
     g_return_val_if_fail (nparams >= 0, NULL);
 
Index: libgnome/gnome-program.h
===================================================================
RCS file: /cvs/gnome/libgnome/libgnome/gnome-program.h,v
retrieving revision 1.29
diff -u -r1.29 gnome-program.h
--- libgnome/gnome-program.h	19 Jul 2004 09:49:59 -0000	1.29
+++ libgnome/gnome-program.h	20 Jun 2005 20:16:46 -0000
@@ -32,6 +32,7 @@
 #define GNOME_PROGRAM_H
 
 #include <glib.h>
+#include <glib/goption.h>
 #include <popt.h>
 #include <stdarg.h>
 #include <errno.h>
@@ -113,6 +114,10 @@
 #define GNOME_PARAM_POPT_TABLE          "popt-table"
 #define GNOME_PARAM_POPT_FLAGS          "popt-flags"
 #define GNOME_PARAM_POPT_CONTEXT        "popt-context"
+#define GNOME_PARAM_GOPTION_TABLE       "goption-table"
+#define GNOME_PARAM_GOPTION_ENABLE      "goption-enable"
+#define GNOME_PARAM_GOPTION_CONTEXT     "goption-context"
+#define GNOME_PARAM_GOPTION_NAME	"goption-name"
 #define GNOME_PARAM_CREATE_DIRECTORIES  "create-directories"
 #define GNOME_PARAM_ENABLE_SOUND        "enable-sound"
 #define GNOME_PARAM_ESPEAKER            "espeaker"


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]