5

我使用 GLib 来解析一些命令行选项。问题是我想让其中两个选项成为强制性选项,以便如果用户忽略它们,程序会在帮助屏幕上终止。

我的代码如下所示:

static gint line   = -1;
static gint column = -1;

static GOptionEntry options[] =
{
    {"line", 'l', 0, G_OPTION_ARG_INT, &line, "The line", "L"},
    {"column", 'c', 0, G_OPTION_ARG_INT, &column, "The column", "C"},
    {NULL}
};

...

int main(int argc, char** argv)
{
    GError *error = NULL;
    GOptionContext *context;

    context = g_option_context_new ("- test");
    g_option_context_add_main_entries (context, options, NULL);

    if (!g_option_context_parse(context, &argc, &argv, &error))
    {
        usage(error->message, context);
    }

    ...

    return 0;
}

如果我在命令行上省略了这些参数之一或两者, g_option_context_parse() 仍然成功并且有问题的值(行和或列)仍然是-1。如果用户没有在命令行上传递这两个选项,我如何告诉 GLib 解析失败?也许我只是瞎了眼,但我找不到可以放入我的 GOptionEntry 数据结构中的标志来告诉它使这些字段成为强制性字段。

当然,我可以检查其中一个变量是否仍然是 -1,但是用户可能只是在命令行上传递了这个值,如果值超出范围,我想打印一条单独的错误消息。

4

3 回答 3

8

由您来检查参数的健全性(除了解析之外),这getopt也适用。问题是,当使事情成为“强制性”时,您经常会遇到“强制性”仅适用于没有其他论点的情况。

例如,./program --help应该不需要额外的参数,对于./program --version. 将“需要--foo 和--bar 除非--version 或--help”的逻辑放在解析器本身中会导致膨胀和过于复杂。

您只需检查参数的值linecolumn解析后的值,以确保它们被设置为某个值。check_sanity()如果您担心main().

总之,您所看到的行为是设计使然,我认为它不会改变。如果任何一个变量在解析器运行后仍然保持初始化状态,则用户忘记指定相应的选项。

于 2010-04-24T14:19:09.443 回答
2

用GLib是不可能实现的,我查了文档和源代码。尽管存在上述缺点,您可能希望提交功能请求,和/或接受您提出的解决方法。

于 2010-04-24T14:10:45.023 回答
2

我最近遇到了类似的问题,我认为(还不确定,但看起来可行)它可以通过 2 个回调来实现。arg 处理回调将执行任何您想要指示正在解析的 arg 已输入的操作(位掩码?,...)。它还将存储解析的值(请参见下面的问题。)将此回调设置为 a并使用标志在数组中GOptionArgFunc指向它。GOptionEntryG_OPTION_ARG_CALLBACK

解析后回调将检查是否已输入所有要求。将此回调设置为 aGOptionParseFunc并使用g_option_group_set_parse_hooks.

如果你使用g_option_group_new你可以传递它user_data(地址到你的位掩码?,...)在两个回调中使用。使用g_option_group_add_entriesandg_option_context_set_main_group而不是g_option_context_add_main_entries获取与GOptionContext.

到目前为止,我看到的唯一问题是您必须设置自己的指向条目数组以用于实际设置条目的解析值,因为该GOptionEntry arg_data字段将用于指向 arg 回调函数。

于 2015-07-05T18:17:42.070 回答