Exemplo n.º 1
0
/* Returns 1 if argument consumed, 0 if all done, -1 on error. */
int parse_one(int *argc, char *argv[], unsigned *offset,
	      void (*errlog)(const char *fmt, ...))
{
	unsigned i, arg, len;
	const char *o, *optarg = NULL;
	char *problem;

	if (getenv("POSIXLY_CORRECT")) {
		/* Don't find options after non-options. */
		arg = 1;
	} else {
		for (arg = 1; argv[arg]; arg++) {
			if (argv[arg][0] == '-')
				break;
		}
	}

	if (!argv[arg] || argv[arg][0] != '-')
		return 0;

	/* Special arg terminator option. */
	if (strcmp(argv[arg], "--") == 0) {
		consume_option(argc, argv, arg);
		return 0;
	}

	/* Long options start with -- */
	if (argv[arg][1] == '-') {
		assert(*offset == 0);
		for (o = first_lopt(&i, &len); o; o = next_lopt(o, &i, &len)) {
			if (strncmp(argv[arg] + 2, o, len) != 0)
				continue;
			if (argv[arg][2 + len] == '=')
				optarg = argv[arg] + 2 + len + 1;
			else if (argv[arg][2 + len] != '\0')
				continue;
			break;
		}
		if (!o)
			return parse_err(errlog, argv[0],
					 argv[arg], strlen(argv[arg]),
					 "unrecognized option");
		/* For error messages, we include the leading '--' */
		o -= 2;
		len += 2;
	} else {
		/* offset allows us to handle -abc */
		for (o = first_sopt(&i); o; o = next_sopt(o, &i)) {
			if (argv[arg][*offset + 1] != *o)
				continue;
			(*offset)++;
			break;
		}
		if (!o)
			return parse_err(errlog, argv[0],
					 argv[arg], strlen(argv[arg]),
					 "unrecognized option");
		/* For error messages, we include the leading '-' */
		o--;
		len = 2;
	}

	if (opt_table[i].type == OPT_NOARG) {
		if (optarg)
			return parse_err(errlog, argv[0], o, len,
					 "doesn't allow an argument");
		problem = opt_table[i].cb(opt_table[i].u.arg);
	} else {
		if (!optarg) {
			/* Swallow any short options as optarg, eg -afile */
			if (*offset && argv[arg][*offset + 1]) {
				optarg = argv[arg] + *offset + 1;
				*offset = 0;
			} else
				optarg = argv[arg+1];
		}
		if (!optarg)
			return parse_err(errlog, argv[0], o, len,
					 "requires an argument");
		problem = opt_table[i].cb_arg(optarg, opt_table[i].u.arg);
	}

	if (problem) {
		parse_err(errlog, argv[0], o, len, problem);
		free(problem);
		return -1;
	}

	/* If no more letters in that short opt, reset offset. */
	if (*offset && !argv[arg][*offset + 1])
		*offset = 0;

	/* All finished with that option? */
	if (*offset == 0) {
		consume_option(argc, argv, arg);
		if (optarg && optarg == argv[arg])
			consume_option(argc, argv, arg);
	}
	return 1;
}
Exemplo n.º 2
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();
}