static int a_seen;
static int b_seen;
+static int q_seen;
static const struct option long_options_required[] =
{
{ "alpha", no_argument, NULL, 'a' },
{ "beta", no_argument, &b_seen, 1 },
{ "prune", required_argument, NULL, 'p' },
- { "quetsche", required_argument, NULL, 'q' },
+ { "quetsche", required_argument, &q_seen, 1 },
+ { "xtremely-",no_argument, NULL, 1003 },
{ "xtra", no_argument, NULL, 1001 },
{ "xtreme", no_argument, NULL, 1002 },
{ "xtremely", no_argument, NULL, 1003 },
{ "alpha", no_argument, NULL, 'a' },
{ "beta", no_argument, &b_seen, 1 },
{ "prune", optional_argument, NULL, 'p' },
- { "quetsche", optional_argument, NULL, 'q' },
+ { "quetsche", optional_argument, &q_seen, 1 },
{ NULL, 0, NULL, 0 }
};
int *non_options_count, const char **non_options,
int *unrecognized)
{
- int option_index;
+ int option_index = -1;
int c;
opterr = 0;
+ q_seen = 0;
while ((c = getopt_long (argc, (char **) argv, options, long_options,
&option_index))
!= -1)
{
case 0:
/* An option with a non-NULL flag pointer was processed. */
+ if (q_seen)
+ *q_value = optarg;
break;
case 'a':
a_seen++;
ASSERT (options[0] == '-');
non_options[(*non_options_count)++] = optarg;
break;
+ case ':':
+ /* Must only happen with option ':' at the beginning. */
+ ASSERT (options[0] == ':'
+ || ((options[0] == '-' || options[0] == '+')
+ && options[1] == ':'));
+ /* fall through */
case '?':
*unrecognized = optopt;
break;
ASSERT (c == 1003);
}
- /* Test processing of boolean options. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ /* Check that -W handles unknown options. */
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "W;", long_options_required, &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 'W');
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wunknown";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "W;", long_options_required, &option_index);
+ /* glibc and BSD behave differently here, but for now, we allow
+ both behaviors since W support is not frequently used. */
+ if (c == '?')
+ {
+ ASSERT (optopt == 0);
+ ASSERT (optarg == NULL);
+ }
+ else
+ {
+ ASSERT (c == 'W');
+ ASSERT (strcmp (optarg, "unknown") == 0);
+ }
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc++] = "unknown";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long (argc, argv, "W;", long_options_required, &option_index);
+ /* glibc and BSD behave differently here, but for now, we allow
+ both behaviors since W support is not frequently used. */
+ if (c == '?')
+ {
+ ASSERT (optopt == 0);
+ ASSERT (optarg == NULL);
+ }
+ else
+ {
+ ASSERT (c == 'W');
+ ASSERT (strcmp (optarg, "unknown") == 0);
+ }
+ }
+
+ /* Test processing of boolean short options. */
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
ASSERT (unrecognized == 0);
ASSERT (optind == 2);
}
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
ASSERT (unrecognized == 0);
ASSERT (optind == 3);
}
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
ASSERT (unrecognized == 0);
ASSERT (optind == 2);
}
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
ASSERT (optind == 3);
}
- /* Test processing of options with arguments. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ /* Test processing of boolean long options. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--alpha";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--beta";
+ argv[argc++] = "--alpha";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--alpha";
+ argv[argc++] = "--beta";
+ argv[argc++] = "--alpha";
+ argv[argc++] = "--beta";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 2);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Test processing of boolean long options via -W. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Walpha";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abW;", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc++] = "beta";
+ argv[argc++] = "-W";
+ argv[argc++] = "alpha";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "aW;b", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Walpha";
+ argv[argc++] = "-Wbeta";
+ argv[argc++] = "-Walpha";
+ argv[argc++] = "-Wbeta";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "W;ab", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 2);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Test processing of short options with arguments. */
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
&non_options_count, non_options, &unrecognized);
ASSERT (a_seen == 0);
ASSERT (b_seen == 0);
- ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "-q";
+ argv[argc++] = "baz";
+ argv[argc++] = "-pfoo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Test processing of long options with arguments. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "--q";
+ argv[argc++] = "baz";
+ argv[argc++] = "--p=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 5);
+ }
+
+ /* Test processing of long options with arguments via -W. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wp=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:q:W;", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-W";
+ argv[argc++] = "p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p:W;q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 4);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-ab";
+ argv[argc++] = "-Wq";
+ argv[argc++] = "baz";
+ argv[argc++] = "-W";
+ argv[argc++] = "p=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "W;abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 1);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 6);
+ }
+
+ /* Test processing of short options with optional arguments. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-pfoo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-p";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+
+ /* Test processing of long options with optional arguments. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p=";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && *p_value == '\0');
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--p";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 1);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 3);
+ }
+
+ /* Test processing of long options with optional arguments via -W. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wp=foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::W;", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wp";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "p::q::W;", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ /* glibc bug http://sources.redhat.com/bugzilla/show_bug.cgi?id=11041 */
+ /* ASSERT (p_value == NULL); */
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 2);
+ }
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-Wp=";
+ argv[argc++] = "foo";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "W;p::q::", long_options_optional,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value != NULL && *p_value == '\0');
ASSERT (q_value == NULL);
ASSERT (non_options_count == 0);
ASSERT (unrecognized == 0);
ASSERT (optind == 2);
}
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
b_seen = 0;
argv[argc++] = "program";
- argv[argc++] = "-p";
+ argv[argc++] = "-W";
+ argv[argc++] = "p=";
argv[argc++] = "foo";
argv[argc++] = "bar";
argv[argc] = NULL;
optind = start;
- getopt_long_loop (argc, argv, "p:q:", long_options_required,
+ getopt_long_loop (argc, argv, "W;p::q::", long_options_optional,
&p_value, &q_value,
&non_options_count, non_options, &unrecognized);
ASSERT (a_seen == 0);
ASSERT (b_seen == 0);
- ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
+ ASSERT (p_value != NULL && *p_value == '\0');
ASSERT (q_value == NULL);
ASSERT (non_options_count == 0);
ASSERT (unrecognized == 0);
ASSERT (optind == 3);
}
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
b_seen = 0;
argv[argc++] = "program";
- argv[argc++] = "-ab";
- argv[argc++] = "-q";
- argv[argc++] = "baz";
- argv[argc++] = "-pfoo";
+ argv[argc++] = "-W";
+ argv[argc++] = "p";
+ argv[argc++] = "-a";
argv[argc++] = "bar";
argv[argc] = NULL;
optind = start;
- getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ getopt_long_loop (argc, argv, "W;abp::q::", long_options_optional,
&p_value, &q_value,
&non_options_count, non_options, &unrecognized);
ASSERT (a_seen == 1);
- ASSERT (b_seen == 1);
- ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
- ASSERT (q_value != NULL && strcmp (q_value, "baz") == 0);
+ ASSERT (b_seen == 0);
+ /* ASSERT (p_value == NULL); */
+ ASSERT (q_value == NULL);
ASSERT (non_options_count == 0);
ASSERT (unrecognized == 0);
- ASSERT (optind == 5);
+ ASSERT (optind == 4);
}
- /* Test processing of options with optional arguments. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ /* Check that invalid options are recognized. */
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
b_seen = 0;
argv[argc++] = "program";
- argv[argc++] = "-pfoo";
+ argv[argc++] = "-p";
+ argv[argc++] = "foo";
+ argv[argc++] = "-x";
+ argv[argc++] = "-a";
argv[argc++] = "bar";
argv[argc] = NULL;
optind = start;
- getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
&p_value, &q_value,
&non_options_count, non_options, &unrecognized);
- ASSERT (a_seen == 0);
+ ASSERT (a_seen == 1);
ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
ASSERT (q_value == NULL);
ASSERT (non_options_count == 0);
- ASSERT (unrecognized == 0);
- ASSERT (optind == 2);
+ ASSERT (unrecognized == 'x');
+ ASSERT (optind == 5);
}
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
argv[argc++] = "program";
argv[argc++] = "-p";
argv[argc++] = "foo";
+ argv[argc++] = "-:";
+ argv[argc++] = "-a";
argv[argc++] = "bar";
argv[argc] = NULL;
optind = start;
- getopt_long_loop (argc, argv, "p::q::", long_options_optional,
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
&p_value, &q_value,
&non_options_count, non_options, &unrecognized);
- ASSERT (a_seen == 0);
+ ASSERT (a_seen == 1);
ASSERT (b_seen == 0);
- ASSERT (p_value == NULL);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
ASSERT (q_value == NULL);
ASSERT (non_options_count == 0);
- ASSERT (unrecognized == 0);
- ASSERT (optind == 2);
+ ASSERT (unrecognized == ':');
+ ASSERT (optind == 5);
}
- for (start = OPTIND_MIN; start <= 1; start++)
+
+ /* Check that unexpected arguments are recognized. */
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
argv[argc++] = "program";
argv[argc++] = "-p";
- argv[argc++] = "-a";
+ argv[argc++] = "foo";
+ argv[argc++] = "--a=";
argv[argc++] = "bar";
argv[argc] = NULL;
optind = start;
- getopt_long_loop (argc, argv, "abp::q::", long_options_optional,
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
&p_value, &q_value,
&non_options_count, non_options, &unrecognized);
- ASSERT (a_seen == 1);
+ ASSERT (a_seen == 0);
ASSERT (b_seen == 0);
- ASSERT (p_value == NULL);
+ ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
ASSERT (q_value == NULL);
ASSERT (non_options_count == 0);
- ASSERT (unrecognized == 0);
- ASSERT (optind == 3);
+ ASSERT (unrecognized == 'a');
+ ASSERT (optind == 4);
}
-
- /* Check that invalid options are recognized. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
argv[argc++] = "program";
argv[argc++] = "-p";
argv[argc++] = "foo";
- argv[argc++] = "-x";
- argv[argc++] = "-a";
+ argv[argc++] = "--b=";
argv[argc++] = "bar";
argv[argc] = NULL;
optind = start;
getopt_long_loop (argc, argv, "abp:q:", long_options_required,
&p_value, &q_value,
&non_options_count, non_options, &unrecognized);
- ASSERT (a_seen == 1);
+ ASSERT (a_seen == 0);
ASSERT (b_seen == 0);
ASSERT (p_value != NULL && strcmp (p_value, "foo") == 0);
ASSERT (q_value == NULL);
ASSERT (non_options_count == 0);
- ASSERT (unrecognized == 'x');
- ASSERT (optind == 5);
+ /* When flag is non-zero, glibc sets optopt anyway, but BSD
+ leaves optopt unchanged. */
+ ASSERT (unrecognized == 1 || unrecognized == 0);
+ ASSERT (optind == 4);
}
/* Check that by default, non-options arguments are moved to the end. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
}
/* Check that '--' ends the argument processing. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
}
/* Check that the '-' flag causes non-options to be returned in order. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
}
/* Check that '--' ends the argument processing. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
}
/* Check that the '-' flag has to come first. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
/* Check that the '+' flag causes the first non-option to terminate the
loop. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
ASSERT (unrecognized == 0);
ASSERT (optind == 1);
}
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
}
/* Check that '--' ends the argument processing. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
}
/* Check that the '+' flag has to come first. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
{
int start;
+ /* Check that POSIXLY_CORRECT stops parsing the same as leading '+'. */
+ for (start = 0; start <= 1; start++)
+ {
+ const char *p_value = NULL;
+ const char *q_value = NULL;
+ int non_options_count = 0;
+ const char *non_options[10];
+ int unrecognized = 0;
+ int argc = 0;
+ const char *argv[10];
+ a_seen = 0;
+ b_seen = 0;
+
+ argv[argc++] = "program";
+ argv[argc++] = "donald";
+ argv[argc++] = "-p";
+ argv[argc++] = "billy";
+ argv[argc++] = "duck";
+ argv[argc++] = "-a";
+ argv[argc++] = "bar";
+ argv[argc] = NULL;
+ optind = start;
+ getopt_long_loop (argc, argv, "abp:q:", long_options_required,
+ &p_value, &q_value,
+ &non_options_count, non_options, &unrecognized);
+ ASSERT (strcmp (argv[0], "program") == 0);
+ ASSERT (strcmp (argv[1], "donald") == 0);
+ ASSERT (strcmp (argv[2], "-p") == 0);
+ ASSERT (strcmp (argv[3], "billy") == 0);
+ ASSERT (strcmp (argv[4], "duck") == 0);
+ ASSERT (strcmp (argv[5], "-a") == 0);
+ ASSERT (strcmp (argv[6], "bar") == 0);
+ ASSERT (argv[7] == NULL);
+ ASSERT (a_seen == 0);
+ ASSERT (b_seen == 0);
+ ASSERT (p_value == NULL);
+ ASSERT (q_value == NULL);
+ ASSERT (non_options_count == 0);
+ ASSERT (unrecognized == 0);
+ ASSERT (optind == 1);
+ }
+
/* Check that POSIXLY_CORRECT doesn't change optional arguments. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
}
/* Check that leading - still sees options after non-options. */
- for (start = OPTIND_MIN; start <= 1; start++)
+ for (start = 0; start <= 1; start++)
{
const char *p_value = NULL;
const char *q_value = NULL;
ASSERT (optind == 4);
}
}
+
+/* Reduce casting, so we can use string literals elsewhere.
+ getopt_long_only takes an array of char*, but luckily does not
+ modify those elements, so we can pass const char*. */
+static int
+do_getopt_long_only (int argc, const char **argv, const char *shortopts,
+ const struct option *longopts, int *longind)
+{
+ return getopt_long_only (argc, (char **) argv, shortopts, longopts, longind);
+}
+
+static void
+test_getopt_long_only (void)
+{
+ /* Test disambiguation of options. */
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-x";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "ab", long_options_required,
+ &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-x";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == 'x');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--x";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-b";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ b_seen = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == 'b');
+ ASSERT (b_seen == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "--b";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ b_seen = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == 0);
+ ASSERT (b_seen == 1);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xt";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "ab", long_options_required,
+ &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xt";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx", long_options_required,
+ &option_index);
+ ASSERT (c == '?');
+ ASSERT (optopt == 0);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtra";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "ab", long_options_required,
+ &option_index);
+ ASSERT (c == 1001);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtreme";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx:", long_options_required,
+ &option_index);
+ ASSERT (c == 1002);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtremel";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "ab", long_options_required,
+ &option_index);
+ /* glibc bug http://sources.redhat.com/bugzilla/show_bug.cgi?id=11041 */
+ /* ASSERT (c == 1003); */
+ ASSERT (optind == 2);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtremel";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx::", long_options_required,
+ &option_index);
+ /* glibc bug http://sources.redhat.com/bugzilla/show_bug.cgi?id=11041 */
+ /* ASSERT (c == 1003); */
+ ASSERT (optind == 2);
+ ASSERT (optarg == NULL);
+ }
+ {
+ int argc = 0;
+ const char *argv[10];
+ int option_index;
+ int c;
+
+ argv[argc++] = "program";
+ argv[argc++] = "-xtras";
+ argv[argc] = NULL;
+ optind = 1;
+ opterr = 0;
+ c = do_getopt_long_only (argc, argv, "abx::", long_options_required,
+ &option_index);
+ ASSERT (c == 'x');
+ ASSERT (strcmp (optarg, "tras") == 0);
+ }
+}