簡體   English   中英

如何使用GLib強制命令行選項?

[英]How to make command-line options mandatory with GLib?

我使用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但是用戶可能只是在命令行上傳遞了這個值,如果值超出范圍,我想打印一個單獨的錯誤消息。

由你來檢查參數的健全性(除了解析之外),這也適用於getopt 問題是,當使事情“強制性”時,您經常會遇到“強制性”僅在沒有其他參數的情況下適用的情況。

例如,。/ ./program --help應該不需要額外的參數,同樣適用於./program --version 在解析器本身中使用“require --foo and --bar除非--version OR --help”的邏輯將與膨脹和過度復雜相關。

您只需在解析參數后檢查linecolumn的值,以確保它們已設置為某些值。 如果您擔心main()混亂,完全可以將所有邏輯放入函數(例如check_sanity() main()

總之,您所看到的行為是設計的,我不認為它可能會改變。 如果在解析器運行后初始化任一變量,則用戶忘記指定相應的選項。

用GLib實現是不可能的,我檢查了文檔和源代碼。 盡管存在上述缺陷,您可能希望提交功能請求,和/或與您提議的解決方法一起使用。

我最近遇到了類似的問題, 我認為 (目前還不確定,但看起來可行)這可以通過2次回調來實現。 arg處理回調會做任何你想要表明已經輸入的arg(bitmask?,...)。 它還會存儲解析后的值(參見下面的問題。)將此回調設置為GOptionArgFunc並使用G_OPTION_ARG_CALLBACK標志指向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回調函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM