命令行选项解析器
命令行选项解析器
GOption 命令行解析器旨在成为 popt 库的更简单的替代品。它支持如下例所示的短命令行选项和长命令行选项
testtreemodel -r 1 --max-size 20 --rand --display=:1.0 -vb -- file1 file2
此示例展示 GOption 命令行解析器的一些功能
- 选项可以是单个字母,前缀为单破折号。
- 多个短选项可以组合在单破折号之后。
- 长选项前缀为两个连续破折号。
- 选项可以附带一个额外参数,此参数可以是数字、字符串或文件名。对于长选项,可在选项名称后附加一个等号以及额外参数,这在额外参数以破折号开头时很有用,否则将被解释为另一个选项。
- 非选项参数作为剩余参数返回给应用程序。
- 仅由两个破折号组成的参数会关闭进一步解析,任何剩余参数(甚至以破折号开头的参数)都会作为剩余参数返回给应用程序。
GOption 的另一个重要功能是它可以自动生成格式良好的帮助输出。除非使用 g_option_context_set_help_enabled()
明确关闭帮助输出,否则 GOption 将识别 --help
、-?
、--help-all
和 --help-groupname
选项(其中 groupname
为 GOptionGroup
的名称)并向标准输出 stdout 写入类似于以下示例中所示的文本。
Usage:
testtreemodel [OPTION...] - test tree model performance
Help Options:
-h, --help Show help options
--help-all Show all help options
--help-gtk Show GTK Options
Application Options:
-r, --repeats=N Average over N repetitions
-m, --max-size=M Test up to 2^M items
--display=DISPLAY X display to use
-v, --verbose Be verbose
-b, --beep Beep when done
--rand Randomize the data
GOption 在 GOptionGroup
中对选项进行分组,这使得轻松合并来自多个来源的选项变得更加容易。这样做的目的是让应用程序从其使用的库中收集选项组,将这些选项组添加到其 GOptionContext
中,并通过对 g_option_context_parse()
的单次调用来解析所有选项。
如果声明选项的类型为字符串或文件名,则 GOption 会负责将选项转换为正确的编码;将以 UTF-8 形式返回字符串,将以 GLib 文件名编码形式返回文件名。请注意,这仅在使用 g_option_context_parse()
之前已调用 setlocale()
的情况下才能正常工作
以下是对 GOption 进行设置以解析上述示例命令行并生成示例帮助输出的完整示例。
static gint repeats = 2;
static gint max_size = 8;
static gboolean verbose = FALSE;
static gboolean beep = FALSE;
static gboolean randomize = FALSE;
static GOptionEntry entries[] =
{
{ "repeats", 'r', 0, G_OPTION_ARG_INT, &repeats, "Average over N repetitions", "N" },
{ "max-size", 'm', 0, G_OPTION_ARG_INT, &max_size, "Test up to 2^M items", "M" },
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL },
{ "beep", 'b', 0, G_OPTION_ARG_NONE, &beep, "Beep when done", NULL },
{ "rand", 0, 0, G_OPTION_ARG_NONE, &randomize, "Randomize the data", NULL },
G_OPTION_ENTRY_NULL
};
int
main (int argc, char *argv[])
{
GError *error = NULL;
GOptionContext *context;
context = g_option_context_new ("- test tree model performance");
g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
g_option_context_add_group (context, gtk_get_option_group (TRUE));
if (!g_option_context_parse (context, &argc, &argv, &error))
{
g_print ("option parsing failed: %s\n", error->message);
exit (1);
}
...
}
在 UNIX 系统上,传递给 main()
的 argv 没有特定编码,甚至其不同部分可能具有不同的编码。通常,正常参数和标志将采用当前语言环境,应将文件名视为不透明的字节字符串。因此,正确使用 G_OPTION_ARG_FILENAME
和 G_OPTION_ARG_STRING
是很重要的。
请注意,在 Windows 上,文件名确实有编码,但将 GOptionContext
与作为参数传递给 main()
的 argv 一起使用会导致程序只能接受来自系统代码页的字符的命令行参数。在尝试处理超出代码页范围的 Unicode 字符的文件名时,可能会导致问题。
要解决这个问题的方法是使用 g_win32_get_command_line()
和 g_option_context_parse_strv()
,后者将正确处理完整的 Unicode 文件名。如果您正在使用 GApplication
,那么此操作会自动为您执行。
以下示例显示如何直接使用 GOptionContext
以正确处理 Windows 上的 Unicode 文件名
int
main (int argc, char **argv)
{
GError *error = NULL;
GOptionContext *context;
gchar **args;
#ifdef G_OS_WIN32
args = g_win32_get_command_line ();
#else
args = g_strdupv (argv);
#endif
// set up context
if (!g_option_context_parse_strv (context, &args, &error))
{
// error happened
}
...
g_strfreev (args);
...
}