2010-04-24 63 views
4

我使用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,但用戶可能已經在命令行上傳遞了此值,並且如果值超出範圍,我想打印單獨的錯誤消息。

+0

來吧,只要想一想「選項」這個詞的意思。 「強制性選擇」是一個矛盾。選項是可選的。你可能把它與「強制性論證」混在一起,這是一個合理的概念。您可能想要有一種「命名參數」,如Python的關鍵字參數。唯一的好處是可以按任意順序傳遞它們,以便進行更多類型的輸入(可能在腳本中使用更多的冗長是可讀性的優點)。無論如何,在解析階段之後驗證它是有意義的,因爲依賴關係可以是任意複雜的。無論如何,「所需選項」是一個謬誤。 – 2014-06-23 11:28:23

回答

8

這是由你來檢查論證的理智(超越解析),這也是爲getopt以及。問題是,當把事情做成強制性的時候,你會經常遇到只有在沒有其他論據的情況下才會使用「強制性」的情況。

例如,./program --help應該不需要額外的參數,對於./program --version也是如此。將「require --foo和--bar,除非--version OR --help」的邏輯放在解析器本身中將會過度膨脹和過於複雜。

您只需檢查參數解析後的值linecolumn以確保它們被設置爲某些值。如果您擔心main()中出現混亂,則完全可以將所有這些邏輯放入函數中(例如check_sanity())。

總之,你看到的行爲是設計的,我不認爲它可能會改變。如果任何變量在解析器運行後保持初始化狀態,用戶忘記指定相應的選項。

1

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

1

我最近碰到類似的問題,並且我認爲(現在還不確定,但看起來可行),它可以通過2個回調來實現。 arg處理回調函數可以做任何你想表示被解析的參數已經被輸入(位掩碼?,...)。它還會存儲解析的值(請參閱下面的gotcha)。將此回調設置爲GOptionArgFunc,並使用G_OPTION_ARG_CALLBACK標誌指向GOptionEntry陣列中的回調。

後解析回調將檢查是否已輸入所有必需項。將此回調設置爲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相關聯的組條目。

我看到迄今爲止唯一的小問題,就是你必須建立自己的指針到進入陣列中使用的實際設置條目解析值,因爲GOptionEntryarg_data場將被用來指向ARG回調函數。