示例#1
0
int main(int argc, char *argv[])
{
	const char *myname = argv[0];

	plan_tests(37);

	/* Simple short arg.*/
	opt_register_noarg("-a", test_noarg, NULL, "All");
	opt_register_early_noarg("-b", test_noarg, NULL, "All");

	/* Early parsing doesn't mangle. */
	ok1(parse_early_args(&argc, &argv, "-a", NULL));
	ok1(argc == 2);
	ok1(argv[0] == myname);
	ok1(strcmp(argv[1], "-a") == 0);
	ok1(argv[2] == NULL);
	ok1(test_cb_called == 0);

	/* ... even if it processes arg. */
	ok1(parse_early_args(&argc, &argv, "-b", NULL));
	ok1(argc == 2);
	ok1(argv[0] == myname);
	ok1(strcmp(argv[1], "-b") == 0);
	ok1(argv[2] == NULL);
	ok1(test_cb_called == 1);

	ok1(parse_early_args(&argc, &argv, "-ab", NULL));
	ok1(argc == 2);
	ok1(argv[0] == myname);
	ok1(strcmp(argv[1], "-ab") == 0);
	ok1(argv[2] == NULL);
	ok1(test_cb_called == 2);

	ok1(parse_args(&argc, &argv, "-ab", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 3);

	opt_register_table(some_early_table, "Some early args");
	ok1(parse_early_args(&argc, &argv, "--verbose", "-dddd", "-h", NULL));
	ok1(argc == 4);
	ok1(argv[0] == myname);
	ok1(strcmp(argv[1], "--verbose") == 0);
	ok1(strcmp(argv[2], "-dddd") == 0);
	ok1(strcmp(argv[3], "-h") == 0);
	ok1(argv[4] == NULL);
	ok1(test_cb_called == 5);

	ok1(parse_args(&argc, &argv, "--verbose", "-d", "ddd", "-h", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 6);

	/* parse_args allocates argv */
	free(argv);
	return exit_status();
}
示例#2
0
文件: irvm.c 项目: pablooliveira/irvm
/* Main: parse arguments and call IRVM entry function */
int
main (int argc, char ** argv)
{
  opt_register_table (opts, NULL);
  if (!opt_parse (&argc, argv, opt_log_stderr))
    exit (1);

  if (argc != 2)
    opt_usage_and_exit ("[OPTIONS] INPUT-FILE");
  input_fn = argv[1];
  opt_free_table ();

  if (!(yyin = fopen (input_fn, "r")))
    err (1, "could not open %s", input_fn);

  irvm ();

  return 0;
}
示例#3
0
文件: opt.c 项目: amboar/iviewiir
void opt_register_table(const struct opt_table entry[], const char *desc)
{
	unsigned int i, start = opt_count;

	if (desc) {
		struct opt_table heading = OPT_SUBTABLE(NULL, desc);
		add_opt(&heading);
	}
	for (i = 0; entry[i].type != OPT_END; i++) {
		if (entry[i].type == OPT_SUBTABLE)
			opt_register_table(subtable_of(&entry[i]),
					   entry[i].desc);
		else {
			check_opt(&entry[i]);
			add_opt(&entry[i]);
		}
	}
	/* We store the table length in arg ptr. */
	if (desc)
		opt_table[start].arg = (void *)(intptr_t)(opt_count - start);
}
示例#4
0
int main(int argc, char **argv)
{
	char errbuf[PCAP_ERRBUF_SIZE];
	pcap_t *pcap_src = NULL;

	opt_register_table(opts, NULL);

	if (!opt_parse(&argc, argv, opt_log_stderr))
		return 1;

	if (!g_ifc_name && !g_file_name)
		return err_ret("No packet source specified\n");
	if (g_ifc_name && g_file_name)
		return err_ret("Both file and interface source specified\n");

	if (g_ifc_name)
		pcap_src = pcap_open_live(g_ifc_name, PCAP_SNAPLEN_ALL,
					  1, -1, errbuf);
	else if (g_file_name)
		pcap_src = pcap_open_offline(g_file_name, errbuf);

	if (!pcap_src) {
		fprintf(stderr, "Couldn't open packet source: %s\n", errbuf);
		return 1;
	}

	pcap_loop(pcap_src, PCAP_CNT_INF, packet_cb, NULL);

	pcap_close(pcap_src);

	if (g_dump)
		dist_dump(dist1, dist2, dist_min);

	if (g_hm)
		hm_dump();

	return 0;
}
示例#5
0
int main(int argc, char **argv) {
    static bool show_series = false, show_all = false, use_cache = true;
    static int i_sid = 0;
    static char usage_str[] = "[SID[:PID]]";
    static struct opt_table opts[] = {
        OPT_WITH_ARG("--items-list|-i", opt_set_intval, NULL, &i_sid,
                "List episodes in a series. Requires a SID as a parameter."),
        OPT_WITHOUT_ARG("--series-list|-s", opt_set_bool, &show_series,
                "List the series available. The first element is the SID."),
        OPT_WITHOUT_ARG("--all|-a", opt_set_bool, &show_all,
                "List all items in all non-empty series."),
        OPT_WITHOUT_ARG("--force|-f", opt_set_invbool, &use_cache,
                "Force bypass the cached metadata."),
        OPT_WITHOUT_ARG("--help|-h", opt_usage_and_exit,
                usage_str, "Show this message."),
        OPT_ENDTABLE
    };
    opt_register_table(opts, NULL);
    if(!opt_parse(&argc, argv, opt_log_stderr)) {
        /* opt_parse will print an error to stderr. */
        exit(1);
    }
    if (!show_all && !show_series && !i_sid && (argc == 1)) {
        opt_usage_and_exit(usage_str);
    }

    struct iv_series *index;
    struct iv_config *config;
    int return_val = 0;
    cache_dir = xdg_user_dir_lookup_with_fallback("CACHE", "/tmp");
    if(NULL == (config = iviewiir_configure())) {
        fprintf(stderr, "Couldn't configure iviewiir, exiting\n");
        return 1;
    }
    int index_len = iviewiir_index(config, &index);
    if(0 >= index_len) {
        fprintf(stderr, "No items in index, exiting\n");
        return_val = 1;
        goto config_cleanup;
    }
    /* Check if they want everything listed */
    if(show_all) {
        list_all(config, index, index_len);
        return_val = 0;
        goto index_cleanup;
    }
    /* Check if they wanted a series list. */
    if(show_series) {
        int i;
        for(i=0; i<index_len; i++) {
            /* Heuristic to trim out empty series. */
            if((int)9e6 < index[i].id) {
                continue;
            }
            printf("%d - %s\n", index[i].id, index[i].title);
        }
        return_val = 0;
        goto index_cleanup;
    }
    /* Check if they want an episode list. */
    if(i_sid) {
        return_val = list_items(config, index, index_len, i_sid);
        goto index_cleanup;
    }
    /* If we've reached here and there are no arguments, print help message. */
    if (argc == 1) {
        opt_usage_and_exit(usage_str);
    }
    /* Otherwise, if they supplied a SID or SID:PID tuple, download the PID */
    int i = 1;
    while(i < argc) {
        if(NULL != strchr(argv[i], ':')) {
            // SID:PID
            const unsigned long sid = strtoul(strtok(argv[i], ":"), NULL, 10);
            const unsigned int pid = strtoul(strtok(NULL, ":"), NULL, 10);
            return_val += download_item(config, index, index_len, sid, pid);
        } else {
            // Check if it's a valid SID
            const unsigned int sid = strtoul(argv[i], NULL, 10);
            struct iv_episode *items;
            // Fetch episode lists for the SID
            debug("sid: %d\n", sid);
            int series_index;
            if(-1 == (series_index =
                        iv_find_series(sid, index, index_len, NULL))) {
                printf("No such series");
                return_val += 1;
                continue;
            }
            // Fetch items in series
            ssize_t items_len =
                iv_easy_series(config, &index[series_index], &items);
            if(1 > items_len) {
                printf("No items in series.\n");
                return_val += 1;
                continue;
            }
            for(i=0; i<items_len; i++) {
                return_val += download_item(config, index, index_len, sid,
                        items[i].id);
            }
            iv_destroy_series(items, items_len);
        }
        i++;
    }
index_cleanup:
    iv_destroy_index(index, index_len);
config_cleanup:
    iv_destroy_config(config);
    free(cache_dir);
    return return_val;
}
示例#6
0
/* Test iterators. */
int main(int argc, char *argv[])
{
	unsigned j, i, len = 0;
	const char *p;

	plan_tests(37 * 2);
	for (j = 0; j < 2; j ++) {
		reset_options();
		/* Giving subtable a title makes an extra entry! */
		opt_register_table(subtables, j == 0 ? NULL : "subtable");

		p = first_lopt(&i, &len);
		ok1(i == j + 0);
		ok1(len == 3);
		ok1(strncmp(p, "jjj", len) == 0);
		p = next_lopt(p, &i, &len);
		ok1(i == j + 0);
		ok1(len == 3);
		ok1(strncmp(p, "lll", len) == 0);
		p = next_lopt(p, &i, &len);
		ok1(i == j + 1);
		ok1(len == 3);
		ok1(strncmp(p, "mmm", len) == 0);
		p = next_lopt(p, &i, &len);
		ok1(i == j + 5);
		ok1(len == 3);
		ok1(strncmp(p, "ddd", len) == 0);
		p = next_lopt(p, &i, &len);
		ok1(i == j + 6);
		ok1(len == 3);
		ok1(strncmp(p, "eee", len) == 0);
		p = next_lopt(p, &i, &len);
		ok1(i == j + 7);
		ok1(len == 3);
		ok1(strncmp(p, "ggg", len) == 0);
		p = next_lopt(p, &i, &len);
		ok1(i == j + 8);
		ok1(len == 3);
		ok1(strncmp(p, "hhh", len) == 0);
		p = next_lopt(p, &i, &len);
		ok1(!p);

		p = first_sopt(&i);
		ok1(i == j + 0);
		ok1(*p == 'j');
		p = next_sopt(p, &i);
		ok1(i == j + 0);
		ok1(*p == 'l');
		p = next_sopt(p, &i);
		ok1(i == j + 1);
		ok1(*p == 'm');
		p = next_sopt(p, &i);
		ok1(i == j + 2);
		ok1(*p == 'a');
		p = next_sopt(p, &i);
		ok1(i == j + 3);
		ok1(*p == 'b');
		p = next_sopt(p, &i);
		ok1(i == j + 7);
		ok1(*p == 'g');
		p = next_sopt(p, &i);
		ok1(i == j + 8);
		ok1(*p == 'h');
		p = next_sopt(p, &i);
		ok1(!p);
	}

	return exit_status();
}
int
main(int argc, char *argv[]){
  opt_register_table(options, NULL);
  if (!opt_parse(&argc, argv, opt_log_stderr)){
    exit(1);
  }
  if (argc == 1){
    DEBUG("No text files to evaluate!");
    opt_usage_and_exit(argv[0]);
  }
  DEBUG("given %d arguments", argc - 1);

  RecurNN *net = rnn_load_net(opt_filename);
  RnnCharAlphabet *alphabet = rnn_char_new_alphabet_from_net(net);
  init_rand64_maybe_randomly(&net->rng, -1);

  int len = 0;
  int count = 0;

  if (opt_min_length <= opt_ignore_start){
    DEBUG("hey! --min-length=%d <= --ignore-start=%d! Fixing.. now its %d.",
        opt_min_length, opt_ignore_start, opt_ignore_start + 1);
    opt_min_length = opt_ignore_start + 1;
  }
  float sum[net->output_size];
  float sumsq[net->output_size];
  float mean[net->output_size];
  float stddev[net->output_size];

  for (int i = 1; i < argc; i++){
    const char *filename = argv[i];
    u8* text = rnn_char_load_new_encoded_text(filename, alphabet, &len, 3);


    if (len >= opt_min_length){
      memset(sum, 0, net->output_size * sizeof(float));
      memset(sumsq, 0, net->output_size * sizeof(float));
      int j, k;
      for (j = 0; j < opt_ignore_start; j++){
        one_hot_opinion(net, text[j], 0);
      }
      for (j = opt_ignore_start; j < len; j++){
        float *raw = one_hot_opinion(net, text[j], 0);
        float *answer = mean;
        softmax(answer, raw, net->output_size);
        for (k = 0; k < net->output_size; k++){
          float a = answer[k];
          sum[k] += a;
          sumsq[k] += a * a;
        }
      }
      for (k = 0; k < net->output_size; k++){
        float m = sum[k] / (len - opt_ignore_start);
        stddev[k] = sqrtf(sumsq[k] / (len - opt_ignore_start) - m * m);
        mean[k] = m;
      }

      printf("%s mean: ", filename);
      for (k = 0; k < net->output_size; k++){
        printf("%.3e ", mean[k]);
      }
      printf(" stddev: ");
      for (k = 0; k < net->output_size; k++){
        printf("%.3e ", stddev[k]);
      }
      puts("\n");
    }
    free(text);
  }
  DEBUG("processed %d texts", count);
  return 0;
}
示例#8
0
/* Test helpers. */
int main(int argc, char *argv[])
{
	char *output;
	char *longname = strdup("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
	char *shortname = strdup("shortname");

	plan_tests(48);
	opt_register_table(subtables, NULL);
	opt_register_noarg("--kkk|-k", my_cb, NULL, "magic kkk option");
	opt_register_noarg("-?", opt_usage_and_exit, "<MyArgs>...",
			   "This message");
	opt_register_arg("--longname", opt_set_charp, opt_show_charp,
			 &longname, "a really long option default");
	opt_register_arg("--shortname", opt_set_charp, opt_show_charp,
			 &shortname, "a short option default");
	output = opt_usage("my name", "ExTrA Args");
	diag("%s", output);
	ok1(strstr(output, "Usage: my name"));
	ok1(strstr(output, "--jjj|-j|--lll|-l <arg>"));
	ok1(strstr(output, "ExTrA Args"));
	ok1(strstr(output, "-a "));
	ok1(strstr(output, " Description of a\n"));
	ok1(strstr(output, "-b <arg>"));
	ok1(strstr(output, " Description of b (default: b)\n"));
	ok1(strstr(output, "--ddd "));
	ok1(strstr(output, " Description of ddd\n"));
	ok1(strstr(output, "--eee <filename> "));
	ok1(strstr(output, " (default: eee)\n"));
	ok1(strstr(output, "long table options:\n"));
	ok1(strstr(output, "--ggg|-g "));
	ok1(strstr(output, " Description of ggg\n"));
	ok1(strstr(output, "-h|--hhh <arg>"));
	ok1(strstr(output, " Description of hhh\n"));
	ok1(strstr(output, "--kkk|-k"));
	ok1(strstr(output, "magic kkk option"));
	/* This entry is hidden. */
	ok1(!strstr(output, "--mmm|-m"));
	free(output);

	/* NULL should use string from registered options. */
	output = opt_usage("my name", NULL);
	diag("%s", output);
	ok1(strstr(output, "Usage: my name"));
	ok1(strstr(output, "--jjj|-j|--lll|-l <arg>"));
	ok1(strstr(output, "<MyArgs>..."));
	ok1(strstr(output, "-a "));
	ok1(strstr(output, " Description of a\n"));
	ok1(strstr(output, "-b <arg>"));
	ok1(strstr(output, " Description of b (default: b)\n"));
	ok1(strstr(output, "--ddd "));
	ok1(strstr(output, " Description of ddd\n"));
	ok1(strstr(output, "--eee <filename> "));
	ok1(strstr(output, " (default: eee)\n"));
	ok1(strstr(output, "long table options:\n"));
	ok1(strstr(output, "--ggg|-g "));
	ok1(strstr(output, " Description of ggg\n"));
	ok1(strstr(output, "-h|--hhh <arg>"));
	ok1(strstr(output, " Description of hhh\n"));
	ok1(strstr(output, "--kkk|-k"));
	ok1(strstr(output, "magic kkk option"));
	ok1(strstr(output, "--longname"));
	ok1(strstr(output, "a really long option default"));
	ok1(strstr(output, "(default: \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\"...)"));
	ok1(strstr(output, "--shortname"));
	ok1(strstr(output, "a short option default"));
	ok1(strstr(output, "(default: \"shortname\")"));
	/* This entry is hidden. */
	ok1(!strstr(output, "--mmm|-m"));
	free(output);

	reset_options();
	/* Empty table test. */
	output = opt_usage("nothing", NULL);
	ok1(strstr(output, "Usage: nothing \n"));
	free(output);

	/* No short args. */
	opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
	output = opt_usage("onearg", NULL);
	ok1(strstr(output, "Usage: onearg \n"));
	ok1(strstr(output, "--aaa"));
	ok1(strstr(output, "AAAAll"));
	free(output);

	free(shortname);
	free(longname);
	return exit_status();
}
示例#9
0
文件: run.c 项目: Krellan/bfgminer
int main(int argc, char *argv[])
{
	const char *myname = argv[0];

	plan_tests(215);

	/* Simple short arg.*/
	opt_register_noarg("-a", test_noarg, NULL, "All");
	ok1(parse_args(&argc, &argv, "-a", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 1);

	/* Simple long arg. */
	opt_register_noarg("--aaa", test_noarg, NULL, "AAAAll");
	ok1(parse_args(&argc, &argv, "--aaa", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 2);

	/* Both long and short args. */
	opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll");
	ok1(parse_args(&argc, &argv, "--aaa", "-a", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 4);

	/* Extra arguments preserved. */
	ok1(parse_args(&argc, &argv, "--aaa", "-a", "extra", "args", NULL));
	ok1(argc == 3);
	ok1(argv[0] == myname);
	ok1(strcmp(argv[1], "extra") == 0);
	ok1(strcmp(argv[2], "args") == 0);
	ok1(test_cb_called == 6);

	/* Malformed versions. */
	ok1(!parse_args(&argc, &argv, "--aaa=arg", NULL));
	ok1(strstr(err_output, ": --aaa: doesn't allow an argument"));
	ok1(!parse_args(&argc, &argv, "--aa", NULL));
	ok1(strstr(err_output, ": --aa: unrecognized option"));
	ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
	ok1(strstr(err_output, ": --aaargh: unrecognized option"));

	/* Argument variants. */
	reset_options();
	test_cb_called = 0;
	opt_register_arg("-a|--aaa", test_arg, NULL, "aaa", "AAAAAAll");
	ok1(parse_args(&argc, &argv, "--aaa", "aaa", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(test_cb_called == 1);

	ok1(parse_args(&argc, &argv, "--aaa=aaa", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(test_cb_called == 2);

	ok1(parse_args(&argc, &argv, "-a", "aaa", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(test_cb_called == 3);

	/* Malformed versions. */
	ok1(!parse_args(&argc, &argv, "-a", NULL));
	ok1(strstr(err_output, ": -a: requires an argument"));
	ok1(!parse_args(&argc, &argv, "--aaa", NULL));
	ok1(strstr(err_output, ": --aaa: requires an argument"));
	ok1(!parse_args(&argc, &argv, "--aa", NULL));
	ok1(strstr(err_output, ": --aa: unrecognized option"));
	ok1(!parse_args(&argc, &argv, "--aaargh", NULL));
	ok1(strstr(err_output, ": --aaargh: unrecognized option"));

	/* Now, tables. */
	/* Short table: */
	reset_options();
	test_cb_called = 0;
	opt_register_table(short_table, NULL);
	ok1(parse_args(&argc, &argv, "-a", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 1);
	/* This one needs an arg. */
	ok1(parse_args(&argc, &argv, "-b", NULL) == false);
	ok1(test_cb_called == 1);
	ok1(parse_args(&argc, &argv, "-b", "b", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 2);

	/* Long table: */
	reset_options();
	test_cb_called = 0;
	opt_register_table(long_table, NULL);
	ok1(parse_args(&argc, &argv, "--ddd", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 1);
	/* This one needs an arg. */
	ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
	ok1(test_cb_called == 1);
	ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 2);

	/* Short and long, both. */
	reset_options();
	test_cb_called = 0;
	opt_register_table(long_and_short_table, NULL);
	ok1(parse_args(&argc, &argv, "-g", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 1);
	ok1(parse_args(&argc, &argv, "--ggg", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 2);
	/* This one needs an arg. */
	ok1(parse_args(&argc, &argv, "-h", NULL) == false);
	ok1(test_cb_called == 2);
	ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 3);
	ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
	ok1(test_cb_called == 3);
	ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 4);

	/* Those will all work as tables. */
	test_cb_called = 0;
	reset_options();
	opt_register_table(subtables, NULL);
	ok1(parse_args(&argc, &argv, "-a", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 1);
	/* This one needs an arg. */
	ok1(parse_args(&argc, &argv, "-b", NULL) == false);
	ok1(test_cb_called == 1);
	ok1(parse_args(&argc, &argv, "-b", "b", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 2);

	ok1(parse_args(&argc, &argv, "--ddd", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 3);
	/* This one needs an arg. */
	ok1(parse_args(&argc, &argv, "--eee", NULL) == false);
	ok1(test_cb_called == 3);
	ok1(parse_args(&argc, &argv, "--eee", "eee", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 4);

	/* Short and long, both. */
	ok1(parse_args(&argc, &argv, "-g", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 5);
	ok1(parse_args(&argc, &argv, "--ggg", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 6);
	/* This one needs an arg. */
	ok1(parse_args(&argc, &argv, "-h", NULL) == false);
	ok1(test_cb_called == 6);
	ok1(parse_args(&argc, &argv, "-h", "hhh", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 7);
	ok1(parse_args(&argc, &argv, "--hhh", NULL) == false);
	ok1(test_cb_called == 7);
	ok1(parse_args(&argc, &argv, "--hhh", "hhh", NULL));
	ok1(argc == 1);
	ok1(argv[0] == myname);
	ok1(argv[1] == NULL);
	ok1(test_cb_called == 8);

	/* Now the tricky one: -? must not be confused with an unknown option */
	test_cb_called = 0;
	reset_options();

	/* glibc's getopt does not handle ? with arguments. */
	opt_register_noarg("-?", test_noarg, NULL, "Help");
	ok1(parse_args(&argc, &argv, "-?", NULL));
	ok1(test_cb_called == 1);
	ok1(parse_args(&argc, &argv, "-a", NULL) == false);
	ok1(test_cb_called == 1);
	ok1(strstr(err_output, ": -a: unrecognized option"));
	ok1(parse_args(&argc, &argv, "--aaaa", NULL) == false);
	ok1(test_cb_called == 1);
	ok1(strstr(err_output, ": --aaaa: unrecognized option"));

	test_cb_called = 0;
	reset_options();

	/* Corner cases involving short arg parsing weirdness. */
	opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
	opt_register_arg("-b|--bbb", test_arg, NULL, "bbb", "b");
	opt_register_arg("-c|--ccc", test_arg, NULL, "aaa", "c");
	/* -aa == -a -a */
	ok1(parse_args(&argc, &argv, "-aa", NULL));
	ok1(test_cb_called == 2);
	ok1(parse_args(&argc, &argv, "-aab", NULL) == false);
	ok1(test_cb_called == 4);
	ok1(strstr(err_output, ": -b: requires an argument"));
	ok1(parse_args(&argc, &argv, "-bbbb", NULL));
	ok1(test_cb_called == 5);
	ok1(parse_args(&argc, &argv, "-aabbbb", NULL));
	ok1(test_cb_called == 8);
	ok1(parse_args(&argc, &argv, "-aabbbb", "-b", "bbb", NULL));
	ok1(test_cb_called == 12);
	ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb", "bbb", NULL));
	ok1(test_cb_called == 16);
	ok1(parse_args(&argc, &argv, "-aabbbb", "--bbb=bbb", NULL));
	ok1(test_cb_called == 20);
	ok1(parse_args(&argc, &argv, "-aacaaa", NULL));
	ok1(test_cb_called == 23);
	ok1(parse_args(&argc, &argv, "-aacaaa", "-a", NULL));
	ok1(test_cb_called == 27);
	ok1(parse_args(&argc, &argv, "-aacaaa", "--bbb", "bbb", "-aacaaa",
		       NULL));
	ok1(test_cb_called == 34);

	test_cb_called = 0;
	reset_options();

	/* -- and POSIXLY_CORRECT */
	opt_register_noarg("-a|--aaa", test_noarg, NULL, "a");
	ok1(parse_args(&argc, &argv, "-a", "--", "-a", NULL));
	ok1(test_cb_called == 1);
	ok1(argc == 2);
	ok1(strcmp(argv[1], "-a") == 0);
	ok1(!argv[2]);

	unsetenv("POSIXLY_CORRECT");
	ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
	ok1(test_cb_called == 3);
	ok1(argc == 3);
	ok1(strcmp(argv[1], "somearg") == 0);
	ok1(strcmp(argv[2], "-a") == 0);
	ok1(!argv[3]);

	setenv("POSIXLY_CORRECT", "1", 1);
	ok1(parse_args(&argc, &argv, "-a", "somearg", "-a", "--", "-a", NULL));
	ok1(test_cb_called == 4);
	ok1(argc == 5);
	ok1(strcmp(argv[1], "somearg") == 0);
	ok1(strcmp(argv[2], "-a") == 0);
	ok1(strcmp(argv[3], "--") == 0);
	ok1(strcmp(argv[4], "-a") == 0);
	ok1(!argv[5]);

	/* parse_args allocates argv */
	free(argv);
	return exit_status();
}