2018/02/15

[c/c++]getopt_long()のlongindexが返るのは戻り値が0のときだけ?→ときだけだった

(2018/02/17更新)

ずっと先延ばしにしてきた、getopt_long()の勉強をすることにした。

組み込みだと、引数とか設定できないじゃないか。
値はNVに保存して、起動時に読み出す。

そういう生活をしていたので、Linuxでツールを作るときも、設定ファイルを読ませるようにしているのだが、これの評判が悪い。。
「ファイルでやる意味が分からん」とまでいわれてしまい、しぶしぶ引数を列挙するタイプで対応していた。

が、似たような機能を同じツールで実現したいことが多くなり、引数で見分ける必要性が出てきた。
しぶしぶgetopt()で対応していたのだが、さらに引数が増え、使える文字が減り、自分でも訳がわからなくなってきたのだ。


以上、自分の中で、どうしてもやらないといけないという動機づけを行う作業でした。


最初に見たのが、こちら。

getopt_long関数の利用 - コマンドラインオプションの処理 - 碧色工房

まずは動かして考えよう、とWindowsのWSLでやってみたのだが、なんか、ときどきSegmentation Faultが発生する。


よくわからんので、こちらのサンプルも動かしてみた。

Man page of GETOPT

こちらは動いたので見比べたのだが、Man pageの方はlongindexを初期化しているし、戻り値が0のときにしかlongindexを使っていない。
最初の方は未初期化で、getopt_long()に任せている。


しかし、説明文を読む限りでは、longindexをNULL以外で指定しておけば、正常な場合はインデックス値が戻ってきそうである。
うーん、WSLの不具合かなぁ。。。


2018/02/17

Azureで動かしているUbuntuで確認したが、やはり同じ動作になった。
WSLよ、疑って済まん。。。


よく読めば、こちらのサイトにもちゃんと書かれていた。
getopt_long関数の利用 - コマンドラインオプションの処理 - 碧色工房


manとしては、こう書かれている。

longindex は、NULL でなければ、 長いオプションのインデックスを longopts からの相対位置として保持している変数へのポインターとなる。

つまり、「長いオプションのインデックスを」だから、短いオプションのときには更新しない、ということか。
読み取るのが難しいですよ。。。


長いオプションかどうか見分けたい場合は、longindexを-1などに初期化してからgetopt_long()を呼び出して、更新されたかどうか確認すればよいのかな。
そういうシーンは少ない気がするので、私の場合はNULLにしてしまうだろう。


せっかくなので、オプションの使い方で気になるところも見ておこう。
「値付きのオプションに、イコールを付けてよいのかどうか」問題だ。
ソースファイルは、工房さんのサンプルをそのまま使っている。

$ ./tst --clear 100
c = 1, 100


$ ./tst --clear=100
c = 1, 100


$ ./tst -c=100
c = 1, =100


$ ./tst -c 100
c = 1, 100


./tst -c100
c = 1, 100

あー、こうなるんだ。

長いオプションの方はイコールを付けて値、短いオプションの方はスペースを入れるか入れないかで値、という使い方が一般的なようだ。
短いオプションでイコールを使ってもうまくいくやつがあるけど、あれはアプリ側で取り除いてるのかな。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。