Example #1
0
/*
 * getopt --
 *	Parse argc/argv argument vector.
 *
 * [eventually this will replace the real getopt]
 */
int
getopt(int nargc, char * const *nargv, const char *options)
{
	int retval;

	_DIAGASSERT(nargv != NULL);
	_DIAGASSERT(options != NULL);

	retval = getopt_internal(nargc, __UNCONST(nargv), options);
	if (retval == -2) {
		++optind;
		/*
		 * We found an option (--), so if we skipped non-options,
		 * we have to permute.
		 */
		if (nonopt_end != -1) {
			permute_args(nonopt_start, nonopt_end, optind,
				       (char **)nargv);
			optind -= nonopt_end - nonopt_start;
		}
		nonopt_start = nonopt_end = -1;
		retval = -1;
	}
	return retval;
}
Example #2
0
/*
 * getopt --
 *	Parse argc/argv argument vector.
 *
 * [eventually this will replace the real getopt]
 */
int
getopt(int nargc, char * const *nargv, const char *options)
{
	int retval;

	if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
		++optind;
		/*
		 * We found an option (--), so if we skipped non-options,
		 * we have to permute.
		 */
		if (nonopt_end != -1) {
			permute_args(nonopt_start, nonopt_end, optind,
				       nargv);
			optind -= nonopt_end - nonopt_start;
		}
		nonopt_start = nonopt_end = -1;
		retval = -1;
	}
	return retval;
}
Example #3
0
/*
 * getopt_internal --
 *	Parse argc/argv argument vector.  Called by user level routines.
 */
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
	const struct pkg_option *long_options, int *idx, int flags)
{
	char *oli;				/* option letter list index */
	int optchar, short_too;
	int posixly_correct;	/* no static, can be changed on the fly */

	if (options == NULL)
		return (-1);

	/*
	 * Disable GNU extensions if POSIXLY_CORRECT is set or options
	 * string begins with a '+'.
	 */
	posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
#ifdef GNU_COMPATIBLE
	if (*options == '-')
		flags |= FLAG_ALLARGS;
	else if (posixly_correct || *options == '+')
		flags &= ~FLAG_PERMUTE;
#else
	if (posixly_correct || *options == '+')
		flags &= ~FLAG_PERMUTE;
	else if (*options == '-')
		flags |= FLAG_ALLARGS;
#endif
#if HAVE_STRICT_MODE >= 1
	flags &= ~FLAG_PERMUTE;
#endif
	if (*options == '+' || *options == '-')
		options++;

	/*
	 * XXX Some GNU programs (like cvs) set pkg_optind to 0 instead of
	 * XXX using pkg_optreset.  Work around this braindamage.
	 */
	if (pkg_optind == 0)
		pkg_optind = pkg_optreset = 1;

	pkg_optarg = NULL;
	if (pkg_optreset)
		nonopt_start = nonopt_end = -1;
start:
	if (pkg_optreset || !*place) {		/* update scanning pointer */
		pkg_optreset = 0;
		if (pkg_optind >= nargc) {          /* end of argument vector */
			place = EMSG;
			if (nonopt_end != -1) {
				/* do permutation, if we have to */
				permute_args(nonopt_start, nonopt_end,
				    pkg_optind, nargv);
				pkg_optind -= nonopt_end - nonopt_start;
			}
			else if (nonopt_start != -1) {
				/*
				 * If we skipped non-options, set pkg_optind
				 * to the first of them.
				 */
				pkg_optind = nonopt_start;
			}
			nonopt_start = nonopt_end = -1;
			return (-1);
		}
		if (*(place = nargv[pkg_optind]) != '-' ||
#ifdef GNU_COMPATIBLE
		    place[1] == '\0') {
#else
		    (place[1] == '\0' && strchr(options, '-') == NULL)) {
#endif
			place = EMSG;		/* found non-option */
			if (flags & FLAG_ALLARGS) {
				/*
				 * GNU extension:
				 * return non-option as argument to option 1
				 */
				pkg_optarg = nargv[pkg_optind++];
				return (INORDER);
			}
			if (!(flags & FLAG_PERMUTE)) {
				/*
				 * If no permutation wanted, stop parsing
				 * at first non-option.
				 */
				return (-1);
			}
			/* do permutation */
			if (nonopt_start == -1)
				nonopt_start = pkg_optind;
			else if (nonopt_end != -1) {
				permute_args(nonopt_start, nonopt_end,
				    pkg_optind, nargv);
				nonopt_start = pkg_optind -
				    (nonopt_end - nonopt_start);
				nonopt_end = -1;
			}
			pkg_optind++;
			/* process next argument */
			goto start;
		}
		if (nonopt_start != -1 && nonopt_end == -1)
			nonopt_end = pkg_optind;

		/*
		 * If we have "-" do nothing, if "--" we are done.
		 */
		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
			pkg_optind++;
			place = EMSG;
			/*
			 * We found an option (--), so if we skipped
			 * non-options, we have to permute.
			 */
			if (nonopt_end != -1) {
				permute_args(nonopt_start, nonopt_end,
				    pkg_optind, nargv);
				pkg_optind -= nonopt_end - nonopt_start;
			}
			nonopt_start = nonopt_end = -1;
			return (-1);
		}
	}
Example #4
0
/*
 * getopt_long --
 *	Parse argc/argv argument vector.
 */
int
getopt_long(int nargc,
	    char * const *nargv,
	    const char *options,
	    const struct option *long_options,
	    int *idx)
{
	int retval;

	/* idx may be NULL */

	if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
		char *current_argv, *has_equal;
		size_t current_argv_len;
		int i, match;

		current_argv = place;
		match = -1;

		optind++;
		place = EMSG;

		if (*current_argv == '\0') {		/* found "--" */
			/*
			 * We found an option (--), so if we skipped
			 * non-options, we have to permute.
			 */
			if (nonopt_end != -1) {
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				optind -= nonopt_end - nonopt_start;
			}
			nonopt_start = nonopt_end = -1;
			return -1;
		}
		if ((has_equal = strchr(current_argv, '=')) != NULL) {
			/* argument found (--option=arg) */
			current_argv_len = has_equal - current_argv;
			has_equal++;
		} else
			current_argv_len = strlen(current_argv);
	    
		for (i = 0; long_options[i].name; i++) {
			/* find matching long option */
			if (strncmp(current_argv, long_options[i].name,
			    current_argv_len))
				continue;

			if (strlen(long_options[i].name) ==
			    (unsigned)current_argv_len) {
				/* exact match */
				match = i;
				break;
			}
			if (match == -1)		/* partial match */
				match = i;
			else {
				/* ambiguous abbreviation */
				if (PRINT_ERROR)
					fprintf(stderr, ambig, (int)current_argv_len,
					     current_argv);
				optopt = 0;
				return BADCH;
			}
		}
		if (match != -1) {			/* option found */
		        if (long_options[match].has_arg == no_argument
			    && has_equal) {
				if (PRINT_ERROR)
					fprintf(stderr, noarg, (int)current_argv_len,
					     current_argv);
				/*
				 * XXX: GNU sets optopt to val regardless of
				 * flag
				 */
				if (long_options[match].flag == NULL)
					optopt = long_options[match].val;
				else
					optopt = 0;
				return BADARG;
			}
			if (long_options[match].has_arg == required_argument ||
			    long_options[match].has_arg == optional_argument) {
				if (has_equal)
					optarg = has_equal;
				else if (long_options[match].has_arg ==
				    required_argument) {
					/*
					 * optional argument doesn't use
					 * next nargv
					 */
					optarg = nargv[optind++];
				}
			}
			if ((long_options[match].has_arg == required_argument)
			    && (optarg == NULL)) {
				/*
				 * Missing argument; leading ':'
				 * indicates no error should be generated
				 */
				if (PRINT_ERROR)
					fprintf(stderr, recargstring, current_argv);
				/*
				 * XXX: GNU sets optopt to val regardless
				 * of flag
				 */
				if (long_options[match].flag == NULL)
					optopt = long_options[match].val;
				else
					optopt = 0;
				--optind;
				return BADARG;
			}
		} else {			/* unknown option */
			if (PRINT_ERROR)
				fprintf(stderr, illoptstring, current_argv);
			optopt = 0;
			return BADCH;
		}
		if (long_options[match].flag) {
			*long_options[match].flag = long_options[match].val;
			retval = 0;
		} else 
			retval = long_options[match].val;
		if (idx)
			*idx = match;
	}
	return retval;
}
Example #5
0
/*
 * getopt_internal --
 *	Parse argc/argv argument vector.  Called by user level routines.
 *  Returns -2 if -- is found (can be long option or end of options marker).
 */
static int
getopt_internal(int nargc,
		char * const *nargv,
		const char *options)
{
	char *oli;				/* option letter list index */
	int optchar;

	optarg = NULL;

	/*
	 * XXX Some programs (like rsyncd) expect to be able to
	 * XXX re-initialize optind to 0 and have getopt_long(3)
	 * XXX properly function again.  Work around this braindamage.
	 */
	if (optind == 0)
		optind = 1;

	if (optreset)
		nonopt_start = nonopt_end = -1;
start:
	if (optreset || !*place) {		/* update scanning pointer */
		optreset = 0;
		if (optind >= nargc) {          /* end of argument vector */
			place = EMSG;
			if (nonopt_end != -1) {
				/* do permutation, if we have to */
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				optind -= nonopt_end - nonopt_start;
			}
			else if (nonopt_start != -1) {
				/*
				 * If we skipped non-options, set optind
				 * to the first of them.
				 */
				optind = nonopt_start;
			}
			nonopt_start = nonopt_end = -1;
			return -1;
		}
		if ((*(place = nargv[optind]) != '-')
		    || (place[1] == '\0')) {    /* found non-option */
			place = EMSG;
			if (IN_ORDER) {
				/*
				 * GNU extension: 
				 * return non-option as argument to option 1
				 */
				optarg = nargv[optind++];
				return INORDER;
			}
			if (!PERMUTE) {
				/*
				 * if no permutation wanted, stop parsing
				 * at first non-option
				 */
				return -1;
			}
			/* do permutation */
			if (nonopt_start == -1)
				nonopt_start = optind;
			else if (nonopt_end != -1) {
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				nonopt_start = optind -
				    (nonopt_end - nonopt_start);
				nonopt_end = -1;
			}
			optind++;
			/* process next argument */
			goto start;
		}
		if (nonopt_start != -1 && nonopt_end == -1)
			nonopt_end = optind;
		if (place[1] && *++place == '-') {	/* found "--" */
			place++;
			return -2;
		}
	}
	if ((optchar = (int)*place++) == (int)':' ||
	    (oli = strchr(options + (IGNORE_FIRST ? 1 : 0), optchar)) == NULL) {
		/* option letter unknown or ':' */
		if (!*place)
			++optind;
		if (PRINT_ERROR)
			fprintf(stderr, illoptchar, optchar);
		optopt = optchar;
		return BADCH;
	}
	if (optchar == 'W' && oli[1] == ';') {		/* -W long-option */
		/* XXX: what if no long options provided (called by getopt)? */
		if (*place) 
			return -2;

		if (++optind >= nargc) {	/* no arg */
			place = EMSG;
			if (PRINT_ERROR)
				fprintf(stderr, recargchar, optchar);
			optopt = optchar;
			return BADARG;
		} else				/* white space */
			place = nargv[optind];
		/*
		 * Handle -W arg the same as --arg (which causes getopt to
		 * stop parsing).
		 */
		return -2;
	}
	if (*++oli != ':') {			/* doesn't take argument */
		if (!*place)
			++optind;
	} else {				/* takes (optional) argument */
		optarg = NULL;
		if (*place)			/* no white space */
			optarg = place;
		/* XXX: disable test for :: if PC? (GNU doesn't) */
		else if (oli[1] != ':') {	/* arg not optional */
			if (++optind >= nargc) {	/* no arg */
				place = EMSG;
				if (PRINT_ERROR)
					fprintf(stderr, recargchar, optchar);
				optopt = optchar;
				return BADARG;
			} else
				optarg = nargv[optind];
		}
		place = EMSG;
		++optind;
	}
	/* dump back option letter */
	return optchar;
}
Example #6
0
/*
 * getopt_internal --
 *	Parse argc/argv argument vector.  Called by user level routines.
 */
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
	const struct option *long_options, int *idx, int flags)
{
	char *oli;				/* option letter list index */
	int optchar, short_too;
	static int posixly_correct = -1;

	if (options == NULL)
		return (-1);

	/*
	 * Disable GNU extensions if POSIXLY_CORRECT is set or options
	 * string begins with a '+'.
	 */
	if (posixly_correct == -1)
		posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
	if (posixly_correct || *options == '+')
		flags &= ~FLAG_PERMUTE;
	else if (*options == '-')
		flags |= FLAG_ALLARGS;
	if (*options == '+' || *options == '-')
		options++;

	/*
	 * XXX Some GNU programs (like cvs) set optind to 0 instead of
	 * XXX using optreset.  Work around this braindamage.
	 */
	if (optind == 0)
		optind = optreset = 1;

	optarg = NULL;
	if (optreset)
		nonopt_start = nonopt_end = -1;
start:
	if (optreset || !*place) {		/* update scanning pointer */
		optreset = 0;
		if (optind >= nargc) {          /* end of argument vector */
			place = EMSG;
			if (nonopt_end != -1) {
				/* do permutation, if we have to */
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				optind -= nonopt_end - nonopt_start;
			}
			else if (nonopt_start != -1) {
				/*
				 * If we skipped non-options, set optind
				 * to the first of them.
				 */
				optind = nonopt_start;
			}
			nonopt_start = nonopt_end = -1;
			return (-1);
		}
		if (*(place = nargv[optind]) != '-' ||
		    (place[1] == '\0' && strchr(options, '-') == NULL)) {
			place = EMSG;		/* found non-option */
			if (flags & FLAG_ALLARGS) {
				/*
				 * GNU extension:
				 * return non-option as argument to option 1
				 */
				optarg = nargv[optind++];
				return (INORDER);
			}
			if (!(flags & FLAG_PERMUTE)) {
				/*
				 * If no permutation wanted, stop parsing
				 * at first non-option.
				 */
				return (-1);
			}
			/* do permutation */
			if (nonopt_start == -1)
				nonopt_start = optind;
			else if (nonopt_end != -1) {
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				nonopt_start = optind -
				    (nonopt_end - nonopt_start);
				nonopt_end = -1;
			}
			optind++;
			/* process next argument */
			goto start;
		}
		if (nonopt_start != -1 && nonopt_end == -1)
			nonopt_end = optind;

		/*
		 * If we have "-" do nothing, if "--" we are done.
		 */
		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
			optind++;
			place = EMSG;
			/*
			 * We found an option (--), so if we skipped
			 * non-options, we have to permute.
			 */
			if (nonopt_end != -1) {
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				optind -= nonopt_end - nonopt_start;
			}
			nonopt_start = nonopt_end = -1;
			return (-1);
		}
	}

	/*
	 * Check long options if:
	 *  1) we were passed some
	 *  2) the arg is not just "-"
	 *  3) either the arg starts with -- we are getopt_long_only()
	 */
	if (long_options != NULL && place != nargv[optind] &&
	    (*place == '-' || (flags & FLAG_LONGONLY))) {
		short_too = 0;
		if (*place == '-')
			place++;		/* --foo long option */
		else if (*place != ':' && strchr(options, *place) != NULL)
			short_too = 1;		/* could be short option too */

		optchar = parse_long_options(nargv, options, long_options,
		    idx, short_too);
		if (optchar != -1) {
			place = EMSG;
			return (optchar);
		}
	}

	if ((optchar = (int)*place++) == (int)':' ||
	    (optchar == (int)'-' && *place != '\0') ||
	    (oli = strchr(options, optchar)) == NULL) {
		/*
		 * If the user specified "-" and  '-' isn't listed in
		 * options, return -1 (non-option) as per POSIX.
		 * Otherwise, it is an unknown option character (or ':').
		 */
		if (optchar == (int)'-' && *place == '\0')
			return (-1);
		if (!*place)
			++optind;
		if (PRINT_ERROR)
			fprintf(stderr, illoptchar, optchar);
		optopt = optchar;
		return (BADCH);
	}
	if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
		/* -W long-option */
		if (*place)			/* no space */
			/* NOTHING */;
		else if (++optind >= nargc) {	/* no arg */
			place = EMSG;
			if (PRINT_ERROR)
				fprintf(stderr, recargchar, optchar);
			optopt = optchar;
			return (BADARG);
		} else				/* white space */
			place = nargv[optind];
		optchar = parse_long_options(nargv, options, long_options,
		    idx, 0);
		place = EMSG;
		return (optchar);
	}
	if (*++oli != ':') {			/* doesn't take argument */
		if (!*place)
			++optind;
	} else {				/* takes (optional) argument */
		optarg = NULL;
		if (*place)			/* no white space */
			optarg = place;
		else if (oli[1] != ':') {	/* arg not optional */
			if (++optind >= nargc) {	/* no arg */
				place = EMSG;
				if (PRINT_ERROR)
					fprintf(stderr, recargchar, optchar);
				optopt = optchar;
				return (BADARG);
			} else
				optarg = nargv[optind];
		}
		place = EMSG;
		++optind;
	}
	/* dump back option letter */
	return (optchar);
}
Example #7
0
/*
 * getopt_internal --
 *	Parse argc/argv argument vector.  Called by user level routines.
 */
static int
getopt_internal(int nargc, char * const *nargv, const char *options,
	const struct option *long_options, int *idx, int flags)
{
	char *oli;				/* option letter list index */
	int optchar, short_too;

	if (options == NULL)
		return (-1);

	/*
	 * XXX Some GNU programs (like cvs) set optind to 0 instead of
	 * XXX using optreset.  Work around this braindamage.
	 */
	if (optind == 0)
		optind = optreset = 1;

	if (*options == '-')
		flags |= FLAG_ALLARGS;
	if (*options == '+' || *options == '-')
		options++;

	optarg = NULL;
	if (optreset)
		nonopt_start = nonopt_end = -1;
start:
	if (optreset || !*place) {		/* update scanning pointer */
		optreset = 0;
		if (optind >= nargc) {          /* end of argument vector */
			place = EMSG;
			if (nonopt_end != -1) {
				/* do permutation, if we have to */
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				optind -= nonopt_end - nonopt_start;
			}
			else if (nonopt_start != -1) {
				/*
				 * If we skipped non-options, set optind
				 * to the first of them.
				 */
				optind = nonopt_start;
			}
			nonopt_start = nonopt_end = -1;
			return (-1);
		}
		if (*(place = nargv[optind]) != '-' ||
#ifdef GNU_COMPATIBLE
		    place[1] == '\0') {
#else
		    (place[1] == '\0' && strchr(options, '-') == NULL)) {
#endif
			place = EMSG;		/* found non-option */
			if (flags & FLAG_ALLARGS) {
				/*
				 * GNU extension:
				 * return non-option as argument to option 1
				 */
				optarg = nargv[optind++];
				return (INORDER);
			}
			if (!(flags & FLAG_PERMUTE)) {
				/*
				 * If no permutation wanted, stop parsing
				 * at first non-option.
				 */
				return (-1);
			}
			/* do permutation */
			if (nonopt_start == -1)
				nonopt_start = optind;
			else if (nonopt_end != -1) {
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				nonopt_start = optind -
				    (nonopt_end - nonopt_start);
				nonopt_end = -1;
			}
			optind++;
			/* process next argument */
			goto start;
		}
		if (nonopt_start != -1 && nonopt_end == -1)
			nonopt_end = optind;

		/*
		 * If we have "-" do nothing, if "--" we are done.
		 */
		if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
			optind++;
			place = EMSG;
			/*
			 * We found an option (--), so if we skipped
			 * non-options, we have to permute.
			 */
			if (nonopt_end != -1) {
				permute_args(nonopt_start, nonopt_end,
				    optind, nargv);
				optind -= nonopt_end - nonopt_start;
			}
			nonopt_start = nonopt_end = -1;
			return (-1);
		}
	}
Example #8
0
/*
 * getopt_long --
 *      Parse argc/argv argument vector.
 */
int
getopt_long(int nargc,
            char * const *nargv,
            const char *options,
            const struct option *long_options,
            int *idx)
{
        int retval;

        _DIAGASSERT(nargv != NULL);
        _DIAGASSERT(options != NULL);
        _DIAGASSERT(long_options != NULL);
        /* idx may be NULL */

        progname = nargv[0];

	/* fprintf(stderr, "FYI: using private getoptlong.c implementation\n"); */

        if ((retval = getopt_internal(nargc, nargv, options)) == -2) {
                char *current_argv, *has_equal;
                size_t current_argv_len;
                int i, match;

                current_argv = place;
                match = -1;

                optind++;
                place = EMSG;

                if (*current_argv == '\0') {            /* found "--" */
                        /*
                         * We found an option (--), so if we skipped
                         * non-options, we have to permute.
                         */
                        if (nonopt_end != -1) {
                                permute_args(nonopt_start, nonopt_end,
                                    optind, nargv);
                                optind -= nonopt_end - nonopt_start;
                        }
                        nonopt_start = nonopt_end = -1;
                        return -1;
                }
                if ((has_equal = strchr(current_argv, '=')) != NULL) {
                        /* argument found (--option=arg) */
                        current_argv_len = has_equal - current_argv;
                        has_equal++;
                } else
                        current_argv_len = strlen(current_argv);

                for (i = 0; long_options[i].name; i++) {
                        /* find matching long option */
                        if (strncmp(current_argv, long_options[i].name,
                            current_argv_len))
                                continue;

                        if (strlen(long_options[i].name) ==
                            (unsigned)current_argv_len) {
                                /* exact match */
                                match = i;
                                break;
                        }
                        if (match == -1)                /* partial match */
                                match = i;
                        else {
                                /* ambiguous abbreviation */
                                if (PRINT_ERROR)
                                        xwarnx(ambig, (int)current_argv_len,
                                             current_argv);
                                optopt = 0;
                                return BADCH;
                        }
                }
                if (match != -1) {                      /* option found */
                        if (long_options[match].has_arg == no_argument
                            && has_equal) {
                                if (PRINT_ERROR)
                                        xwarnx(noarg, (int)current_argv_len,
                                             current_argv);
                                /*
                                 * XXX: GNU sets optopt to val regardless of
                                 * flag
                                 */
                                if (long_options[match].flag == NULL)
                                        optopt = long_options[match].val;
                                else
                                        optopt = 0;
                                /* XXX: GNU returns '?' if options[0] != ':' */
fprintf(stdout, "Sanity: 5\n");fprintf(stderr, "SANITY: 5\n");
                             //   if (options[0] != ':')
                              //          return BADCH;
                                optopt = BADCH;
                                //        return BADCH;
                                return BADARG;
                        }
                        if (long_options[match].has_arg == required_argument ||
                            long_options[match].has_arg == optional_argument) {
                                if (has_equal)
                                        optarg = has_equal;
                                else if (long_options[match].has_arg ==
                                    required_argument) {
                                        /*
                                         * optional argument doesn't use
                                         * next nargv
                                         */
                                        if (optind >= nargc) {          /* end of argument vector */
//fprintf(stdout, "Sanity: 8\n");fprintf(stderr, "SANITY: 8\n");
                                                optarg = 0;
                                        } else {
//fprintf(stdout, "Sanity: 9\n");fprintf(stderr, "SANITY: 9\n");
                                                optarg = nargv[optind++];
                                        }
                                }
                        }
                        if ((long_options[match].has_arg == required_argument)
                            && (optarg == NULL)) {
                                /*
                                 * Missing argument; leading ':'
                                 * indicates no error should be generated
                                 */
                                if (PRINT_ERROR)
                                        xwarnx(recargstring, current_argv);
                                /*
                                 * XXX: GNU sets optopt to val regardless
                                 * of flag
                                 */
                                if (long_options[match].flag == NULL)
                                        optopt = long_options[match].val;
                                else
                                        optopt = 0;
                                /* XXX: GNU returns '?' if options[0] != ':' */
                                //--optind;
//fprintf(stdout, "Sanity: 6\n");fprintf(stderr, "SANITY: 6\n");
                                return BADARG;
                        }
                } else {                        /* unknown option */
                        if (PRINT_ERROR)
                                xwarnx(illoptstring, current_argv);
                        optopt = 0;
                        optarg = current_argv;
                        return BADCH;
                }
                if (long_options[match].flag) {
                        *long_options[match].flag = long_options[match].val;
                        retval = 0;
                } else
                        retval = long_options[match].val;
                if (idx)
                        *idx = match;
        }
//fprintf(stdout, "Terminal: %d\n",retval);fprintf(stderr, "TERMINAL: %d\n",retval);
        return retval;
}
Example #9
0
/*
 * getopt_internal --
 *	Parse argc/argv argument vector.  Called by user level routines.
 */
static int
getopt_internal_TS(int nargc, char * const *nargv, const char *options,
	const struct option_TS *long_options, int *idx, int flags,struct OptVars* vars)
{
	char *oli;				/* option letter list index */
	int optchar, short_too;

	if (options == NULL)
		return (-1);

	/*
	 * Disable GNU extensions if POSIXLY_CORRECT is set or options
	 * string begins with a '+'.
	 */
	if (posixly_correct || *options == '+')
		flags &= ~FLAG_PERMUTE;
	else if (*options == '-')
		flags |= FLAG_ALLARGS;
	if (*options == '+' || *options == '-')
		options++;

	/*
	 * XXX Some GNU programs (like cvs) set optind to 0 instead of
	 * XXX using optreset.  Work around this braindamage.
	 */
	if (vars->optind == 0)
	   vars->optind = vars->optreset = 1;

	vars->optarg = NULL;
	if (vars->optreset)
	   vars->nonopt_start = vars->nonopt_end = -1;
start:
	if (vars->optreset || !*(vars->place)) {		/* update scanning pointer */
	   vars->optreset = 0;
		if (vars->optind >= nargc) {          /* end of argument vector */
			(vars->place) = EMSG;
			if (vars->nonopt_end != -1) {
				/* do permutation, if we have to */
				permute_args(vars->nonopt_start, vars->nonopt_end,
				      vars->optind, nargv);
				vars->optind -= vars->nonopt_end - vars->nonopt_start;
			}
			else if (vars->nonopt_start != -1) {
				/*
				 * If we skipped non-options, set optind
				 * to the first of them.
				 */
			   vars->optind = vars->nonopt_start;
			}
			vars->nonopt_start = vars->nonopt_end = -1;
			return (-1);
		}
		if (*((vars->place) = nargv[vars->optind]) != '-' ||
		    ((vars->place)[1] == '\0' && strchr(options, '-') == NULL)) {
			(vars->place) = EMSG;		/* found non-option */
			if (flags & FLAG_ALLARGS) {
				/*
				 * GNU extension:
				 * return non-option as argument to option 1
				 */
			   vars->optarg = nargv[(vars->optind)++];
				return (INORDER);
			}
			if (!(flags & FLAG_PERMUTE)) {
				/*
				 * If no permutation wanted, stop parsing
				 * at first non-option.
				 */
				return (-1);
			}
			/* do permutation */
			if (vars->nonopt_start == -1)
			   vars->nonopt_start = vars->optind;
			else if (vars->nonopt_end != -1) {
				permute_args(vars->nonopt_start, vars->nonopt_end,
				      vars->optind, nargv);
				vars->nonopt_start = vars->optind -
				    (vars->nonopt_end - vars->nonopt_start);
				vars->nonopt_end = -1;
			}
			(vars->optind)++;
			/* process next argument */
			goto start;
		}
		if (vars->nonopt_start != -1 && vars->nonopt_end == -1)
		   vars->nonopt_end = vars->optind;

		/*
		 * If we have "-" do nothing, if "--" we are done.
		 */
		if ((vars->place)[1] != '\0' && *++(vars->place) == '-' && (vars->place)[1] == '\0') {
			(vars->optind)++;
			(vars->place) = EMSG;
			/*
			 * We found an option (--), so if we skipped
			 * non-options, we have to permute.
			 */
			if (vars->nonopt_end != -1) {
				permute_args(vars->nonopt_start, vars->nonopt_end,
				      vars->optind, nargv);
				vars->optind -= vars->nonopt_end - vars->nonopt_start;
			}
			vars->nonopt_start = vars->nonopt_end = -1;
			return (-1);
		}
	}

	/*
	 * Check long options if:
	 *  1) we were passed some
	 *  2) the arg is not just "-"
	 *  3) either the arg starts with -- we are getopt_long_only()
	 */
	if (long_options != NULL && (vars->place) != nargv[vars->optind] &&
	    (*(vars->place) == '-' || (flags & FLAG_LONGONLY))) {
		short_too = 0;
		if (*(vars->place) == '-')
			(vars->place)++;		/* --foo long option */
		else if (*(vars->place) != ':' && strchr(options, *(vars->place)) != NULL)
			short_too = 1;		/* could be short option too */

		optchar = parse_long_options_TS(nargv, options, long_options,
		    idx, short_too,vars);
		if (optchar != -1) {
			(vars->place) = EMSG;
			return (optchar);
		}
	}

	if ((optchar = (int)*(vars->place)++) == (int)':' ||
	    (optchar == (int)'-' && *(vars->place) != '\0') ||
	    (oli = (char*)strchr(options, optchar)) == NULL) {
		/*
		 * If the user specified "-" and  '-' isn't listed in
		 * options, return -1 (non-option) as per POSIX.
		 * Otherwise, it is an unknown option character (or ':').
		 */
		if (optchar == (int)'-' && *(vars->place) == '\0')
			return (-1);
		if (!*(vars->place))
			++(vars->optind);
		if (PRINT_ERROR) {
		//	warnx(illoptchar, optchar);
      }
		vars->optopt = optchar;
		return (BADCH);
	}
	if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
		/* -W long-option */
		if (*(vars->place))			/* no space */
			/* NOTHING */;
		else if (++(vars->optind) >= nargc) {	/* no arg */
			(vars->place) = EMSG;
			if (PRINT_ERROR) {
			//	warnx(recargchar, optchar);
         }
			vars->optopt = optchar;
			return (BADARG);
		} else				/* white space */
			(vars->place) = nargv[vars->optind];
		optchar = parse_long_options_TS(nargv, options, long_options, idx, 0,vars);
		(vars->place) = EMSG;
		return (optchar);
	}
	if (*++oli != ':') {			/* doesn't take argument */
		if (!*(vars->place))
			++(vars->optind);
	} else {				/* takes (optional) argument */
	   vars->optarg = NULL;
		if (*(vars->place))			/* no white space */
		   vars->optarg = (vars->place);
		/* XXX: disable test for :: if PC? (GNU doesn't) */
		else if (oli[1] != ':') {	/* arg not optional */
			if (++(vars->optind) >= nargc) {	/* no arg */
				(vars->place) = EMSG;
				if (PRINT_ERROR) {
				//	warnx(recargcha, optchar);
            }
				vars->optopt = optchar;
				return (BADARG);
			} else
			   vars->optarg = nargv[vars->optind];
		} else if (!(flags & FLAG_PERMUTE)) {
			/*
			 * If permutation is disabled, we can accept an
			 * optional arg separated by whitespace.
			 */
			if (vars->optind + 1 < nargc)
			   vars->optarg = nargv[++(vars->optind)];
		}
		(vars->place) = EMSG;
		++(vars->optind);
	}
	/* dump back option letter */
	return (optchar);
}