使い方って,流れを見た方が早いことって多いよね.
ということで,流れを紹介. というか,manそのまんまなんだけどね.
たぶん,スイッチのオプションを解析したあとに, フラッグなしの数字を処理した方がよいと思われる. つまり,poptGetNextOpt(optCon)が先で,poptGetArgが後.
実際に使ってみた例はこっち. ちょっと汚いけど,こんな感じで使うもんなのかな,といったもの.
#include <popt.h>
#include <stdio.h>
/* これつけた方がカッコイイ */
void usage(poptContext optCon, int exitcode, char *error, char *addl) {
poptPrintUsage(optCon, stderr, 0);
if (error) fprintf(stderr, "%s: %s0, error, addl);
exit(exitcode);
}
int main(int argc, char *argv[]) {
char c; /* used for argument parsing */
int i = 0; /* used for tracking options */
char *portname;
int speed = 0; /* used in argument parsing to set speed */
int raw = 0; /* raw mode? */
int j;
char buf[BUFSIZ+1];
poptContext optCon; /* context for parsing command-line options */
/* ここでオプションを設定 */
struct poptOption optionsTable[] = {
/*{ "longname", "shortname", argInfo, *arg, int val, description, argment description} */
{ "bps", 'b', POPT_ARG_INT, &speed, 0, "signaling rate in bits-per-second", "BPS" },
{ "crnl", 'c', 0, 0, 'c', "expand cr characters to cr/lf sequences" },
{ "hwflow", 'h', 0, 0, 'h', "use hardware (RTS/CTS) flow control" },
{ "noflow", 'n', 0, 0, 'n', "use no flow control" },
{ "raw", 'r', 0, &raw, 0, "don't perform any character conversions" },
{ "swflow", 's', 0, 0, 's', "use software (XON/XOF) flow control" } ,
POPT_AUTOHELP { NULL, 0, 0, NULL, 0 }
};
/* この場合,へルプはこんな風に表示される.
$ a.out --help
Usage: a.out [OPTIONS]*
-b, --bps=BPS signaling rate in bits-per-second
-c, --crnl expand cr characters to cr/lf sequences
-h, --hwflow use hardware (RTS/CTS) flow control
-n, --noflow use no flow control
-r, --raw don't perform any character conversions
-s, --swflow use software (XON/XOF) flow control
Help options
-?, --help Show this help message
--usage Display brief usage message
*/
optCon = poptGetContext(NULL, argc, argv, optionsTable, 0); /* オプションを読み込む */
poptSetOtherOptionHelp(optCon, "[OPTIONS]* <port>"); /* これをつけると,へルプのところに[OPTIONS]* がつく*/
if (argc < 2) {
poptPrintUsage(optCon, stderr, 0);
exit(1);
}
/* Now do options processing, get portname */
while ((c = poptGetNextOpt(optCon)) >= 0) {
switch (c) {
case 'c':
buf[i++] = 'c';
break;
case 'h':
buf[i++] = 'h';
break;
case 's':
buf[i++] = 's';
break;
case 'n':
buf[i++] = 'n';
break;
}
}
/* ここでは,数字は1つしかないので,単純に読み込む.
二つ以上ある場合は,
poptPeekArg(optCon)を利用したりして分岐する必要があるかも知れない */
portname = poptGetArg(optCon);
if((portname == NULL) || !(poptPeekArg(optCon) == NULL))
usage(optCon, 1, "Specify a single port", ".e.g., /dev/cua0");
if (c < -1) {
/* an error occurred during option processing */
fprintf(stderr, "%s: %s\n",
poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
poptStrerror(c));
return 1;
}
/* 結果出力 */
printf("Options chosen: ");
for(j = 0; j < i ; j++)
printf("-%c ", buf[j]);
if(raw) printf("-r ");
if(speed) printf("-b %d ", speed);
printf("\nPortname chosen: %s\n", portname);
/* これを忘れないこと.メモリリークが起きる(たぶん). */
poptFreeContext(optCon);
exit(0);
}