Example #1
0
Option parse_args( int argc, const char *argv[], const Options *options )
{
	static int argn = 1;
	static bool no_more_options = false;
	
	static int first_nonopt = 1;
	
	Option option = { NOT_OPTION, NULL, 0 };
	option.argn = first_nonopt;
	
	while (argn < argc)
	{
		size_t arg_len = strlen(argv[argn]);
		
		if (!no_more_options &&
		    argv[argn][0] == '-' &&  // first char is '-'
		    arg_len > 1)             // option is not "-"
		{
			option.argn = argn;
			
			if (argv[argn][1] == '-')  // string begins with "--"
			{
				if (arg_len == 2)  // "--" alone indicates end of options
				{
					++argn;
					no_more_options = true;
				}
				else
				{
					argn = parse_long_opt(argc, argv, options, &option);
				}
			}
			else
			{
				argn = parse_short_opt(argc, argv, options, &option);
			}
			
			// shift option in front of non-options
			permute(argv, &first_nonopt, &option.argn, argn);
			
			// don't include "--" in non-options
			if (no_more_options)
				++option.argn;
			break;
		}
		else
		{
			// skip non-options, permute later when option encountered
			++argn;
		}
	}
	
	return option;
}
Example #2
0
void parse_args(int argc, char *argv[], cmd_data_t *cmd_data)
{
    int a;
    char *arg;
    bool argused;

    for (a=1; a < argc; a++) {
        arg = argv[a];
        argused = false;

        if (arg[0] == '-') {
            if (arg[1] == '-') {
                argused = parse_long_opt(arg + 2, cmd_data);
            } else if (arg[1] == 'o' && a+1 < argc) {
                cmd_data->arglist[cmd_data->num_args++] = arg;
                arg = argv[++a];
                argused = parse_output_file_name(arg, cmd_data);
            } else {
                int num_used = parse_short_opt(arg + 1, cmd_data);
                argused = num_used > 0;

                if (num_used > 1) {
                    a += num_used - 1;
                }
            }
        } else {
            argused = parse_input_file_name(arg, cmd_data);
        }

        if (!argused) {
            cmd_data->arglist[cmd_data->num_args++] = arg;
        }
    }

    post_parse_fixup(cmd_data);
}
Example #3
0
int parse_options_step(struct parse_opt_ctx_t *ctx,
		       const struct option *options,
		       const char * const usagestr[])
{
	int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);

	/* we must reset ->opt, unknown short option leave it dangling */
	ctx->opt = NULL;

	for (; ctx->argc; ctx->argc--, ctx->argv++) {
		const char *arg = ctx->argv[0];

		if (*arg != '-' || !arg[1]) {
			if (parse_nodash_opt(ctx, arg, options) == 0)
				continue;
			if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
				return PARSE_OPT_NON_OPTION;
			ctx->out[ctx->cpidx++] = ctx->argv[0];
			continue;
		}

		if (arg[1] != '-') {
			ctx->opt = arg + 1;
			if (internal_help && *ctx->opt == 'h')
				return parse_options_usage(ctx, usagestr, options, 0);
			switch (parse_short_opt(ctx, options)) {
			case -1:
				return parse_options_usage(ctx, usagestr, options, 1);
			case -2:
				if (ctx->opt)
					check_typos(arg + 1, options);
				goto unknown;
			}
			if (ctx->opt)
				check_typos(arg + 1, options);
			while (ctx->opt) {
				if (internal_help && *ctx->opt == 'h')
					return parse_options_usage(ctx, usagestr, options, 0);
				switch (parse_short_opt(ctx, options)) {
				case -1:
					return parse_options_usage(ctx, usagestr, options, 1);
				case -2:
					/* fake a short option thing to hide the fact that we may have
					 * started to parse aggregated stuff
					 *
					 * This is leaky, too bad.
					 */
					ctx->argv[0] = xstrdup(ctx->opt - 1);
					*(char *)ctx->argv[0] = '-';
					goto unknown;
				}
			}
			continue;
		}

		if (!arg[2]) { /* "--" */
			if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
				ctx->argc--;
				ctx->argv++;
			}
			break;
		}

		if (internal_help && !strcmp(arg + 2, "help-all"))
			return usage_with_options_internal(ctx, usagestr, options, 1, 0);
		if (internal_help && !strcmp(arg + 2, "help"))
			return parse_options_usage(ctx, usagestr, options, 0);
		switch (parse_long_opt(ctx, arg + 2, options)) {
		case -1:
			return parse_options_usage(ctx, usagestr, options, 1);
		case -2:
			goto unknown;
		}
		continue;
unknown:
		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
			return PARSE_OPT_UNKNOWN;
		ctx->out[ctx->cpidx++] = ctx->argv[0];
		ctx->opt = NULL;
	}
	return PARSE_OPT_DONE;
}
Example #4
0
static int parse_options_step(struct parse_opt_ctx_t *ctx,
			      const struct option *options,
			      const char * const usagestr[])
{
	int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
	int excl_short_opt = 1;
	const char *arg;

	/* we must reset ->opt, unknown short option leave it dangling */
	ctx->opt = NULL;

	for (; ctx->argc; ctx->argc--, ctx->argv++) {
		arg = ctx->argv[0];
		if (*arg != '-' || !arg[1]) {
			if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
				break;
			ctx->out[ctx->cpidx++] = ctx->argv[0];
			continue;
		}

		if (arg[1] != '-') {
			ctx->opt = ++arg;
			if (internal_help && *ctx->opt == 'h') {
				return usage_with_options_internal(usagestr, options, 0, ctx);
			}
			switch (parse_short_opt(ctx, options)) {
			case -1:
				return parse_options_usage(usagestr, options, arg, 1);
			case -2:
				goto unknown;
			case -3:
				goto exclusive;
			default:
				break;
			}
			if (ctx->opt)
				check_typos(arg, options);
			while (ctx->opt) {
				if (internal_help && *ctx->opt == 'h')
					return usage_with_options_internal(usagestr, options, 0, ctx);
				arg = ctx->opt;
				switch (parse_short_opt(ctx, options)) {
				case -1:
					return parse_options_usage(usagestr, options, arg, 1);
				case -2:
					/* fake a short option thing to hide the fact that we may have
					 * started to parse aggregated stuff
					 *
					 * This is leaky, too bad.
					 */
					ctx->argv[0] = strdup(ctx->opt - 1);
					*(char *)ctx->argv[0] = '-';
					goto unknown;
				case -3:
					goto exclusive;
				default:
					break;
				}
			}
			continue;
		}

		if (!arg[2]) { /* "--" */
			if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
				ctx->argc--;
				ctx->argv++;
			}
			break;
		}

		arg += 2;
		if (internal_help && !strcmp(arg, "help-all"))
			return usage_with_options_internal(usagestr, options, 1, ctx);
		if (internal_help && !strcmp(arg, "help"))
			return usage_with_options_internal(usagestr, options, 0, ctx);
		if (!strcmp(arg, "list-opts"))
			return PARSE_OPT_LIST_OPTS;
		if (!strcmp(arg, "list-cmds"))
			return PARSE_OPT_LIST_SUBCMDS;
		switch (parse_long_opt(ctx, arg, options)) {
		case -1:
			return parse_options_usage(usagestr, options, arg, 0);
		case -2:
			goto unknown;
		case -3:
			excl_short_opt = 0;
			goto exclusive;
		default:
			break;
		}
		continue;
unknown:
		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
			return PARSE_OPT_UNKNOWN;
		ctx->out[ctx->cpidx++] = ctx->argv[0];
		ctx->opt = NULL;
	}
	return PARSE_OPT_DONE;

exclusive:
	parse_options_usage(usagestr, options, arg, excl_short_opt);
	if ((excl_short_opt && ctx->excl_opt->short_name) ||
	    ctx->excl_opt->long_name == NULL) {
		char opt = ctx->excl_opt->short_name;
		parse_options_usage(NULL, options, &opt, 1);
	} else {
		parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
	}
	return PARSE_OPT_HELP;
}