マニュアルページがこれらの詳細の真上にあることは間違いありませんが、ソースコードから十分なヒントを収集できます。たとえば、glibc-xyz / posix/getopt.cのglibcの実装_getopt_internal_r
です。(おそらく、それがこのGNU拡張関数の唯一の興味深い実装ですか?)
そのコードは、誤ったlongオプションに遭遇すると、0に設定されます。これは、間違いなく非NULであるoptopt
場合に、このケースを誤ったshortオプションと区別するのに役立つと思います。optopt
opterr != 0
ほとんどの場合、誤ったlongオプションをとして出力するときに生成されるエラーメッセージargv[optind]
と、後のコード(常にまたは-控えめに-少なくともほとんど)は、後でoptind
戻る前に増分します。
したがって、このプログラムを検討してください。
#include <getopt.h>
#include <stdio.h>
int main(int argc, char **argv) {
struct option longopts[] = {
{ "foo", no_argument, NULL, 'F' },
{ NULL, 0, NULL, 0 }
};
int c;
do {
int curind = optind;
c = getopt_long(argc, argv, "f", longopts, NULL);
switch (c) {
case 'f': printf("-f\n"); break;
case 'F': printf("--foo\n"); break;
case '?':
if (optopt) printf("bad short opt '%c'\n", optopt);
else printf("bad long opt \"%s\"\n", argv[curind]);
break;
case -1:
break;
default:
printf("returned %d\n", c);
break;
}
} while (c != -1);
return 0;
}
$ ./longopt -f -x --bar --foo
-f
./longopt:無効なオプション-'x'
bad short opt'x'
./longopt:認識されないオプション'--bar'
bad long opt "-バー」
--foo
したがって、これらの場合、のpre- getopt_long
valueをキャッシュするoptind
ことにより、メッセージと同じ悪いオプションを簡単に出力できopterr
ます。
__nextchar
glibc実装が(「認識されないオプション」の場合)ではなく独自に使用することargv[optind]
は検討に値するため、これはすべての場合に完全に正しいとは限りませんが、開始するには十分なはずです。
optind
との繰り返しの呼び出しとの関係を注意深く考えるgetopt_long
と、印刷argv[cached_optind]
はかなり安全になると思います。 optopt
短いオプションの場合、単語内のどの文字が問題であるかを知る必要があるために存在しますが、長いオプションの場合、問題は現在の単語全体です(形式のオプション引数をモジュロで削除します=param
)。そして、現在の単語はgetopt_long
、(着信)optind
値で見ている単語です。
optopt = 0
ドキュメントに書かれた保証がない場合でも、私はその振る舞いを利用することについてはやや楽観的ではありません。