int getsubopt(char **optionp, char * const *tokens, char **valuep);
glibc 向けの機能検査マクロの要件 (feature_test_macros(7) 参照):
getsubopt():
ro,name=xyz
tokens 引数はトークンへのポインターの配列へのポインターで、 配列は NULL で終端される。 getsubopt() はこのトークンを optionp 内で探す。 それぞれのトークンは、NULL 終端された 1文字以上の文字列で、 他のトークンと区別できる必要がある。 また、等号とカンマを含んではならない。
getsubopt() は呼び出されるたびに、 optionp 中の次の未処理のサブオプションの情報を返す。 サブオプション内に等号があった場合、最初の等号は そのサブオプションの名前と値の区切りと解釈される。 区切りから次のカンマ (最後のサブオプションの場合、文字列の末尾) までが、サブオプションの値となる。 サブオプションの名前が tokens 内の名前と一致し、値を表す文字列が見つかった場合、 getsubopt() は *valuep を値を表す文字列のアドレスに設定する。 optionp 中の最初のカンマはヌルバイトで上書きされる。そのため、 *valuep はそのサブオプションの「値の文字列」そのものとなる。
サブオプションが認識されたが、値を表す文字列が見つからなかった場合、 *valuep は NULL に設定される。
getsubopt() が返る時、 optionp は次のサブオプションを指している。 ちょうど最後のサブオプションが処理された場合は、 文字列末尾のヌルバイト ('\0') を指している。
*optionp は変更されるので、 getsubopt() を呼び出す前の最初のサブオプションは getsubopt() を呼び出し後のサブオプションと必ずしも同じとは限らない。
インターフェース | 属性 | 値 |
getsubopt() | Thread safety | MT-Safe |
#define _XOPEN_SOURCE 500 #include <stdlib.h> #include <assert.h> #include <stdio.h>
int
main(int argc, char **argv)
{
enum {
RO_OPT = 0,
RW_OPT,
NAME_OPT
};
char *const token[] = {
[RO_OPT] = "ro",
[RW_OPT] = "rw",
[NAME_OPT] = "name",
NULL
};
char *subopts;
char *value;
int opt;
int readonly = 0;
int readwrite = 0;
char *name = NULL;
int errfnd = 0;
while ((opt = getopt(argc, argv, "o:")) != -1) {
switch (opt) {
case 'o':
subopts = optarg;
while (*subopts != '\0' && !errfnd) {
switch (getsubopt(&subopts, token, &value)) {
case RO_OPT:
readonly = 1;
break;
case RW_OPT:
readwrite = 1;
break;
case NAME_OPT:
if (value == NULL) {
fprintf(stderr, "Missing value for "
"suboption '%s'\n", token[NAME_OPT]);
errfnd = 1;
continue;
}
name = value;
break;
default:
fprintf(stderr, "No match found "
"for token: /%s/\n", value);
errfnd = 1;
break;
}
}
if (readwrite && readonly) {
fprintf(stderr, "Only one of '%s' and '%s' can be "
"specified\n", token[RO_OPT], token[RW_OPT]);
errfnd = 1;
}
break;
default:
errfnd = 1;
}
}
if (errfnd || argc == 1) {
fprintf(stderr, "\nUsage: %s -o <suboptstring>\n", argv[0]);
fprintf(stderr, "suboptions are 'ro', 'rw', "
"and 'name=<value>'\n");
exit(EXIT_FAILURE);
}
/* Remainder of program... */