2010-04-24 5 views
4

GLib을 사용하여 일부 명령 행 옵션을 구문 분석합니다. 문제는 이러한 옵션 중 두 개를 필수로 설정하여 사용자가 도움말을 생략하면 프로그램이 도움말 화면으로 종료되도록하려는 것입니다.GLib에서 명령 행 옵션을 필수로 만드는 방법은 무엇입니까?

내 코드는 다음과 같습니다

내가) 명령 줄 g_option_context_parse에 이러한 매개 변수 중 하나 또는 모두를 (생략 여전히 성공하고 문제가되는 값 (라인 또는 열)이 여전히있는 경우

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; 
} 
- 1. 사용자가 명령 줄에서 두 옵션을 모두 전달하지 않으면 GLib이 구문 분석에 실패한다고 어떻게 말할 수 있습니까? 아마 나는 눈이 멀었지만 그 필드를 필수로 만들도록 GOptionEntry 데이터 구조에 넣을 수있는 플래그를 찾을 수 없었습니다.

물론 해당 변수 중 하나가 -1인지 확인할 수 있지만 사용자가 명령 줄에서이 값을 전달하면 값이 범위를 벗어날 경우 별도의 오류 메시지가 인쇄됩니다.

+0

어서, 그냥 "옵션"이라는 단어가 의미하는 바를 생각해보십시오. "필수 옵션"은 모순입니다. 옵션은 선택 사항입니다. 이것을 합법적 개념 인 "필수 인수"와 혼합했을 수 있습니다. 파이썬의 키워드 인수처럼 일종의 "명명 된 인수"를 원할 수도 있습니다. 유일한 이점은보다 많은 입력을 위해 임의의 순서로 전달할 수 있다는 것입니다 (스크립트의 경우 더 자세한 표시는 가독성을위한 이점입니다). 어쨌든, 종속성이 임의로 복잡 할 수 있기 때문에 파싱 단계 이후에 유효성 검사 만하는 것이 좋습니다. 어쨌든 "필수 옵션"은 오류입니다. –

답변

8

getopt도 마찬가지입니다. (구문 분석을 넘어서서) 인자의 온상을 점검하는 것은 여러분에게 달려 있습니다. 문제는 '필수'일 때 '필수'가 다른 주장이없는 경우에만 적용되는 경우가 많습니다.

예를 들어 에는 추가 인수가 필요하지 않으며, 마찬가지로 ./program --version에 대한 인수도 필요하지 않습니다. 파서 자체에서 "--foo 및 --bar가 필요하지 않으면 --version OR --help"논리를 사용하면 부풀어 오르고 지나치게 복잡해집니다.

인수가 구문 분석 된 후 무언가로 설정되었는지 확인하기 만하면 linecolumn의 값을 확인하기 만하면됩니다. main()의 혼란에 대해 걱정할 경우 해당 논리를 모두 기능 (예 : check_sanity())에 넣는 것은 전적으로 가능합니다.

요약하면보고있는 동작은 의도적으로 변경된 것으로 생각하지 않습니다. 구문 분석기가 실행 된 후에 두 변수 중 하나가 초기화 된 상태로 남아 있으면 사용자가 각 옵션을 지정하는 것을 잊었습니다.

1

GLib로는 불가능하며 문서와 소스 코드를 확인했습니다. 언급 된 단점에도 불구하고 기능 요청을 제출하거나 제안 된 해결 방법으로 살고 싶을 수 있습니다.

1

최근에 비슷한 문제가 발생하여 라고 생각합니다. 아직 알지 못하지만 2 가지 콜백으로 처리 할 수 ​​있습니다 . arg 처리 콜백은 구문 분석중인 arg가 입력되었음을 나타내려는 모든 작업을 수행합니다 (bitmask?, ...). 또한 구문 분석 된 값을 저장합니다 (아래의 gotcha를 참조하십시오).이 콜백을 GOptionArgFunc으로 설정하고 배열의 G_OPTION_ARG_CALLBACK 플래그를 사용하여이 콜백을 가리 킵니다.

포스트 파싱 콜백은 모든 필수 항목이 입력되었는지 확인합니다. 이 콜백을 GOptionParseFunc으로 설정하고 g_option_group_set_parse_hooks을 사용하여이 콜백을 가리 킵니다.

g_option_group_new을 사용하는 경우 두 개의 콜백 모두에서 사용할 user_data (주소를 비트 마스크에?, ...) 전달할 수 있습니다. g_option_context_add_main_entries 대신 g_option_group_add_entries 및 을 사용하면 GOptionContext과 관련된 그룹의 항목을 가져올 수 있습니다.

내가 지금까지 보았던 유일한 점은 입력란의 구문 분석 된 값을 실제로 설정하는 데 자신의 포인터 - 투 - 배열을 설정해야한다는 것입니다. 왜냐하면 GOptionEntryarg_data 필드가 arg를 가리키는 데 사용되기 때문입니다 콜백 함수.

관련 문제