#include "config.h"
-#include "galias.h"
-
#include "goption.h"
#include "glib.h"
#include "gi18n.h"
+#include "galias.h"
+
#include <string.h>
#include <stdlib.h>
#include <errno.h>
g_return_if_fail (context != NULL);
g_return_if_fail (group != NULL);
+ if (context->main_group)
+ {
+ g_warning ("This GOptionContext already has a main group");
+
+ return;
+ }
+
context->main_group = group;
}
g_option_group_set_translation_domain (context->main_group, translation_domain);
}
+static gint
+calculate_max_length (GOptionGroup *group)
+{
+ GOptionEntry *entry;
+ gint i, len, max_length;
+
+ max_length = 0;
+
+ for (i = 0; i < group->n_entries; i++)
+ {
+ entry = &group->entries[i];
+
+ if (entry->flags & G_OPTION_FLAG_HIDDEN)
+ continue;
+
+ len = g_utf8_strlen (entry->long_name, -1);
+
+ if (entry->short_name)
+ len += 4;
+
+ if (entry->arg != G_OPTION_ARG_NONE && entry->arg_description)
+ len += 1 + g_utf8_strlen (TRANSLATE (group, entry->arg_description), -1);
+
+ max_length = MAX (max_length, len);
+ }
+
+ return max_length;
+}
+
static void
print_entry (GOptionGroup *group,
gint max_length,
if (entry->flags & G_OPTION_FLAG_HIDDEN)
return;
+ if (entry->long_name[0] == 0)
+ return;
+
str = g_string_new (NULL);
if (entry->short_name)
static void
print_help (GOptionContext *context,
gboolean main_help,
- GOptionGroup *group)
+ GOptionGroup *group)
{
GList *list;
gint max_length, len;
gint i;
+ GOptionEntry *entry;
GHashTable *shadow_map;
gboolean seen[256];
{
for (i = 0; i < context->main_group->n_entries; i++)
{
+ entry = &context->main_group->entries[i];
g_hash_table_insert (shadow_map,
- (gpointer)context->main_group->entries[i].long_name,
- context->main_group->entries + i);
+ (gpointer)entry->long_name,
+ entry);
- if (seen[(guchar)context->main_group->entries[i].short_name])
- context->main_group->entries[i].short_name = 0;
+ if (seen[(guchar)entry->short_name])
+ entry->short_name = 0;
else
- seen[(guchar)context->main_group->entries[i].short_name] = TRUE;
+ seen[(guchar)entry->short_name] = TRUE;
}
}
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);
+ entry = &group->entries[i];
+ if (g_hash_table_lookup (shadow_map, entry->long_name))
+ entry->long_name = g_strdup_printf ("%s-%s", group->name, entry->long_name);
else
- g_hash_table_insert (shadow_map, (gpointer)group->entries[i].long_name, group->entries + i);
+ g_hash_table_insert (shadow_map, (gpointer)entry->long_name, entry);
- if (seen[(guchar)group->entries[i].short_name])
- group->entries[i].short_name = 0;
+ if (seen[(guchar)entry->short_name])
+ entry->short_name = 0;
else
- seen[(guchar)group->entries[i].short_name] = TRUE;
+ seen[(guchar)entry->short_name] = TRUE;
}
list = list->next;
}
list = context->groups;
- max_length = g_utf8_strlen ("--help, -?", -1);
+ max_length = g_utf8_strlen ("-?, --help", -1);
if (list)
{
max_length = MAX (max_length, len);
}
+ if (context->main_group)
+ {
+ len = calculate_max_length (context->main_group);
+ max_length = MAX (max_length, len);
+ }
+
while (list != NULL)
{
GOptionGroup *group = list->data;
max_length = MAX (max_length, len);
/* Then we go through the entries */
- for (i = 0; i < group->n_entries; i++)
- {
- if (group->entries[i].flags & G_OPTION_FLAG_HIDDEN)
- continue;
-
- len = g_utf8_strlen (group->entries[i].long_name, -1);
-
- if (group->entries[i].short_name)
- len += 4;
-
- if (group->entries[i].arg != G_OPTION_ARG_NONE &&
- group->entries[i].arg_description)
- len += 1 + g_utf8_strlen (TRANSLATE (group, group->entries[i].arg_description), -1);
-
- max_length = MAX (max_length, len);
- }
+ len = calculate_max_length (group);
+ max_length = MAX (max_length, len);
list = list->next;
}
{
list = context->groups;
- g_print ("%s\n --%-*s %s\n",
- _("Help Options:"), max_length, "help", _("Show help options"));
+ g_print ("%s\n -%c, --%-*s %s\n",
+ _("Help Options:"), '?', max_length - 4, "help",
+ _("Show help options"));
/* We only want --help-all when there are groups */
if (list)
- g_print (" --%-*s %s\n", max_length, "help-all", _("Show all help options"));
-
+ g_print (" --%-*s %s\n", max_length, "help-all",
+ _("Show all help options"));
+
while (list)
{
GOptionGroup *group = list->data;
- g_print (" --help-%-*s %s\n", max_length - 5, group->name, TRANSLATE (group, group->help_description));
+ g_print (" --help-%-*s %s\n", max_length - 5, group->name,
+ TRANSLATE (group, group->help_description));
list = list->next;
}
if (context->main_group)
for (i = 0; i < context->main_group->n_entries; i++)
- print_entry (context->main_group, max_length, &context->main_group->entries[i]);
+ print_entry (context->main_group, max_length,
+ &context->main_group->entries[i]);
while (list != NULL)
{
{
g_set_error (error,
G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
- _("Cannot parse integer value '%s' for --%s"),
+ _("Cannot parse integer value '%s' for %s"),
arg, arg_name);
return FALSE;
}
*
* If the parsing is successful, any parsed arguments are
* removed from the array and @argc and @argv are updated
- * accordingly. In case of an error, @argc and @argv are
- * left unmodified.
+ * accordingly. A '--' option is stripped from @argv
+ * unless there are unparsed options before and after it,
+ * or some of the options after it start with '-'. In case
+ * of an error, @argc and @argv are left unmodified.
*
* If automatic <option>--help</option> support is enabled
* (see g_option_context_set_help_enabled()), and the
if (argc && argv)
{
gboolean stop_parsing = FALSE;
+ gboolean has_unknown = FALSE;
+ gint separator_pos = 0;
for (i = 1; i < *argc; i++)
{
/* '--' terminates list of arguments */
if (*arg == 0)
{
- add_pending_null (context, &((*argv)[i]), NULL);
+ separator_pos = i;
stop_parsing = TRUE;
continue;
}
for (j = 0; j < strlen (arg); j++)
{
+ if (context->help_enabled && arg[j] == '?')
+ print_help (context, TRUE, NULL);
+
parsed = FALSE;
if (context->main_group &&
if (!nulled_out[j])
{
if (!new_arg)
- new_arg = g_malloc (strlen (arg));
+ new_arg = g_malloc (strlen (arg) + 1);
new_arg[arg_index++] = arg[j];
}
}
}
}
+ if (!parsed)
+ has_unknown = TRUE;
+
if (!parsed && !context->ignore_unknown)
{
g_set_error (error,
G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION,
- _("Unknown option %s"), (*argv)[i]);
+ _("Unknown option %s"), (*argv)[i]);
goto fail;
}
}
argc, argv, error, &parsed))
goto fail;
+ if (!parsed && (has_unknown || (*argv)[i][0] == '-'))
+ separator_pos = 0;
}
}
+
+ if (separator_pos > 0)
+ add_pending_null (context, &((*argv)[separator_pos]), NULL);
+
}
/* Call post-parse hooks */
g_free);
}
+#define __G_OPTION_C__
+#include "galiasdef.c"