1 /* goption.c - Option parser
3 * Copyright (C) 1999, 2003 Red Hat Software
4 * Copyright (C) 2004 Anders Carlsson <andersca@gnome.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this library; if not, see <http://www.gnu.org/licenses/>.
22 * @Short_description: parses commandline options
23 * @Title: Commandline option parser
25 * The GOption commandline parser is intended to be a simpler replacement
26 * for the popt library. It supports short and long commandline options,
27 * as shown in the following example:
29 * `testtreemodel -r 1 --max-size 20 --rand --display=:1.0 -vb -- file1 file2`
31 * The example demonstrates a number of features of the GOption
34 * - Options can be single letters, prefixed by a single dash.
36 * - Multiple short options can be grouped behind a single dash.
38 * - Long options are prefixed by two consecutive dashes.
40 * - Options can have an extra argument, which can be a number, a string or
41 * a filename. For long options, the extra argument can be appended with
42 * an equals sign after the option name, which is useful if the extra
43 * argument starts with a dash, which would otherwise cause it to be
44 * interpreted as another option.
46 * - Non-option arguments are returned to the application as rest arguments.
48 * - An argument consisting solely of two dashes turns off further parsing,
49 * any remaining arguments (even those starting with a dash) are returned
50 * to the application as rest arguments.
52 * Another important feature of GOption is that it can automatically
53 * generate nicely formatted help output. Unless it is explicitly turned
54 * off with g_option_context_set_help_enabled(), GOption will recognize
55 * the `--help`, `-?`, `--help-all` and `--help-groupname` options
56 * (where `groupname` is the name of a #GOptionGroup) and write a text
57 * similar to the one shown in the following example to stdout.
61 * testtreemodel [OPTION...] - test tree model performance
64 * -h, --help Show help options
65 * --help-all Show all help options
66 * --help-gtk Show GTK+ Options
68 * Application Options:
69 * -r, --repeats=N Average over N repetitions
70 * -m, --max-size=M Test up to 2^M items
71 * --display=DISPLAY X display to use
72 * -v, --verbose Be verbose
73 * -b, --beep Beep when done
74 * --rand Randomize the data
77 * GOption groups options in #GOptionGroups, which makes it easy to
78 * incorporate options from multiple sources. The intended use for this is
79 * to let applications collect option groups from the libraries it uses,
80 * add them to their #GOptionContext, and parse all options by a single call
81 * to g_option_context_parse(). See gtk_get_option_group() for an example.
83 * If an option is declared to be of type string or filename, GOption takes
84 * care of converting it to the right encoding; strings are returned in
85 * UTF-8, filenames are returned in the GLib filename encoding. Note that
86 * this only works if setlocale() has been called before
87 * g_option_context_parse().
89 * Here is a complete example of setting up GOption to parse the example
90 * commandline above and produce the example help output.
91 * |[<!-- language="C" -->
92 * static gint repeats = 2;
93 * static gint max_size = 8;
94 * static gboolean verbose = FALSE;
95 * static gboolean beep = FALSE;
96 * static gboolean randomize = FALSE;
98 * static GOptionEntry entries[] =
100 * { "repeats", 'r', 0, G_OPTION_ARG_INT, &repeats, "Average over N repetitions", "N" },
101 * { "max-size", 'm', 0, G_OPTION_ARG_INT, &max_size, "Test up to 2^M items", "M" },
102 * { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL },
103 * { "beep", 'b', 0, G_OPTION_ARG_NONE, &beep, "Beep when done", NULL },
104 * { "rand", 0, 0, G_OPTION_ARG_NONE, &randomize, "Randomize the data", NULL },
109 * main (int argc, char *argv[])
111 * GError *error = NULL;
112 * GOptionContext *context;
114 * context = g_option_context_new ("- test tree model performance");
115 * g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
116 * g_option_context_add_group (context, gtk_get_option_group (TRUE));
117 * if (!g_option_context_parse (context, &argc, &argv, &error))
119 * g_print ("option parsing failed: %s\n", error->message);
128 * On UNIX systems, the argv that is passed to main() has no particular
129 * encoding, even to the extent that different parts of it may have
130 * different encodings. In general, normal arguments and flags will be
131 * in the current locale and filenames should be considered to be opaque
132 * byte strings. Proper use of %G_OPTION_ARG_FILENAME vs
133 * %G_OPTION_ARG_STRING is therefore important.
135 * Note that on Windows, filenames do have an encoding, but using
136 * #GOptionContext with the argv as passed to main() will result in a
137 * program that can only accept commandline arguments with characters
138 * from the system codepage. This can cause problems when attempting to
139 * deal with filenames containing Unicode characters that fall outside
142 * A solution to this is to use g_win32_get_command_line() and
143 * g_option_context_parse_strv() which will properly handle full Unicode
144 * filenames. If you are using #GApplication, this is done
145 * automatically for you.
147 * The following example shows how you can use #GOptionContext directly
148 * in order to correctly deal with Unicode filenames on Windows:
150 * |[<!-- language="C" -->
152 * main (int argc, char **argv)
154 * GError *error = NULL;
155 * GOptionContext *context;
159 * args = g_win32_get_command_line ();
161 * args = g_strdupv (argv);
166 * if (!g_option_context_parse_strv (context, &args, &error))
187 #if defined __OpenBSD__
189 #include <sys/sysctl.h>
195 #include "glibintl.h"
197 #define TRANSLATE(group, str) (((group)->translate_func ? (* (group)->translate_func) ((str), (group)->translate_data) : (str)))
199 #define NO_ARG(entry) ((entry)->arg == G_OPTION_ARG_NONE || \
200 ((entry)->arg == G_OPTION_ARG_CALLBACK && \
201 ((entry)->flags & G_OPTION_FLAG_NO_ARG)))
203 #define OPTIONAL_ARG(entry) ((entry)->arg == G_OPTION_ARG_CALLBACK && \
204 (entry)->flags & G_OPTION_FLAG_OPTIONAL_ARG)
236 struct _GOptionContext
240 gchar
*parameter_string
;
244 GTranslateFunc translate_func
;
245 GDestroyNotify translate_notify
;
246 gpointer translate_data
;
248 guint help_enabled
: 1;
249 guint ignore_unknown
: 1;
251 guint strict_posix
: 1;
253 GOptionGroup
*main_group
;
255 /* We keep a list of change so we can revert them */
258 /* We also keep track of all argv elements
259 * that should be NULLed or modified.
261 GList
*pending_nulls
;
268 gchar
*help_description
;
272 GDestroyNotify destroy_notify
;
275 GTranslateFunc translate_func
;
276 GDestroyNotify translate_notify
;
277 gpointer translate_data
;
279 GOptionEntry
*entries
;
282 GOptionParseFunc pre_parse_func
;
283 GOptionParseFunc post_parse_func
;
284 GOptionErrorFunc error_func
;
287 static void free_changes_list (GOptionContext
*context
,
289 static void free_pending_nulls (GOptionContext
*context
,
290 gboolean perform_nulls
);
294 _g_unichar_get_width (gunichar c
)
296 if (G_UNLIKELY (g_unichar_iszerowidth (c
)))
299 /* we ignore the fact that we should call g_unichar_iswide_cjk() under
300 * some locales (legacy East Asian ones) */
301 if (g_unichar_iswide (c
))
308 _g_utf8_strwidth (const gchar
*p
)
311 g_return_val_if_fail (p
!= NULL
, 0);
315 len
+= _g_unichar_get_width (g_utf8_get_char (p
));
316 p
= g_utf8_next_char (p
);
322 G_DEFINE_QUARK (g
-option
-context
-error
-quark
, g_option_error
)
325 * g_option_context_new:
326 * @parameter_string: (nullable): a string which is displayed in
327 * the first line of `--help` output, after the usage summary
328 * `programname [OPTION...]`
330 * Creates a new option context.
332 * The @parameter_string can serve multiple purposes. It can be used
333 * to add descriptions for "rest" arguments, which are not parsed by
334 * the #GOptionContext, typically something like "FILES" or
335 * "FILE1 FILE2...". If you are using #G_OPTION_REMAINING for
336 * collecting "rest" arguments, GLib handles this automatically by
337 * using the @arg_description of the corresponding #GOptionEntry in
340 * Another usage is to give a short summary of the program
341 * functionality, like " - frob the strings", which will be displayed
342 * in the same line as the usage. For a longer description of the
343 * program functionality that should be displayed as a paragraph
344 * below the usage line, use g_option_context_set_summary().
346 * Note that the @parameter_string is translated using the
347 * function set with g_option_context_set_translate_func(), so
348 * it should normally be passed untranslated.
350 * Returns: a newly created #GOptionContext, which must be
351 * freed with g_option_context_free() after use.
356 g_option_context_new (const gchar
*parameter_string
)
359 GOptionContext
*context
;
361 context
= g_new0 (GOptionContext
, 1);
363 context
->parameter_string
= g_strdup (parameter_string
);
364 context
->strict_posix
= FALSE
;
365 context
->help_enabled
= TRUE
;
366 context
->ignore_unknown
= FALSE
;
372 * g_option_context_free:
373 * @context: a #GOptionContext
375 * Frees context and all the groups which have been
378 * Please note that parsed arguments need to be freed separately (see
383 void g_option_context_free (GOptionContext
*context
)
385 g_return_if_fail (context
!= NULL
);
387 g_list_free_full (context
->groups
, (GDestroyNotify
) g_option_group_unref
);
389 if (context
->main_group
)
390 g_option_group_unref (context
->main_group
);
392 free_changes_list (context
, FALSE
);
393 free_pending_nulls (context
, FALSE
);
395 g_free (context
->parameter_string
);
396 g_free (context
->summary
);
397 g_free (context
->description
);
399 if (context
->translate_notify
)
400 (* context
->translate_notify
) (context
->translate_data
);
407 * g_option_context_set_help_enabled:
408 * @context: a #GOptionContext
409 * @help_enabled: %TRUE to enable `--help`, %FALSE to disable it
411 * Enables or disables automatic generation of `--help` output.
412 * By default, g_option_context_parse() recognizes `--help`, `-h`,
413 * `-?`, `--help-all` and `--help-groupname` and creates suitable
418 void g_option_context_set_help_enabled (GOptionContext
*context
,
419 gboolean help_enabled
)
422 g_return_if_fail (context
!= NULL
);
424 context
->help_enabled
= help_enabled
;
428 * g_option_context_get_help_enabled:
429 * @context: a #GOptionContext
431 * Returns whether automatic `--help` generation
432 * is turned on for @context. See g_option_context_set_help_enabled().
434 * Returns: %TRUE if automatic help generation is turned on.
439 g_option_context_get_help_enabled (GOptionContext
*context
)
441 g_return_val_if_fail (context
!= NULL
, FALSE
);
443 return context
->help_enabled
;
447 * g_option_context_set_ignore_unknown_options:
448 * @context: a #GOptionContext
449 * @ignore_unknown: %TRUE to ignore unknown options, %FALSE to produce
450 * an error when unknown options are met
452 * Sets whether to ignore unknown options or not. If an argument is
453 * ignored, it is left in the @argv array after parsing. By default,
454 * g_option_context_parse() treats unknown options as error.
456 * This setting does not affect non-option arguments (i.e. arguments
457 * which don't start with a dash). But note that GOption cannot reliably
458 * determine whether a non-option belongs to a preceding unknown option.
463 g_option_context_set_ignore_unknown_options (GOptionContext
*context
,
464 gboolean ignore_unknown
)
466 g_return_if_fail (context
!= NULL
);
468 context
->ignore_unknown
= ignore_unknown
;
472 * g_option_context_get_ignore_unknown_options:
473 * @context: a #GOptionContext
475 * Returns whether unknown options are ignored or not. See
476 * g_option_context_set_ignore_unknown_options().
478 * Returns: %TRUE if unknown options are ignored.
483 g_option_context_get_ignore_unknown_options (GOptionContext
*context
)
485 g_return_val_if_fail (context
!= NULL
, FALSE
);
487 return context
->ignore_unknown
;
491 * g_option_context_set_strict_posix:
492 * @context: a #GOptionContext
493 * @strict_posix: the new value
495 * Sets strict POSIX mode.
497 * By default, this mode is disabled.
499 * In strict POSIX mode, the first non-argument parameter encountered
500 * (eg: filename) terminates argument processing. Remaining arguments
501 * are treated as non-options and are not attempted to be parsed.
503 * If strict POSIX mode is disabled then parsing is done in the GNU way
504 * where option arguments can be freely mixed with non-options.
506 * As an example, consider "ls foo -l". With GNU style parsing, this
507 * will list "foo" in long mode. In strict POSIX style, this will list
508 * the files named "foo" and "-l".
510 * It may be useful to force strict POSIX mode when creating "verb
511 * style" command line tools. For example, the "gsettings" command line
512 * tool supports the global option "--schemadir" as well as many
513 * subcommands ("get", "set", etc.) which each have their own set of
514 * arguments. Using strict POSIX mode will allow parsing the global
515 * options up to the verb name while leaving the remaining options to be
516 * parsed by the relevant subcommand (which can be determined by
517 * examining the verb name, which should be present in argv[1] after
523 g_option_context_set_strict_posix (GOptionContext
*context
,
524 gboolean strict_posix
)
526 g_return_if_fail (context
!= NULL
);
528 context
->strict_posix
= strict_posix
;
532 * g_option_context_get_strict_posix:
533 * @context: a #GOptionContext
535 * Returns whether strict POSIX code is enabled.
537 * See g_option_context_set_strict_posix() for more information.
539 * Returns: %TRUE if strict POSIX is enabled, %FALSE otherwise.
544 g_option_context_get_strict_posix (GOptionContext
*context
)
546 g_return_val_if_fail (context
!= NULL
, FALSE
);
548 return context
->strict_posix
;
552 * g_option_context_add_group:
553 * @context: a #GOptionContext
554 * @group: (transfer full): the group to add
556 * Adds a #GOptionGroup to the @context, so that parsing with @context
557 * will recognize the options in the group. Note that this will take
558 * ownership of the @group and thus the @group should not be freed.
563 g_option_context_add_group (GOptionContext
*context
,
568 g_return_if_fail (context
!= NULL
);
569 g_return_if_fail (group
!= NULL
);
570 g_return_if_fail (group
->name
!= NULL
);
571 g_return_if_fail (group
->description
!= NULL
);
572 g_return_if_fail (group
->help_description
!= NULL
);
574 for (list
= context
->groups
; list
; list
= list
->next
)
576 GOptionGroup
*g
= (GOptionGroup
*)list
->data
;
578 if ((group
->name
== NULL
&& g
->name
== NULL
) ||
579 (group
->name
&& g
->name
&& strcmp (group
->name
, g
->name
) == 0))
580 g_warning ("A group named \"%s\" is already part of this GOptionContext",
584 context
->groups
= g_list_append (context
->groups
, group
);
588 * g_option_context_set_main_group:
589 * @context: a #GOptionContext
590 * @group: (transfer full): the group to set as main group
592 * Sets a #GOptionGroup as main group of the @context.
593 * This has the same effect as calling g_option_context_add_group(),
594 * the only difference is that the options in the main group are
595 * treated differently when generating `--help` output.
600 g_option_context_set_main_group (GOptionContext
*context
,
603 g_return_if_fail (context
!= NULL
);
604 g_return_if_fail (group
!= NULL
);
606 if (context
->main_group
)
608 g_warning ("This GOptionContext already has a main group");
613 context
->main_group
= group
;
617 * g_option_context_get_main_group:
618 * @context: a #GOptionContext
620 * Returns a pointer to the main group of @context.
622 * Returns: (transfer none): the main group of @context, or %NULL if
623 * @context doesn't have a main group. Note that group belongs to
624 * @context and should not be modified or freed.
629 g_option_context_get_main_group (GOptionContext
*context
)
631 g_return_val_if_fail (context
!= NULL
, NULL
);
633 return context
->main_group
;
637 * g_option_context_add_main_entries:
638 * @context: a #GOptionContext
639 * @entries: a %NULL-terminated array of #GOptionEntrys
640 * @translation_domain: (nullable): a translation domain to use for translating
641 * the `--help` output for the options in @entries
642 * with gettext(), or %NULL
644 * A convenience function which creates a main group if it doesn't
645 * exist, adds the @entries to it and sets the translation domain.
650 g_option_context_add_main_entries (GOptionContext
*context
,
651 const GOptionEntry
*entries
,
652 const gchar
*translation_domain
)
654 g_return_if_fail (entries
!= NULL
);
656 if (!context
->main_group
)
657 context
->main_group
= g_option_group_new (NULL
, NULL
, NULL
, NULL
, NULL
);
659 g_option_group_add_entries (context
->main_group
, entries
);
660 g_option_group_set_translation_domain (context
->main_group
, translation_domain
);
664 calculate_max_length (GOptionGroup
*group
,
668 gint i
, len
, max_length
;
669 const gchar
*long_name
;
673 for (i
= 0; i
< group
->n_entries
; i
++)
675 entry
= &group
->entries
[i
];
677 if (entry
->flags
& G_OPTION_FLAG_HIDDEN
)
680 long_name
= g_hash_table_lookup (aliases
, &entry
->long_name
);
682 long_name
= entry
->long_name
;
683 len
= _g_utf8_strwidth (long_name
);
685 if (entry
->short_name
)
688 if (!NO_ARG (entry
) && entry
->arg_description
)
689 len
+= 1 + _g_utf8_strwidth (TRANSLATE (group
, entry
->arg_description
));
691 max_length
= MAX (max_length
, len
);
698 print_entry (GOptionGroup
*group
,
700 const GOptionEntry
*entry
,
705 const gchar
*long_name
;
707 if (entry
->flags
& G_OPTION_FLAG_HIDDEN
)
710 if (entry
->long_name
[0] == 0)
713 long_name
= g_hash_table_lookup (aliases
, &entry
->long_name
);
715 long_name
= entry
->long_name
;
717 str
= g_string_new (NULL
);
719 if (entry
->short_name
)
720 g_string_append_printf (str
, " -%c, --%s", entry
->short_name
, long_name
);
722 g_string_append_printf (str
, " --%s", long_name
);
724 if (entry
->arg_description
)
725 g_string_append_printf (str
, "=%s", TRANSLATE (group
, entry
->arg_description
));
727 g_string_append_printf (string
, "%s%*s %s\n", str
->str
,
728 (int) (max_length
+ 4 - _g_utf8_strwidth (str
->str
)), "",
729 entry
->description
? TRANSLATE (group
, entry
->description
) : "");
730 g_string_free (str
, TRUE
);
734 group_has_visible_entries (GOptionContext
*context
,
736 gboolean main_entries
)
738 GOptionFlags reject_filter
= G_OPTION_FLAG_HIDDEN
;
741 gboolean main_group
= group
== context
->main_group
;
744 reject_filter
|= G_OPTION_FLAG_IN_MAIN
;
746 for (i
= 0, l
= (group
? group
->n_entries
: 0); i
< l
; i
++)
748 entry
= &group
->entries
[i
];
750 if (main_entries
&& !main_group
&& !(entry
->flags
& G_OPTION_FLAG_IN_MAIN
))
752 if (entry
->long_name
[0] == 0) /* ignore rest entry */
754 if (!(entry
->flags
& reject_filter
))
762 group_list_has_visible_entries (GOptionContext
*context
,
764 gboolean main_entries
)
768 if (group_has_visible_entries (context
, group_list
->data
, main_entries
))
771 group_list
= group_list
->next
;
778 context_has_h_entry (GOptionContext
*context
)
783 if (context
->main_group
)
785 for (i
= 0; i
< context
->main_group
->n_entries
; i
++)
787 if (context
->main_group
->entries
[i
].short_name
== 'h')
792 for (list
= context
->groups
; list
!= NULL
; list
= g_list_next (list
))
796 group
= (GOptionGroup
*)list
->data
;
797 for (i
= 0; i
< group
->n_entries
; i
++)
799 if (group
->entries
[i
].short_name
== 'h')
807 * g_option_context_get_help:
808 * @context: a #GOptionContext
809 * @main_help: if %TRUE, only include the main group
810 * @group: (nullable): the #GOptionGroup to create help for, or %NULL
812 * Returns a formatted, translated help text for the given context.
813 * To obtain the text produced by `--help`, call
814 * `g_option_context_get_help (context, TRUE, NULL)`.
815 * To obtain the text produced by `--help-all`, call
816 * `g_option_context_get_help (context, FALSE, NULL)`.
817 * To obtain the help text for an option group, call
818 * `g_option_context_get_help (context, FALSE, group)`.
820 * Returns: A newly allocated string containing the help text
825 g_option_context_get_help (GOptionContext
*context
,
830 gint max_length
= 0, len
;
833 GHashTable
*shadow_map
;
836 const gchar
*rest_description
;
840 string
= g_string_sized_new (1024);
842 rest_description
= NULL
;
843 if (context
->main_group
)
846 for (i
= 0; i
< context
->main_group
->n_entries
; i
++)
848 entry
= &context
->main_group
->entries
[i
];
849 if (entry
->long_name
[0] == 0)
851 rest_description
= TRANSLATE (context
->main_group
, entry
->arg_description
);
857 g_string_append_printf (string
, "%s\n %s", _("Usage:"), g_get_prgname ());
858 if (context
->help_enabled
||
859 (context
->main_group
&& context
->main_group
->n_entries
> 0) ||
860 context
->groups
!= NULL
)
861 g_string_append_printf (string
, " %s", _("[OPTION…]"));
863 if (rest_description
)
865 g_string_append (string
, " ");
866 g_string_append (string
, rest_description
);
869 if (context
->parameter_string
)
871 g_string_append (string
, " ");
872 g_string_append (string
, TRANSLATE (context
, context
->parameter_string
));
875 g_string_append (string
, "\n\n");
877 if (context
->summary
)
879 g_string_append (string
, TRANSLATE (context
, context
->summary
));
880 g_string_append (string
, "\n\n");
883 memset (seen
, 0, sizeof (gboolean
) * 256);
884 shadow_map
= g_hash_table_new (g_str_hash
, g_str_equal
);
885 aliases
= g_hash_table_new_full (NULL
, NULL
, NULL
, g_free
);
887 if (context
->main_group
)
889 for (i
= 0; i
< context
->main_group
->n_entries
; i
++)
891 entry
= &context
->main_group
->entries
[i
];
892 g_hash_table_insert (shadow_map
,
893 (gpointer
)entry
->long_name
,
896 if (seen
[(guchar
)entry
->short_name
])
897 entry
->short_name
= 0;
899 seen
[(guchar
)entry
->short_name
] = TRUE
;
903 list
= context
->groups
;
906 GOptionGroup
*g
= list
->data
;
907 for (i
= 0; i
< g
->n_entries
; i
++)
909 entry
= &g
->entries
[i
];
910 if (g_hash_table_lookup (shadow_map
, entry
->long_name
) &&
911 !(entry
->flags
& G_OPTION_FLAG_NOALIAS
))
913 g_hash_table_insert (aliases
, &entry
->long_name
,
914 g_strdup_printf ("%s-%s", g
->name
, entry
->long_name
));
917 g_hash_table_insert (shadow_map
, (gpointer
)entry
->long_name
, entry
);
919 if (seen
[(guchar
)entry
->short_name
] &&
920 !(entry
->flags
& G_OPTION_FLAG_NOALIAS
))
921 entry
->short_name
= 0;
923 seen
[(guchar
)entry
->short_name
] = TRUE
;
928 g_hash_table_destroy (shadow_map
);
930 list
= context
->groups
;
932 if (context
->help_enabled
)
934 max_length
= _g_utf8_strwidth ("-?, --help");
938 len
= _g_utf8_strwidth ("--help-all");
939 max_length
= MAX (max_length
, len
);
943 if (context
->main_group
)
945 len
= calculate_max_length (context
->main_group
, aliases
);
946 max_length
= MAX (max_length
, len
);
951 GOptionGroup
*g
= list
->data
;
953 if (context
->help_enabled
)
955 /* First, we check the --help-<groupname> options */
956 len
= _g_utf8_strwidth ("--help-") + _g_utf8_strwidth (g
->name
);
957 max_length
= MAX (max_length
, len
);
960 /* Then we go through the entries */
961 len
= calculate_max_length (g
, aliases
);
962 max_length
= MAX (max_length
, len
);
967 /* Add a bit of padding */
970 if (!group
&& context
->help_enabled
)
972 list
= context
->groups
;
974 token
= context_has_h_entry (context
) ? '?' : 'h';
976 g_string_append_printf (string
, "%s\n -%c, --%-*s %s\n",
977 _("Help Options:"), token
, max_length
- 4, "help",
978 _("Show help options"));
980 /* We only want --help-all when there are groups */
982 g_string_append_printf (string
, " --%-*s %s\n",
983 max_length
, "help-all",
984 _("Show all help options"));
988 GOptionGroup
*g
= list
->data
;
990 if (group_has_visible_entries (context
, g
, FALSE
))
991 g_string_append_printf (string
, " --help-%-*s %s\n",
992 max_length
- 5, g
->name
,
993 TRANSLATE (g
, g
->help_description
));
998 g_string_append (string
, "\n");
1003 /* Print a certain group */
1005 if (group_has_visible_entries (context
, group
, FALSE
))
1007 g_string_append (string
, TRANSLATE (group
, group
->description
));
1008 g_string_append (string
, "\n");
1009 for (i
= 0; i
< group
->n_entries
; i
++)
1010 print_entry (group
, max_length
, &group
->entries
[i
], string
, aliases
);
1011 g_string_append (string
, "\n");
1014 else if (!main_help
)
1016 /* Print all groups */
1018 list
= context
->groups
;
1022 GOptionGroup
*g
= list
->data
;
1024 if (group_has_visible_entries (context
, g
, FALSE
))
1026 g_string_append (string
, g
->description
);
1027 g_string_append (string
, "\n");
1028 for (i
= 0; i
< g
->n_entries
; i
++)
1029 if (!(g
->entries
[i
].flags
& G_OPTION_FLAG_IN_MAIN
))
1030 print_entry (g
, max_length
, &g
->entries
[i
], string
, aliases
);
1032 g_string_append (string
, "\n");
1039 /* Print application options if --help or --help-all has been specified */
1040 if ((main_help
|| !group
) &&
1041 (group_has_visible_entries (context
, context
->main_group
, TRUE
) ||
1042 group_list_has_visible_entries (context
, context
->groups
, TRUE
)))
1044 list
= context
->groups
;
1046 if (context
->help_enabled
|| list
)
1047 g_string_append (string
, _("Application Options:"));
1049 g_string_append (string
, _("Options:"));
1050 g_string_append (string
, "\n");
1051 if (context
->main_group
)
1052 for (i
= 0; i
< context
->main_group
->n_entries
; i
++)
1053 print_entry (context
->main_group
, max_length
,
1054 &context
->main_group
->entries
[i
], string
, aliases
);
1056 while (list
!= NULL
)
1058 GOptionGroup
*g
= list
->data
;
1060 /* Print main entries from other groups */
1061 for (i
= 0; i
< g
->n_entries
; i
++)
1062 if (g
->entries
[i
].flags
& G_OPTION_FLAG_IN_MAIN
)
1063 print_entry (g
, max_length
, &g
->entries
[i
], string
, aliases
);
1068 g_string_append (string
, "\n");
1071 if (context
->description
)
1073 g_string_append (string
, TRANSLATE (context
, context
->description
));
1074 g_string_append (string
, "\n");
1077 g_hash_table_destroy (aliases
);
1079 return g_string_free (string
, FALSE
);
1084 print_help (GOptionContext
*context
,
1086 GOptionGroup
*group
)
1090 help
= g_option_context_get_help (context
, main_help
, group
);
1091 g_print ("%s", help
);
1098 parse_int (const gchar
*arg_name
,
1107 tmp
= strtol (arg
, &end
, 0);
1109 if (*arg
== '\0' || *end
!= '\0')
1112 G_OPTION_ERROR
, G_OPTION_ERROR_BAD_VALUE
,
1113 _("Cannot parse integer value “%s” for %s"),
1119 if (*result
!= tmp
|| errno
== ERANGE
)
1122 G_OPTION_ERROR
, G_OPTION_ERROR_BAD_VALUE
,
1123 _("Integer value “%s” for %s out of range"),
1133 parse_double (const gchar
*arg_name
,
1142 tmp
= g_strtod (arg
, &end
);
1144 if (*arg
== '\0' || *end
!= '\0')
1147 G_OPTION_ERROR
, G_OPTION_ERROR_BAD_VALUE
,
1148 _("Cannot parse double value “%s” for %s"),
1152 if (errno
== ERANGE
)
1155 G_OPTION_ERROR
, G_OPTION_ERROR_BAD_VALUE
,
1156 _("Double value “%s” for %s out of range"),
1168 parse_int64 (const gchar
*arg_name
,
1177 tmp
= g_ascii_strtoll (arg
, &end
, 0);
1179 if (*arg
== '\0' || *end
!= '\0')
1182 G_OPTION_ERROR
, G_OPTION_ERROR_BAD_VALUE
,
1183 _("Cannot parse integer value “%s” for %s"),
1187 if (errno
== ERANGE
)
1190 G_OPTION_ERROR
, G_OPTION_ERROR_BAD_VALUE
,
1191 _("Integer value “%s” for %s out of range"),
1203 get_change (GOptionContext
*context
,
1204 GOptionArg arg_type
,
1208 Change
*change
= NULL
;
1210 for (list
= context
->changes
; list
!= NULL
; list
= list
->next
)
1212 change
= list
->data
;
1214 if (change
->arg_data
== arg_data
)
1218 change
= g_new0 (Change
, 1);
1219 change
->arg_type
= arg_type
;
1220 change
->arg_data
= arg_data
;
1222 context
->changes
= g_list_prepend (context
->changes
, change
);
1230 add_pending_null (GOptionContext
*context
,
1236 n
= g_new0 (PendingNull
, 1);
1240 context
->pending_nulls
= g_list_prepend (context
->pending_nulls
, n
);
1244 parse_arg (GOptionContext
*context
,
1245 GOptionGroup
*group
,
1246 GOptionEntry
*entry
,
1248 const gchar
*option_name
,
1254 g_assert (value
|| OPTIONAL_ARG (entry
) || NO_ARG (entry
));
1258 case G_OPTION_ARG_NONE
:
1260 (void) get_change (context
, G_OPTION_ARG_NONE
,
1263 *(gboolean
*)entry
->arg_data
= !(entry
->flags
& G_OPTION_FLAG_REVERSE
);
1266 case G_OPTION_ARG_STRING
:
1271 if (!context
->strv_mode
)
1272 data
= g_locale_to_utf8 (value
, -1, NULL
, NULL
, error
);
1274 data
= g_strdup (value
);
1276 data
= g_locale_to_utf8 (value
, -1, NULL
, NULL
, error
);
1282 change
= get_change (context
, G_OPTION_ARG_STRING
,
1285 if (!change
->allocated
.str
)
1286 change
->prev
.str
= *(gchar
**)entry
->arg_data
;
1288 g_free (change
->allocated
.str
);
1290 change
->allocated
.str
= data
;
1292 *(gchar
**)entry
->arg_data
= data
;
1295 case G_OPTION_ARG_STRING_ARRAY
:
1300 if (!context
->strv_mode
)
1301 data
= g_locale_to_utf8 (value
, -1, NULL
, NULL
, error
);
1303 data
= g_strdup (value
);
1305 data
= g_locale_to_utf8 (value
, -1, NULL
, NULL
, error
);
1311 change
= get_change (context
, G_OPTION_ARG_STRING_ARRAY
,
1314 if (change
->allocated
.array
.len
== 0)
1316 change
->prev
.array
= *(gchar
***)entry
->arg_data
;
1317 change
->allocated
.array
.data
= g_new (gchar
*, 2);
1320 change
->allocated
.array
.data
=
1321 g_renew (gchar
*, change
->allocated
.array
.data
,
1322 change
->allocated
.array
.len
+ 2);
1324 change
->allocated
.array
.data
[change
->allocated
.array
.len
] = data
;
1325 change
->allocated
.array
.data
[change
->allocated
.array
.len
+ 1] = NULL
;
1327 change
->allocated
.array
.len
++;
1329 *(gchar
***)entry
->arg_data
= change
->allocated
.array
.data
;
1334 case G_OPTION_ARG_FILENAME
:
1339 if (!context
->strv_mode
)
1340 data
= g_locale_to_utf8 (value
, -1, NULL
, NULL
, error
);
1342 data
= g_strdup (value
);
1347 data
= g_strdup (value
);
1349 change
= get_change (context
, G_OPTION_ARG_FILENAME
,
1352 if (!change
->allocated
.str
)
1353 change
->prev
.str
= *(gchar
**)entry
->arg_data
;
1355 g_free (change
->allocated
.str
);
1357 change
->allocated
.str
= data
;
1359 *(gchar
**)entry
->arg_data
= data
;
1363 case G_OPTION_ARG_FILENAME_ARRAY
:
1368 if (!context
->strv_mode
)
1369 data
= g_locale_to_utf8 (value
, -1, NULL
, NULL
, error
);
1371 data
= g_strdup (value
);
1376 data
= g_strdup (value
);
1378 change
= get_change (context
, G_OPTION_ARG_STRING_ARRAY
,
1381 if (change
->allocated
.array
.len
== 0)
1383 change
->prev
.array
= *(gchar
***)entry
->arg_data
;
1384 change
->allocated
.array
.data
= g_new (gchar
*, 2);
1387 change
->allocated
.array
.data
=
1388 g_renew (gchar
*, change
->allocated
.array
.data
,
1389 change
->allocated
.array
.len
+ 2);
1391 change
->allocated
.array
.data
[change
->allocated
.array
.len
] = data
;
1392 change
->allocated
.array
.data
[change
->allocated
.array
.len
+ 1] = NULL
;
1394 change
->allocated
.array
.len
++;
1396 *(gchar
***)entry
->arg_data
= change
->allocated
.array
.data
;
1401 case G_OPTION_ARG_INT
:
1405 if (!parse_int (option_name
, value
,
1410 change
= get_change (context
, G_OPTION_ARG_INT
,
1412 change
->prev
.integer
= *(gint
*)entry
->arg_data
;
1413 *(gint
*)entry
->arg_data
= data
;
1416 case G_OPTION_ARG_CALLBACK
:
1421 if (!value
&& entry
->flags
& G_OPTION_FLAG_OPTIONAL_ARG
)
1423 else if (entry
->flags
& G_OPTION_FLAG_NO_ARG
)
1425 else if (entry
->flags
& G_OPTION_FLAG_FILENAME
)
1428 if (!context
->strv_mode
)
1429 data
= g_locale_to_utf8 (value
, -1, NULL
, NULL
, error
);
1431 data
= g_strdup (value
);
1433 data
= g_strdup (value
);
1437 data
= g_locale_to_utf8 (value
, -1, NULL
, NULL
, error
);
1439 if (!(entry
->flags
& (G_OPTION_FLAG_NO_ARG
|G_OPTION_FLAG_OPTIONAL_ARG
)) &&
1443 retval
= (* (GOptionArgFunc
) entry
->arg_data
) (option_name
, data
, group
->user_data
, error
);
1445 if (!retval
&& error
!= NULL
&& *error
== NULL
)
1447 G_OPTION_ERROR
, G_OPTION_ERROR_FAILED
,
1448 _("Error parsing option %s"), option_name
);
1456 case G_OPTION_ARG_DOUBLE
:
1460 if (!parse_double (option_name
, value
,
1467 change
= get_change (context
, G_OPTION_ARG_DOUBLE
,
1469 change
->prev
.dbl
= *(gdouble
*)entry
->arg_data
;
1470 *(gdouble
*)entry
->arg_data
= data
;
1473 case G_OPTION_ARG_INT64
:
1477 if (!parse_int64 (option_name
, value
,
1484 change
= get_change (context
, G_OPTION_ARG_INT64
,
1486 change
->prev
.int64
= *(gint64
*)entry
->arg_data
;
1487 *(gint64
*)entry
->arg_data
= data
;
1491 g_assert_not_reached ();
1498 parse_short_option (GOptionContext
*context
,
1499 GOptionGroup
*group
,
1510 for (j
= 0; j
< group
->n_entries
; j
++)
1512 if (arg
== group
->entries
[j
].short_name
)
1515 gchar
*value
= NULL
;
1517 option_name
= g_strdup_printf ("-%c", group
->entries
[j
].short_name
);
1519 if (NO_ARG (&group
->entries
[j
]))
1526 G_OPTION_ERROR
, G_OPTION_ERROR_FAILED
,
1527 _("Error parsing option %s"), option_name
);
1528 g_free (option_name
);
1532 if (idx
< *argc
- 1)
1534 if (!OPTIONAL_ARG (&group
->entries
[j
]))
1536 value
= (*argv
)[idx
+ 1];
1537 add_pending_null (context
, &((*argv
)[idx
+ 1]), NULL
);
1542 if ((*argv
)[idx
+ 1][0] == '-')
1546 value
= (*argv
)[idx
+ 1];
1547 add_pending_null (context
, &((*argv
)[idx
+ 1]), NULL
);
1552 else if (idx
>= *argc
- 1 && OPTIONAL_ARG (&group
->entries
[j
]))
1557 G_OPTION_ERROR
, G_OPTION_ERROR_BAD_VALUE
,
1558 _("Missing argument for %s"), option_name
);
1559 g_free (option_name
);
1564 if (!parse_arg (context
, group
, &group
->entries
[j
],
1565 value
, option_name
, error
))
1567 g_free (option_name
);
1571 g_free (option_name
);
1580 parse_long_option (GOptionContext
*context
,
1581 GOptionGroup
*group
,
1592 for (j
= 0; j
< group
->n_entries
; j
++)
1597 if (aliased
&& (group
->entries
[j
].flags
& G_OPTION_FLAG_NOALIAS
))
1600 if (NO_ARG (&group
->entries
[j
]) &&
1601 strcmp (arg
, group
->entries
[j
].long_name
) == 0)
1606 option_name
= g_strconcat ("--", group
->entries
[j
].long_name
, NULL
);
1607 retval
= parse_arg (context
, group
, &group
->entries
[j
],
1608 NULL
, option_name
, error
);
1609 g_free (option_name
);
1611 add_pending_null (context
, &((*argv
)[*idx
]), NULL
);
1618 gint len
= strlen (group
->entries
[j
].long_name
);
1620 if (strncmp (arg
, group
->entries
[j
].long_name
, len
) == 0 &&
1621 (arg
[len
] == '=' || arg
[len
] == 0))
1623 gchar
*value
= NULL
;
1626 add_pending_null (context
, &((*argv
)[*idx
]), NULL
);
1627 option_name
= g_strconcat ("--", group
->entries
[j
].long_name
, NULL
);
1629 if (arg
[len
] == '=')
1630 value
= arg
+ len
+ 1;
1631 else if (*idx
< *argc
- 1)
1633 if (!OPTIONAL_ARG (&group
->entries
[j
]))
1635 value
= (*argv
)[*idx
+ 1];
1636 add_pending_null (context
, &((*argv
)[*idx
+ 1]), NULL
);
1641 if ((*argv
)[*idx
+ 1][0] == '-')
1644 retval
= parse_arg (context
, group
, &group
->entries
[j
],
1645 NULL
, option_name
, error
);
1647 g_free (option_name
);
1652 value
= (*argv
)[*idx
+ 1];
1653 add_pending_null (context
, &((*argv
)[*idx
+ 1]), NULL
);
1658 else if (*idx
>= *argc
- 1 && OPTIONAL_ARG (&group
->entries
[j
]))
1661 retval
= parse_arg (context
, group
, &group
->entries
[j
],
1662 NULL
, option_name
, error
);
1664 g_free (option_name
);
1670 G_OPTION_ERROR
, G_OPTION_ERROR_BAD_VALUE
,
1671 _("Missing argument for %s"), option_name
);
1672 g_free (option_name
);
1676 if (!parse_arg (context
, group
, &group
->entries
[j
],
1677 value
, option_name
, error
))
1679 g_free (option_name
);
1683 g_free (option_name
);
1693 parse_remaining_arg (GOptionContext
*context
,
1694 GOptionGroup
*group
,
1703 for (j
= 0; j
< group
->n_entries
; j
++)
1708 if (group
->entries
[j
].long_name
[0])
1711 g_return_val_if_fail (group
->entries
[j
].arg
== G_OPTION_ARG_CALLBACK
||
1712 group
->entries
[j
].arg
== G_OPTION_ARG_STRING_ARRAY
||
1713 group
->entries
[j
].arg
== G_OPTION_ARG_FILENAME_ARRAY
, FALSE
);
1715 add_pending_null (context
, &((*argv
)[*idx
]), NULL
);
1717 if (!parse_arg (context
, group
, &group
->entries
[j
], (*argv
)[*idx
], "", error
))
1728 free_changes_list (GOptionContext
*context
,
1733 for (list
= context
->changes
; list
!= NULL
; list
= list
->next
)
1735 Change
*change
= list
->data
;
1739 switch (change
->arg_type
)
1741 case G_OPTION_ARG_NONE
:
1742 *(gboolean
*)change
->arg_data
= change
->prev
.bool;
1744 case G_OPTION_ARG_INT
:
1745 *(gint
*)change
->arg_data
= change
->prev
.integer
;
1747 case G_OPTION_ARG_STRING
:
1748 case G_OPTION_ARG_FILENAME
:
1749 g_free (change
->allocated
.str
);
1750 *(gchar
**)change
->arg_data
= change
->prev
.str
;
1752 case G_OPTION_ARG_STRING_ARRAY
:
1753 case G_OPTION_ARG_FILENAME_ARRAY
:
1754 g_strfreev (change
->allocated
.array
.data
);
1755 *(gchar
***)change
->arg_data
= change
->prev
.array
;
1757 case G_OPTION_ARG_DOUBLE
:
1758 *(gdouble
*)change
->arg_data
= change
->prev
.dbl
;
1760 case G_OPTION_ARG_INT64
:
1761 *(gint64
*)change
->arg_data
= change
->prev
.int64
;
1764 g_assert_not_reached ();
1771 g_list_free (context
->changes
);
1772 context
->changes
= NULL
;
1776 free_pending_nulls (GOptionContext
*context
,
1777 gboolean perform_nulls
)
1781 for (list
= context
->pending_nulls
; list
!= NULL
; list
= list
->next
)
1783 PendingNull
*n
= list
->data
;
1789 /* Copy back the short options */
1791 strcpy (*n
->ptr
+ 1, n
->value
);
1795 if (context
->strv_mode
)
1806 g_list_free (context
->pending_nulls
);
1807 context
->pending_nulls
= NULL
;
1810 /* Use a platform-specific mechanism to look up the first argument to
1811 * the current process.
1812 * Note if you implement this for other platforms, also add it to
1813 * tests/option-argv0.c
1816 platform_get_argv0 (void)
1823 if (!g_file_get_contents ("/proc/self/cmdline",
1828 /* Sanity check for a NUL terminator. */
1829 if (!memchr (cmdline
, 0, len
))
1831 /* We could just return cmdline, but I think it's better
1832 * to hold on to a smaller malloc block; the arguments
1835 base_arg0
= g_path_get_basename (cmdline
);
1838 #elif defined __OpenBSD__
1843 int mib
[] = { CTL_KERN
, KERN_PROC_ARGS
, getpid(), KERN_PROC_ARGV
};
1845 if (sysctl (mib
, G_N_ELEMENTS (mib
), NULL
, &len
, NULL
, 0) == -1)
1848 cmdline
= g_malloc0 (len
);
1850 if (sysctl (mib
, G_N_ELEMENTS (mib
), cmdline
, &len
, NULL
, 0) == -1)
1856 /* We could just return cmdline, but I think it's better
1857 * to hold on to a smaller malloc block; the arguments
1860 base_arg0
= g_path_get_basename (*cmdline
);
1869 * g_option_context_parse:
1870 * @context: a #GOptionContext
1871 * @argc: (inout) (optional): a pointer to the number of command line arguments
1872 * @argv: (inout) (array length=argc) (optional): a pointer to the array of command line arguments
1873 * @error: a return location for errors
1875 * Parses the command line arguments, recognizing options
1876 * which have been added to @context. A side-effect of
1877 * calling this function is that g_set_prgname() will be
1880 * If the parsing is successful, any parsed arguments are
1881 * removed from the array and @argc and @argv are updated
1882 * accordingly. A '--' option is stripped from @argv
1883 * unless there are unparsed options before and after it,
1884 * or some of the options after it start with '-'. In case
1885 * of an error, @argc and @argv are left unmodified.
1887 * If automatic `--help` support is enabled
1888 * (see g_option_context_set_help_enabled()), and the
1889 * @argv array contains one of the recognized help options,
1890 * this function will produce help output to stdout and
1893 * Note that function depends on the [current locale][setlocale] for
1894 * automatic character set conversion of string and filename
1897 * Returns: %TRUE if the parsing was successful,
1898 * %FALSE if an error occurred
1903 g_option_context_parse (GOptionContext
*context
,
1911 /* Set program name */
1912 if (!g_get_prgname())
1916 if (argc
&& argv
&& *argc
)
1917 prgname
= g_path_get_basename ((*argv
)[0]);
1919 prgname
= platform_get_argv0 ();
1922 g_set_prgname (prgname
);
1924 g_set_prgname ("<unknown>");
1929 /* Call pre-parse hooks */
1930 list
= context
->groups
;
1933 GOptionGroup
*group
= list
->data
;
1935 if (group
->pre_parse_func
)
1937 if (!(* group
->pre_parse_func
) (context
, group
,
1938 group
->user_data
, error
))
1945 if (context
->main_group
&& context
->main_group
->pre_parse_func
)
1947 if (!(* context
->main_group
->pre_parse_func
) (context
, context
->main_group
,
1948 context
->main_group
->user_data
, error
))
1954 gboolean stop_parsing
= FALSE
;
1955 gboolean has_unknown
= FALSE
;
1956 gint separator_pos
= 0;
1958 for (i
= 1; i
< *argc
; i
++)
1961 gboolean parsed
= FALSE
;
1963 if ((*argv
)[i
][0] == '-' && (*argv
)[i
][1] != '\0' && !stop_parsing
)
1965 if ((*argv
)[i
][1] == '-')
1969 arg
= (*argv
)[i
] + 2;
1971 /* '--' terminates list of arguments */
1975 stop_parsing
= TRUE
;
1979 /* Handle help options */
1980 if (context
->help_enabled
)
1982 if (strcmp (arg
, "help") == 0)
1983 print_help (context
, TRUE
, NULL
);
1984 else if (strcmp (arg
, "help-all") == 0)
1985 print_help (context
, FALSE
, NULL
);
1986 else if (strncmp (arg
, "help-", 5) == 0)
1988 list
= context
->groups
;
1992 GOptionGroup
*group
= list
->data
;
1994 if (strcmp (arg
+ 5, group
->name
) == 0)
1995 print_help (context
, FALSE
, group
);
2002 if (context
->main_group
&&
2003 !parse_long_option (context
, context
->main_group
, &i
, arg
,
2004 FALSE
, argc
, argv
, error
, &parsed
))
2010 /* Try the groups */
2011 list
= context
->groups
;
2014 GOptionGroup
*group
= list
->data
;
2016 if (!parse_long_option (context
, group
, &i
, arg
,
2017 FALSE
, argc
, argv
, error
, &parsed
))
2029 /* Now look for --<group>-<option> */
2030 dash
= strchr (arg
, '-');
2033 /* Try the groups */
2034 list
= context
->groups
;
2037 GOptionGroup
*group
= list
->data
;
2039 if (strncmp (group
->name
, arg
, dash
- arg
) == 0)
2041 if (!parse_long_option (context
, group
, &i
, dash
+ 1,
2042 TRUE
, argc
, argv
, error
, &parsed
))
2053 if (context
->ignore_unknown
)
2057 { /* short option */
2058 gint new_i
= i
, arg_length
;
2059 gboolean
*nulled_out
= NULL
;
2060 gboolean has_h_entry
= context_has_h_entry (context
);
2061 arg
= (*argv
)[i
] + 1;
2062 arg_length
= strlen (arg
);
2063 nulled_out
= g_newa (gboolean
, arg_length
);
2064 memset (nulled_out
, 0, arg_length
* sizeof (gboolean
));
2065 for (j
= 0; j
< arg_length
; j
++)
2067 if (context
->help_enabled
&& (arg
[j
] == '?' ||
2068 (arg
[j
] == 'h' && !has_h_entry
)))
2069 print_help (context
, TRUE
, NULL
);
2071 if (context
->main_group
&&
2072 !parse_short_option (context
, context
->main_group
,
2074 argc
, argv
, error
, &parsed
))
2078 /* Try the groups */
2079 list
= context
->groups
;
2082 GOptionGroup
*group
= list
->data
;
2083 if (!parse_short_option (context
, group
, i
, &new_i
, arg
[j
],
2084 argc
, argv
, error
, &parsed
))
2092 if (context
->ignore_unknown
&& parsed
)
2093 nulled_out
[j
] = TRUE
;
2094 else if (context
->ignore_unknown
)
2098 /* !context->ignore_unknown && parsed */
2100 if (context
->ignore_unknown
)
2102 gchar
*new_arg
= NULL
;
2104 for (j
= 0; j
< arg_length
; j
++)
2109 new_arg
= g_malloc (arg_length
+ 1);
2110 new_arg
[arg_index
++] = arg
[j
];
2114 new_arg
[arg_index
] = '\0';
2115 add_pending_null (context
, &((*argv
)[i
]), new_arg
);
2120 add_pending_null (context
, &((*argv
)[i
]), NULL
);
2128 if (!parsed
&& !context
->ignore_unknown
)
2131 G_OPTION_ERROR
, G_OPTION_ERROR_UNKNOWN_OPTION
,
2132 _("Unknown option %s"), (*argv
)[i
]);
2138 if (context
->strict_posix
)
2139 stop_parsing
= TRUE
;
2141 /* Collect remaining args */
2142 if (context
->main_group
&&
2143 !parse_remaining_arg (context
, context
->main_group
, &i
,
2144 argc
, argv
, error
, &parsed
))
2147 if (!parsed
&& (has_unknown
|| (*argv
)[i
][0] == '-'))
2152 if (separator_pos
> 0)
2153 add_pending_null (context
, &((*argv
)[separator_pos
]), NULL
);
2157 /* Call post-parse hooks */
2158 list
= context
->groups
;
2161 GOptionGroup
*group
= list
->data
;
2163 if (group
->post_parse_func
)
2165 if (!(* group
->post_parse_func
) (context
, group
,
2166 group
->user_data
, error
))
2173 if (context
->main_group
&& context
->main_group
->post_parse_func
)
2175 if (!(* context
->main_group
->post_parse_func
) (context
, context
->main_group
,
2176 context
->main_group
->user_data
, error
))
2182 free_pending_nulls (context
, TRUE
);
2184 for (i
= 1; i
< *argc
; i
++)
2186 for (k
= i
; k
< *argc
; k
++)
2187 if ((*argv
)[k
] != NULL
)
2193 for (j
= i
+ k
; j
< *argc
; j
++)
2195 (*argv
)[j
-k
] = (*argv
)[j
];
2207 /* Call error hooks */
2208 list
= context
->groups
;
2211 GOptionGroup
*group
= list
->data
;
2213 if (group
->error_func
)
2214 (* group
->error_func
) (context
, group
,
2215 group
->user_data
, error
);
2220 if (context
->main_group
&& context
->main_group
->error_func
)
2221 (* context
->main_group
->error_func
) (context
, context
->main_group
,
2222 context
->main_group
->user_data
, error
);
2224 free_changes_list (context
, TRUE
);
2225 free_pending_nulls (context
, FALSE
);
2231 * g_option_group_new:
2232 * @name: the name for the option group, this is used to provide
2233 * help for the options in this group with `--help-`@name
2234 * @description: a description for this group to be shown in
2235 * `--help`. This string is translated using the translation
2236 * domain or translation function of the group
2237 * @help_description: a description for the `--help-`@name option.
2238 * This string is translated using the translation domain or translation function
2240 * @user_data: (nullable): user data that will be passed to the pre- and post-parse hooks,
2241 * the error hook and to callbacks of %G_OPTION_ARG_CALLBACK options, or %NULL
2242 * @destroy: (nullable): a function that will be called to free @user_data, or %NULL
2244 * Creates a new #GOptionGroup.
2246 * Returns: a newly created option group. It should be added
2247 * to a #GOptionContext or freed with g_option_group_unref().
2252 g_option_group_new (const gchar
*name
,
2253 const gchar
*description
,
2254 const gchar
*help_description
,
2256 GDestroyNotify destroy
)
2259 GOptionGroup
*group
;
2261 group
= g_new0 (GOptionGroup
, 1);
2262 group
->ref_count
= 1;
2263 group
->name
= g_strdup (name
);
2264 group
->description
= g_strdup (description
);
2265 group
->help_description
= g_strdup (help_description
);
2266 group
->user_data
= user_data
;
2267 group
->destroy_notify
= destroy
;
2274 * g_option_group_free:
2275 * @group: a #GOptionGroup
2277 * Frees a #GOptionGroup. Note that you must not free groups
2278 * which have been added to a #GOptionContext.
2282 * Deprecated: 2.44: Use g_option_group_unref() instead.
2285 g_option_group_free (GOptionGroup
*group
)
2287 g_option_group_unref (group
);
2291 * g_option_group_ref:
2292 * @group: a #GOptionGroup
2294 * Increments the reference count of @group by one.
2296 * Returns: a #GoptionGroup
2301 g_option_group_ref (GOptionGroup
*group
)
2303 g_return_val_if_fail (group
!= NULL
, NULL
);
2311 * g_option_group_unref:
2312 * @group: a #GOptionGroup
2314 * Decrements the reference count of @group by one.
2315 * If the reference count drops to 0, the @group will be freed.
2316 * and all memory allocated by the @group is released.
2321 g_option_group_unref (GOptionGroup
*group
)
2323 g_return_if_fail (group
!= NULL
);
2325 if (--group
->ref_count
== 0)
2327 g_free (group
->name
);
2328 g_free (group
->description
);
2329 g_free (group
->help_description
);
2331 g_free (group
->entries
);
2333 if (group
->destroy_notify
)
2334 (* group
->destroy_notify
) (group
->user_data
);
2336 if (group
->translate_notify
)
2337 (* group
->translate_notify
) (group
->translate_data
);
2344 * g_option_group_add_entries:
2345 * @group: a #GOptionGroup
2346 * @entries: a %NULL-terminated array of #GOptionEntrys
2348 * Adds the options specified in @entries to @group.
2353 g_option_group_add_entries (GOptionGroup
*group
,
2354 const GOptionEntry
*entries
)
2358 g_return_if_fail (entries
!= NULL
);
2360 for (n_entries
= 0; entries
[n_entries
].long_name
!= NULL
; n_entries
++) ;
2362 group
->entries
= g_renew (GOptionEntry
, group
->entries
, group
->n_entries
+ n_entries
);
2364 /* group->entries could be NULL in the trivial case where we add no
2365 * entries to no entries */
2367 memcpy (group
->entries
+ group
->n_entries
, entries
, sizeof (GOptionEntry
) * n_entries
);
2369 for (i
= group
->n_entries
; i
< group
->n_entries
+ n_entries
; i
++)
2371 gchar c
= group
->entries
[i
].short_name
;
2373 if (c
== '-' || (c
!= 0 && !g_ascii_isprint (c
)))
2375 g_warning (G_STRLOC
": ignoring invalid short option '%c' (%d) in entry %s:%s",
2376 c
, c
, group
->name
, group
->entries
[i
].long_name
);
2377 group
->entries
[i
].short_name
= '\0';
2380 if (group
->entries
[i
].arg
!= G_OPTION_ARG_NONE
&&
2381 (group
->entries
[i
].flags
& G_OPTION_FLAG_REVERSE
) != 0)
2383 g_warning (G_STRLOC
": ignoring reverse flag on option of arg-type %d in entry %s:%s",
2384 group
->entries
[i
].arg
, group
->name
, group
->entries
[i
].long_name
);
2386 group
->entries
[i
].flags
&= ~G_OPTION_FLAG_REVERSE
;
2389 if (group
->entries
[i
].arg
!= G_OPTION_ARG_CALLBACK
&&
2390 (group
->entries
[i
].flags
& (G_OPTION_FLAG_NO_ARG
|G_OPTION_FLAG_OPTIONAL_ARG
|G_OPTION_FLAG_FILENAME
)) != 0)
2392 g_warning (G_STRLOC
": ignoring no-arg, optional-arg or filename flags (%d) on option of arg-type %d in entry %s:%s",
2393 group
->entries
[i
].flags
, group
->entries
[i
].arg
, group
->name
, group
->entries
[i
].long_name
);
2395 group
->entries
[i
].flags
&= ~(G_OPTION_FLAG_NO_ARG
|G_OPTION_FLAG_OPTIONAL_ARG
|G_OPTION_FLAG_FILENAME
);
2399 group
->n_entries
+= n_entries
;
2403 * g_option_group_set_parse_hooks:
2404 * @group: a #GOptionGroup
2405 * @pre_parse_func: (nullable): a function to call before parsing, or %NULL
2406 * @post_parse_func: (nullable): a function to call after parsing, or %NULL
2408 * Associates two functions with @group which will be called
2409 * from g_option_context_parse() before the first option is parsed
2410 * and after the last option has been parsed, respectively.
2412 * Note that the user data to be passed to @pre_parse_func and
2413 * @post_parse_func can be specified when constructing the group
2414 * with g_option_group_new().
2419 g_option_group_set_parse_hooks (GOptionGroup
*group
,
2420 GOptionParseFunc pre_parse_func
,
2421 GOptionParseFunc post_parse_func
)
2423 g_return_if_fail (group
!= NULL
);
2425 group
->pre_parse_func
= pre_parse_func
;
2426 group
->post_parse_func
= post_parse_func
;
2430 * g_option_group_set_error_hook:
2431 * @group: a #GOptionGroup
2432 * @error_func: a function to call when an error occurs
2434 * Associates a function with @group which will be called
2435 * from g_option_context_parse() when an error occurs.
2437 * Note that the user data to be passed to @error_func can be
2438 * specified when constructing the group with g_option_group_new().
2443 g_option_group_set_error_hook (GOptionGroup
*group
,
2444 GOptionErrorFunc error_func
)
2446 g_return_if_fail (group
!= NULL
);
2448 group
->error_func
= error_func
;
2453 * g_option_group_set_translate_func:
2454 * @group: a #GOptionGroup
2455 * @func: (nullable): the #GTranslateFunc, or %NULL
2456 * @data: (nullable): user data to pass to @func, or %NULL
2457 * @destroy_notify: (nullable): a function which gets called to free @data, or %NULL
2459 * Sets the function which is used to translate user-visible strings,
2460 * for `--help` output. Different groups can use different
2461 * #GTranslateFuncs. If @func is %NULL, strings are not translated.
2463 * If you are using gettext(), you only need to set the translation
2464 * domain, see g_option_group_set_translation_domain().
2469 g_option_group_set_translate_func (GOptionGroup
*group
,
2470 GTranslateFunc func
,
2472 GDestroyNotify destroy_notify
)
2474 g_return_if_fail (group
!= NULL
);
2476 if (group
->translate_notify
)
2477 group
->translate_notify (group
->translate_data
);
2479 group
->translate_func
= func
;
2480 group
->translate_data
= data
;
2481 group
->translate_notify
= destroy_notify
;
2484 static const gchar
*
2485 dgettext_swapped (const gchar
*msgid
,
2486 const gchar
*domainname
)
2488 return g_dgettext (domainname
, msgid
);
2492 * g_option_group_set_translation_domain:
2493 * @group: a #GOptionGroup
2494 * @domain: the domain to use
2496 * A convenience function to use gettext() for translating
2497 * user-visible strings.
2502 g_option_group_set_translation_domain (GOptionGroup
*group
,
2503 const gchar
*domain
)
2505 g_return_if_fail (group
!= NULL
);
2507 g_option_group_set_translate_func (group
,
2508 (GTranslateFunc
)dgettext_swapped
,
2514 * g_option_context_set_translate_func:
2515 * @context: a #GOptionContext
2516 * @func: (nullable): the #GTranslateFunc, or %NULL
2517 * @data: (nullable): user data to pass to @func, or %NULL
2518 * @destroy_notify: (nullable): a function which gets called to free @data, or %NULL
2520 * Sets the function which is used to translate the contexts
2521 * user-visible strings, for `--help` output. If @func is %NULL,
2522 * strings are not translated.
2524 * Note that option groups have their own translation functions,
2525 * this function only affects the @parameter_string (see g_option_context_new()),
2526 * the summary (see g_option_context_set_summary()) and the description
2527 * (see g_option_context_set_description()).
2529 * If you are using gettext(), you only need to set the translation
2530 * domain, see g_option_context_set_translation_domain().
2535 g_option_context_set_translate_func (GOptionContext
*context
,
2536 GTranslateFunc func
,
2538 GDestroyNotify destroy_notify
)
2540 g_return_if_fail (context
!= NULL
);
2542 if (context
->translate_notify
)
2543 context
->translate_notify (context
->translate_data
);
2545 context
->translate_func
= func
;
2546 context
->translate_data
= data
;
2547 context
->translate_notify
= destroy_notify
;
2551 * g_option_context_set_translation_domain:
2552 * @context: a #GOptionContext
2553 * @domain: the domain to use
2555 * A convenience function to use gettext() for translating
2556 * user-visible strings.
2561 g_option_context_set_translation_domain (GOptionContext
*context
,
2562 const gchar
*domain
)
2564 g_return_if_fail (context
!= NULL
);
2566 g_option_context_set_translate_func (context
,
2567 (GTranslateFunc
)dgettext_swapped
,
2573 * g_option_context_set_summary:
2574 * @context: a #GOptionContext
2575 * @summary: (nullable): a string to be shown in `--help` output
2576 * before the list of options, or %NULL
2578 * Adds a string to be displayed in `--help` output before the list
2579 * of options. This is typically a summary of the program functionality.
2581 * Note that the summary is translated (see
2582 * g_option_context_set_translate_func() and
2583 * g_option_context_set_translation_domain()).
2588 g_option_context_set_summary (GOptionContext
*context
,
2589 const gchar
*summary
)
2591 g_return_if_fail (context
!= NULL
);
2593 g_free (context
->summary
);
2594 context
->summary
= g_strdup (summary
);
2599 * g_option_context_get_summary:
2600 * @context: a #GOptionContext
2602 * Returns the summary. See g_option_context_set_summary().
2604 * Returns: the summary
2609 g_option_context_get_summary (GOptionContext
*context
)
2611 g_return_val_if_fail (context
!= NULL
, NULL
);
2613 return context
->summary
;
2617 * g_option_context_set_description:
2618 * @context: a #GOptionContext
2619 * @description: (nullable): a string to be shown in `--help` output
2620 * after the list of options, or %NULL
2622 * Adds a string to be displayed in `--help` output after the list
2623 * of options. This text often includes a bug reporting address.
2625 * Note that the summary is translated (see
2626 * g_option_context_set_translate_func()).
2631 g_option_context_set_description (GOptionContext
*context
,
2632 const gchar
*description
)
2634 g_return_if_fail (context
!= NULL
);
2636 g_free (context
->description
);
2637 context
->description
= g_strdup (description
);
2642 * g_option_context_get_description:
2643 * @context: a #GOptionContext
2645 * Returns the description. See g_option_context_set_description().
2647 * Returns: the description
2652 g_option_context_get_description (GOptionContext
*context
)
2654 g_return_val_if_fail (context
!= NULL
, NULL
);
2656 return context
->description
;
2660 * g_option_context_parse_strv:
2661 * @context: a #GOptionContext
2662 * @arguments: (inout) (array null-terminated=1): a pointer to the
2663 * command line arguments (which must be in UTF-8 on Windows)
2664 * @error: a return location for errors
2666 * Parses the command line arguments.
2668 * This function is similar to g_option_context_parse() except that it
2669 * respects the normal memory rules when dealing with a strv instead of
2670 * assuming that the passed-in array is the argv of the main function.
2672 * In particular, strings that are removed from the arguments list will
2673 * be freed using g_free().
2675 * On Windows, the strings are expected to be in UTF-8. This is in
2676 * contrast to g_option_context_parse() which expects them to be in the
2677 * system codepage, which is how they are passed as @argv to main().
2678 * See g_win32_get_command_line() for a solution.
2680 * This function is useful if you are trying to use #GOptionContext with
2683 * Returns: %TRUE if the parsing was successful,
2684 * %FALSE if an error occurred
2689 g_option_context_parse_strv (GOptionContext
*context
,
2696 context
->strv_mode
= TRUE
;
2697 argc
= g_strv_length (*arguments
);
2698 success
= g_option_context_parse (context
, &argc
, arguments
, error
);
2699 context
->strv_mode
= FALSE
;