Handle conflicts between options in different groups. (#156808)
authorMatthias Clasen <mclasen@redhat.com>
Mon, 1 Nov 2004 17:40:09 +0000 (17:40 +0000)
committerMatthias Clasen <matthiasc@src.gnome.org>
Mon, 1 Nov 2004 17:40:09 +0000 (17:40 +0000)
2004-11-01  Matthias Clasen  <mclasen@redhat.com>

Handle conflicts between options in different groups. (#156808)

* glib/goption.c (g_option_context_parse): When a long option does not
match exactly, try to parse it as --group-option.
(g_option_context_add_group): Warn if a group name conflict occurs.

* glib/goption.c (print_help): Print out the effective options, ie
don't print shadowed short options, and for long options print
--group-option instead of --option if appropriate.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-12
ChangeLog.pre-2-6
ChangeLog.pre-2-8
glib/goption.c

index dd8cbbf..81b1464 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2004-11-01  Matthias Clasen  <mclasen@redhat.com>
+
+       Handle conflicts between options in different groups. (#156808)
+       
+       * glib/goption.c (g_option_context_parse): When a long option does not
+       match exactly, try to parse it as --group-option.
+       (g_option_context_add_group): Warn if a group name conflict occurs.
+
+       * glib/goption.c (print_help): Print out the effective options, ie 
+       don't print shadowed short options, and for long options print
+       --group-option instead of --option if appropriate.
+
 2004-10-31  Matthias Clasen  <mclasen@redhat.com>
 
        * glib/gwin32.c: Add bits of markup to g_win32_get_windows_version()
index dd8cbbf..81b1464 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-01  Matthias Clasen  <mclasen@redhat.com>
+
+       Handle conflicts between options in different groups. (#156808)
+       
+       * glib/goption.c (g_option_context_parse): When a long option does not
+       match exactly, try to parse it as --group-option.
+       (g_option_context_add_group): Warn if a group name conflict occurs.
+
+       * glib/goption.c (print_help): Print out the effective options, ie 
+       don't print shadowed short options, and for long options print
+       --group-option instead of --option if appropriate.
+
 2004-10-31  Matthias Clasen  <mclasen@redhat.com>
 
        * glib/gwin32.c: Add bits of markup to g_win32_get_windows_version()
index dd8cbbf..81b1464 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-01  Matthias Clasen  <mclasen@redhat.com>
+
+       Handle conflicts between options in different groups. (#156808)
+       
+       * glib/goption.c (g_option_context_parse): When a long option does not
+       match exactly, try to parse it as --group-option.
+       (g_option_context_add_group): Warn if a group name conflict occurs.
+
+       * glib/goption.c (print_help): Print out the effective options, ie 
+       don't print shadowed short options, and for long options print
+       --group-option instead of --option if appropriate.
+
 2004-10-31  Matthias Clasen  <mclasen@redhat.com>
 
        * glib/gwin32.c: Add bits of markup to g_win32_get_windows_version()
index dd8cbbf..81b1464 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-01  Matthias Clasen  <mclasen@redhat.com>
+
+       Handle conflicts between options in different groups. (#156808)
+       
+       * glib/goption.c (g_option_context_parse): When a long option does not
+       match exactly, try to parse it as --group-option.
+       (g_option_context_add_group): Warn if a group name conflict occurs.
+
+       * glib/goption.c (print_help): Print out the effective options, ie 
+       don't print shadowed short options, and for long options print
+       --group-option instead of --option if appropriate.
+
 2004-10-31  Matthias Clasen  <mclasen@redhat.com>
 
        * glib/gwin32.c: Add bits of markup to g_win32_get_windows_version()
index dd8cbbf..81b1464 100644 (file)
@@ -1,3 +1,15 @@
+2004-11-01  Matthias Clasen  <mclasen@redhat.com>
+
+       Handle conflicts between options in different groups. (#156808)
+       
+       * glib/goption.c (g_option_context_parse): When a long option does not
+       match exactly, try to parse it as --group-option.
+       (g_option_context_add_group): Warn if a group name conflict occurs.
+
+       * glib/goption.c (print_help): Print out the effective options, ie 
+       don't print shadowed short options, and for long options print
+       --group-option instead of --option if appropriate.
+
 2004-10-31  Matthias Clasen  <mclasen@redhat.com>
 
        * glib/gwin32.c: Add bits of markup to g_win32_get_windows_version()
index b40afb2..99ad65c 100644 (file)
@@ -271,13 +271,25 @@ void
 g_option_context_add_group (GOptionContext *context,
                            GOptionGroup   *group)
 {
+  GList *list;
+
   g_return_if_fail (context != NULL);
   g_return_if_fail (group != NULL);
   g_return_if_fail (group->name != NULL);
   g_return_if_fail (group->description != NULL);
   g_return_if_fail (group->help_description != NULL);
 
-  context->groups = g_list_prepend (context->groups, group);
+  for (list = context->groups; list; list = list->next)
+    {
+      GOptionGroup *g = (GOptionGroup *)list->data;
+
+      if ((group->name == NULL && g->name == NULL) ||
+         (group->name && g->name && strcmp (group->name, g->name) == 0))
+       g_warning ("A group named \"%s\" is already part of this GOptionContext", 
+                  group->name);
+    }
+
+  context->groups = g_list_append (context->groups, group);
 }
 
 /**
@@ -358,7 +370,7 @@ print_entry (GOptionGroup       *group,
 
   if (entry->flags & G_OPTION_FLAG_HIDDEN)
     return;
-         
+
   str = g_string_new (NULL);
   
   if (entry->short_name)
@@ -382,11 +394,52 @@ print_help (GOptionContext *context,
   GList *list;
   gint max_length, len;
   gint i;
+  GHashTable *shadow_map;
+  gboolean seen[256];
   
   g_print ("%s\n  %s %s %s\n\n", 
           _("Usage:"), g_get_prgname(), _("[OPTION...]"),
           context->parameter_string ? context->parameter_string : "");
 
+  memset (seen, 0, sizeof (gboolean) * 256);
+  shadow_map = g_hash_table_new (g_str_hash, g_str_equal);
+
+  if (context->main_group)
+    {
+      for (i = 0; i < context->main_group->n_entries; i++)
+       {
+         g_hash_table_insert (shadow_map, 
+                              (gpointer)context->main_group->entries[i].long_name, 
+                              context->main_group->entries + i);
+         
+         if (seen[(guchar)context->main_group->entries[i].short_name])
+           context->main_group->entries[i].short_name = 0;
+         else
+           seen[(guchar)context->main_group->entries[i].short_name] = TRUE;
+       }
+    }
+
+  list = context->groups;
+  while (list != NULL)
+    {
+      GOptionGroup *group = list->data;
+      for (i = 0; i < group->n_entries; i++)
+       {
+         if (g_hash_table_lookup (shadow_map, group->entries[i].long_name))
+           group->entries[i].long_name = g_strdup_printf ("%s-%s", group->name, group->entries[i].long_name);
+         else  
+           g_hash_table_insert (shadow_map, (gpointer)group->entries[i].long_name, group->entries + i);
+
+         if (seen[(guchar)group->entries[i].short_name])
+           group->entries[i].short_name = 0;
+         else
+           seen[(guchar)group->entries[i].short_name] = TRUE;
+       }
+      list = list->next;
+    }
+
+  g_hash_table_destroy (shadow_map);
+
   list = context->groups;
 
   max_length = g_utf8_strlen ("--help, -?", -1);
@@ -504,7 +557,6 @@ print_help (GOptionContext *context,
 
       g_print ("\n");
     }
-
   
   exit (0);
 }
@@ -1061,7 +1113,7 @@ g_option_context_parse (GOptionContext   *context,
 
       for (i = 1; i < *argc; i++)
        {
-         gchar *arg;
+         gchar *arg, *dash;
          gboolean parsed = FALSE;
 
          if ((*argv)[i][0] == '-' && !stop_parsing)
@@ -1128,12 +1180,41 @@ g_option_context_parse (GOptionContext   *context,
                      
                      list = list->next;
                    }
+                 
+                 if (parsed)
+                   continue;
 
+                 /* Now look for --<group>-<option> */
+                 dash = strchr (arg, '-');
+                 if (dash)
+                   {
+                     /* Try the groups */
+                     list = context->groups;
+                     while (list)
+                       {
+                         GOptionGroup *group = list->data;
+                         
+                         if (strncmp (group->name, arg, dash - arg) == 0)
+                           {
+                             if (!parse_long_option (context, group, &i, dash + 1,
+                                                     argc, argv, error, &parsed))
+                               goto fail;
+                             
+                             if (parsed)
+                               break;
+                           }
+                         
+                         list = list->next;
+                       }
+                   }
+                 
                  if (context->ignore_unknown)
                    continue;
                }
              else
                {
+                 /* short option */
+
                  gint new_i, j;
                  gboolean *nulled_out = NULL;
                  
@@ -1346,6 +1427,7 @@ g_option_group_new (const gchar    *name,
   return group;
 }
 
+
 /**
  * g_option_group_free:
  * @group: a #GOptionGroup