如何使用GLib强制命令行选项?

时间:2010-04-24 13:36:27

标签: c glib optional-parameters

我使用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但是用户可能只是在命令行上传递了这个值,如果值超出范围,我想打印一个单独的错误消息。 / p>

3 个答案:

答案 0 :(得分:9)

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

例如,./program --help应该不需要额外的参数,同样适用于./program --version。在解析器本身中使用“require --foo and --bar除非--version OR --help”的逻辑将会出现膨胀和过度复杂的情况。

在解析参数后,您只需检查linecolumn的值,以确保它们已设置为某些内容。如果您担心check_sanity()中的混乱,完全有可能将所有逻辑放入函数(例如main())。

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

答案 1 :(得分:2)

使用GLib无法实现,我检查了文档和源代码。尽管存在上述缺陷,您可能希望提交功能请求,和/或与您提议的解决方法一起使用。

答案 2 :(得分:2)

我最近遇到了类似的问题,我认为(暂时还不知道,但看起来可行)它可以通过2次回调来实现。 arg处理回调会做任何你想要表明已经输入的arg(bitmask?,...)。它还会存储已解析的值(请参阅下面的问题。)将此回调设置为GOptionArgFunc,并使用GOptionEntry标记指向G_OPTION_ARG_CALLBACK数组中的回调。

解析后回调将检查是否已输入所有必需项。将此回调设置为GOptionParseFunc,并使用g_option_group_set_parse_hooks指向该回调。

如果您使用g_option_group_new,可以将user_data(地址转换为您的位掩码?,...)传递给两个回调。使用g_option_group_add_entriesg_option_context_set_main_group代替g_option_context_add_main_entries来获取与GOptionContext相关联的群组条目。

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