⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 getopt.c

📁 linux下的网络下载工具prozilla的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	    last_nonopt = optind;	if (first_nonopt > optind)	    first_nonopt = optind;	if (ordering == PERMUTE)	{	    /*	     * If we have just processed some options following some non-options,	     * exchange them so that the options come first.  	     */	    if (first_nonopt != last_nonopt && last_nonopt != optind)		exchange((char **) argv);	    else if (last_nonopt != optind)		first_nonopt = optind;	    /*	     * Skip any additional non-options	     * and extend the range of non-options previously skipped.  	     */	    while (optind < argc && NONOPTION_P)		optind++;	    last_nonopt = optind;	}	/*	 * The special ARGV-element `--' means premature end of options.	 * Skip it like a null option,	 * then exchange with previous non-options as if it were an option,	 * then skip everything else like a non-option.  	 */	if (optind != argc && !strcmp(argv[optind], "--"))	{	    optind++;	    if (first_nonopt != last_nonopt && last_nonopt != optind)		exchange((char **) argv);	    else if (first_nonopt == last_nonopt)		first_nonopt = optind;	    last_nonopt = argc;	    optind = argc;	}	/*	 * If we have done all the ARGV-elements, stop the scan	 * and back over any non-options that we skipped and permuted.  	 */	if (optind == argc)	{	    /*	     * Set the next-arg-index to point at the non-options	     * that we previously skipped, so the caller will digest them.  	     */	    if (first_nonopt != last_nonopt)		optind = first_nonopt;	    return -1;	}	/*	 * If we have come to a non-option and did not permute it,	 * either stop the scan or describe it to the caller and pass it by.  	 */	if (NONOPTION_P)	{	    if (ordering == REQUIRE_ORDER)		return -1;	    optarg = argv[optind++];	    return 1;	}	/*	 * We have found another option-ARGV-element.	 * Skip the initial punctuation.  	 */	nextchar = (argv[optind] + 1		    + (longopts != NULL && argv[optind][1] == '-'));    }    /*     * Decode the current option-ARGV-element.       */    /*     * Check whether the ARGV-element is a long option.     *      * If long_only and the ARGV-element has the form "-f", where f is     * a valid short option, don't consider it an abbreviated form of     * a long option that starts with f.  Otherwise there would be no     * way to give the -f short option.     *      * On the other hand, if there's a long option "fubar" and     * the ARGV-element is "-fu", do consider that an abbreviation of     * the long option, just like "--fu", and not "-f" with arg "u".     *      * This distinction seems to be the most useful approach.       */    if (longopts != NULL	&& (argv[optind][1] == '-'	    || (long_only		&& (argv[optind][2]		    || !my_index(optstring, argv[optind][1])))))    {	char *nameend;	const struct option *p;	const struct option *pfound = NULL;	int exact = 0;	int ambig = 0;	int indfound = -1;	int option_index;	for (nameend = nextchar; *nameend && *nameend != '='; nameend++)	    /*	     * Do nothing.  	     */ ;	/*	 * Test all long options for either exact match	 * or abbreviated matches.  	 */	for (p = longopts, option_index = 0; p->name; p++, option_index++)	    if (!strncmp(p->name, nextchar, nameend - nextchar))	    {		if ((unsigned int) (nameend - nextchar)		    == (unsigned int) strlen(p->name))		{		    /*		     * Exact match found.  		     */		    pfound = p;		    indfound = option_index;		    exact = 1;		    break;		} else if (pfound == NULL)		{		    /*		     * First nonexact match found.  		     */		    pfound = p;		    indfound = option_index;		} else		    /*		     * Second or later nonexact match found.  		     */		    ambig = 1;	    }	if (ambig && !exact)	{	    if (opterr)		fprintf(stderr, _("%s: option `%s' is ambiguous\n"),			argv[0], argv[optind]);	    nextchar += strlen(nextchar);	    optind++;	    optopt = 0;	    return '?';	}	if (pfound != NULL)	{	    option_index = indfound;	    optind++;	    if (*nameend)	    {		/*		 * Don't test has_arg with >, because some C compilers don't		 * allow it to be used on enums.  		 */		if (pfound->has_arg)		    optarg = nameend + 1;		else		{		    if (opterr)			if (argv[optind - 1][1] == '-')			    /*			     * --option 			     */			    fprintf(stderr,				    _				    ("%s: option `--%s' doesn't allow an argument\n"),				    argv[0], pfound->name);			else			    /*			     * +option or -option 			     */			    fprintf(stderr,				    _				    ("%s: option `%c%s' doesn't allow an argument\n"),				    argv[0], argv[optind - 1][0],				    pfound->name);		    nextchar += strlen(nextchar);		    optopt = pfound->val;		    return '?';		}	    } else if (pfound->has_arg == 1)	    {		if (optind < argc)		    optarg = argv[optind++];		else		{		    if (opterr)			fprintf(stderr,				_				("%s: option `%s' requires an argument\n"),				argv[0], argv[optind - 1]);		    nextchar += strlen(nextchar);		    optopt = pfound->val;		    return optstring[0] == ':' ? ':' : '?';		}	    }	    nextchar += strlen(nextchar);	    if (longind != NULL)		*longind = option_index;	    if (pfound->flag)	    {		*(pfound->flag) = pfound->val;		return 0;	    }	    return pfound->val;	}	/*	 * Can't find it as a long option.  If this is not getopt_long_only,	 * or the option starts with '--' or is not a valid short	 * option, then it's an error.	 * Otherwise interpret it as a short option.  	 */	if (!long_only || argv[optind][1] == '-'	    || my_index(optstring, *nextchar) == NULL)	{	    if (opterr)	    {		if (argv[optind][1] == '-')		    /*		     * --option 		     */		    fprintf(stderr, _("%s: unrecognized option `--%s'\n"),			    argv[0], nextchar);		else		    /*		     * +option or -option 		     */		    fprintf(stderr, _("%s: unrecognized option `%c%s'\n"),			    argv[0], argv[optind][0], nextchar);	    }	    nextchar = (char *) "";	    optind++;	    optopt = 0;	    return '?';	}    }    /*     * Look at and handle the next short option-character.       */    {	char c = *nextchar++;	char *temp = my_index(optstring, c);	/*	 * Increment `optind' when we start to process its last character.  	 */	if (*nextchar == '\0')	    ++optind;	if (temp == NULL || c == ':')	{	    if (opterr)	    {		if (posixly_correct)		    /*		     * 1003.2 specifies the format of this message.  		     */		    fprintf(stderr, _("%s: illegal option -- %c\n"),			    argv[0], c);		else		    fprintf(stderr, _("%s: invalid option -- %c\n"),			    argv[0], c);	    }	    optopt = c;	    return '?';	}	/*	 * Convenience. Treat POSIX -W foo same as long option --foo 	 */	if (temp[0] == 'W' && temp[1] == ';')	{	    char *nameend;	    const struct option *p;	    const struct option *pfound = NULL;	    int exact = 0;	    int ambig = 0;	    int indfound = 0;	    int option_index;	    /*	     * This is an option that requires an argument.  	     */	    if (*nextchar != '\0')	    {		optarg = nextchar;		/*		 * If we end this ARGV-element by taking the rest as an arg,		 * we must advance to the next element now.  		 */		optind++;	    } else if (optind == argc)	    {		if (opterr)		{		    /*		     * 1003.2 specifies the format of this message.  		     */		    fprintf(stderr,			    _("%s: option requires an argument -- %c\n"),			    argv[0], c);		}		optopt = c;		if (optstring[0] == ':')		    c = ':';		else		    c = '?';		return c;	    } else		/*		 * We already incremented `optind' once;		 * increment it again when taking next ARGV-elt as argument.  		 */		optarg = argv[optind++];	    /*	     * optarg is now the argument, see if it's in the	     * table of longopts.  	     */	    for (nextchar = nameend = optarg; *nameend && *nameend != '=';		 nameend++)		/*		 * Do nothing.  		 */ ;	    /*	     * Test all long options for either exact match	     * or abbreviated matches.  	     */	    for (p = longopts, option_index = 0; p->name;		 p++, option_index++)		if (!strncmp(p->name, nextchar, nameend - nextchar))		{		    if ((unsigned int) (nameend - nextchar) ==			strlen(p->name))		    {			/*			 * Exact match found.  			 */			pfound = p;			indfound = option_index;			exact = 1;			break;		    } else if (pfound == NULL)		    {			/*			 * First nonexact match found.  			 */			pfound = p;			indfound = option_index;		    } else			/*			 * Second or later nonexact match found.  			 */			ambig = 1;		}	    if (ambig && !exact)	    {		if (opterr)		    fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"),			    argv[0], argv[optind]);		nextchar += strlen(nextchar);		optind++;		return '?';	    }	    if (pfound != NULL)	    {		option_index = indfound;		if (*nameend)		{		    /*		     * Don't test has_arg with >, because some C compilers don't		     * allow it to be used on enums.  		     */		    if (pfound->has_arg)			optarg = nameend + 1;		    else		    {			if (opterr)			    fprintf(stderr, _("\%s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name);			nextchar += strlen(nextchar);			return '?';		    }		} else if (pfound->has_arg == 1)		{		    if (optind < argc)			optarg = argv[optind++];		    else		    {			if (opterr)			    fprintf(stderr,				    _				    ("%s: option `%s' requires an argument\n"),				    argv[0], argv[optind - 1]);			nextchar += strlen(nextchar);			return optstring[0] == ':' ? ':' : '?';		    }		}		nextchar += strlen(nextchar);		if (longind != NULL)		    *longind = option_index;		if (pfound->flag)		{		    *(pfound->flag) = pfound->val;		    return 0;		}		return pfound->val;	    }	    nextchar = NULL;	    return 'W';		/*				 * Let the application handle it.   				 */	}	if (temp[1] == ':')	{	    if (temp[2] == ':')	    {		/*		 * This is an option that accepts an argument optionally.  		 */		if (*nextchar != '\0')		{		    optarg = nextchar;		    optind++;		} else		    optarg = NULL;		nextchar = NULL;	    } else	    {		/*		 * This is an option that requires an argument.  		 */		if (*nextchar != '\0')		{		    optarg = nextchar;		    /*		     * If we end this ARGV-element by taking the rest as an arg,		     * we must advance to the next element now.  		     */		    optind++;		} else if (optind == argc)		{		    if (opterr)		    {			/*			 * 1003.2 specifies the format of this message.  			 */			fprintf(stderr,				_				("%s: option requires an argument -- %c\n"),				argv[0], c);		    }		    optopt = c;		    if (optstring[0] == ':')			c = ':';		    else			c = '?';		} else		    /*		     * We already incremented `optind' once;		     * increment it again when taking next ARGV-elt as argument.  		     */		    optarg = argv[optind++];		nextchar = NULL;	    }	}	return c;    }}int getopt(argc, argv, optstring)int argc;char *const *argv;const char *optstring;{    return _getopt_internal(argc, argv, optstring,			    (const struct option *) 0, (int *) 0, 0);}#endif				/*				 * Not ELIDE_CODE.  				 */#ifdef TEST/* Compile with -DTEST to make an executable for use in testing   the above definition of `getopt'.  */int main(argc, argv)int argc;char **argv;{    int c;    int digit_optind = 0;    while (1)    {	int this_option_optind = optind ? optind : 1;	c = getopt(argc, argv, "abc:d:0123456789");	if (c == -1)	    break;	switch (c)	{	case '0':	case '1':	case '2':	case '3':	case '4':	case '5':	case '6':	case '7':	case '8':	case '9':	    if (digit_optind != 0 && digit_optind != this_option_optind)		printf("digits occur in two different argv-elements.\n");	    digit_optind = this_option_optind;	    printf("option %c\n", c);	    break;	case 'a':	    printf("option a\n");	    break;	case 'b':	    printf("option b\n");	    break;	case 'c':	    printf("option c with value `%s'\n", optarg);	    break;	case '?':	    break;	default:	    printf("?? getopt returned character code 0%o ??\n", c);	}    }    if (optind < argc)    {	printf("non-option ARGV-elements: ");	while (optind < argc)	    printf("%s ", argv[optind++]);	printf("\n");    }    exit(0);}#endif				/*				 * TEST 				 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -