コード例 #1
0
ファイル: getopt.c プロジェクト: bygreencn/rtmpdump
int _getopt_internal_r_a ( int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, struct _getopt_data_a *d, int posixly_correct )
{
	int print_errors = d->opterr;

	if ( argc < 1 )
	{
		return -1;
	}

	d->optarg = NULL;

	if ( d->optind == 0 || !d->__initialized )
	{
		if ( d->optind == 0 )
		{
			d->optind = 1;
		}

		optstring = _getopt_initialize_a ( optstring, d, posixly_correct );
		d->__initialized = 1;
	}
	else if ( optstring[0] == '-' || optstring[0] == '+' )
	{
		optstring++;
	}

	if ( optstring[0] == ':' )
	{
		print_errors = 0;
	}

	if ( d->__nextchar == NULL || *d->__nextchar == '\0' )
	{
		if ( d->__last_nonopt > d->optind )
		{
			d->__last_nonopt = d->optind;
		}

		if ( d->__first_nonopt > d->optind )
		{
			d->__first_nonopt = d->optind;
		}

		if ( d->__ordering == PERMUTE )
		{
			if ( d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind )
			{
				exchange_a ( ( char ** ) argv, d );
			}
			else if ( d->__last_nonopt != d->optind )
			{
				d->__first_nonopt = d->optind;
			}

			while ( d->optind < argc && ( argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' ) )
			{
				d->optind++;
			}

			d->__last_nonopt = d->optind;
		}

		if ( d->optind != argc && !strcmp ( argv[d->optind], "--" ) )
		{
			d->optind++;

			if ( d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind )
			{
				exchange_a ( ( char ** ) argv, d );
			}
			else if ( d->__first_nonopt == d->__last_nonopt )
			{
				d->__first_nonopt = d->optind;
			}

			d->__last_nonopt = argc;
			d->optind = argc;
		}

		if ( d->optind == argc )
		{
			if ( d->__first_nonopt != d->__last_nonopt )
			{
				d->optind = d->__first_nonopt;
			}

			return -1;
		}

		if ( ( argv[d->optind][0] != '-' || argv[d->optind][1] == '\0' ) )
		{
			if ( d->__ordering == REQUIRE_ORDER )
			{
				return -1;
			}

			d->optarg = argv[d->optind++];
			return 1;
		}

		d->__nextchar = ( argv[d->optind] + 1 + ( longopts != NULL && argv[d->optind][1] == '-' ) );
	}

	if ( longopts != NULL && ( argv[d->optind][1] == '-' || ( long_only && ( argv[d->optind][2] || !strchr ( optstring, argv[d->optind][1] ) ) ) ) )
	{
		char *nameend;
		unsigned int namelen;
		const struct option_a *p;
		const struct option_a *pfound = NULL;
		struct option_list
		{
			const struct option_a *p;
			struct option_list *next;
		} *ambig_list = NULL;
		int exact = 0;
		int indfound = -1;
		int option_index;

		for ( nameend = d->__nextchar; *nameend && *nameend != '='; nameend++ );

		namelen = ( unsigned int ) ( nameend - d->__nextchar );

		for ( p = longopts, option_index = 0; p->name; p++, option_index++ )
			if ( !strncmp ( p->name, d->__nextchar, namelen ) )
			{
				if ( namelen == ( unsigned int ) strlen ( p->name ) )
				{
					pfound = p;
					indfound = option_index;
					exact = 1;
					break;
				}
				else if ( pfound == NULL )
				{
					pfound = p;
					indfound = option_index;
				}
				else if ( long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val )
				{
					struct option_list *newp = ( struct option_list * ) alloca ( sizeof ( *newp ) );
					newp->p = p;
					newp->next = ambig_list;
					ambig_list = newp;
				}
			}

		if ( ambig_list != NULL && !exact )
		{
			if ( print_errors )
			{
				struct option_list first;
				first.p = pfound;
				first.next = ambig_list;
				ambig_list = &first;
				fprintf ( stderr, "%s: option '%s' is ambiguous; possibilities:", argv[0], argv[d->optind] );

				do
				{
					fprintf ( stderr, " '--%s'", ambig_list->p->name );
					ambig_list = ambig_list->next;
				}
				while ( ambig_list != NULL );

				fputc ( '\n', stderr );
			}

			d->__nextchar += strlen ( d->__nextchar );
			d->optind++;
			d->optopt = 0;
			return '?';
		}

		if ( pfound != NULL )
		{
			option_index = indfound;
			d->optind++;

			if ( *nameend )
			{
				if ( pfound->has_arg )
				{
					d->optarg = nameend + 1;
				}
				else
				{
					if ( print_errors )
					{
						if ( argv[d->optind - 1][1] == '-' )
						{
							fprintf ( stderr, "%s: option '--%s' doesn't allow an argument\n", argv[0], pfound->name );
						}
						else
						{
							fprintf ( stderr, "%s: option '%c%s' doesn't allow an argument\n", argv[0], argv[d->optind - 1][0], pfound->name );
						}
					}

					d->__nextchar += strlen ( d->__nextchar );
					d->optopt = pfound->val;
					return '?';
				}
			}
			else if ( pfound->has_arg == 1 )
			{
				if ( d->optind < argc )
				{
					d->optarg = argv[d->optind++];
				}
				else
				{
					if ( print_errors )
					{
						fprintf ( stderr, "%s: option '--%s' requires an argument\n", argv[0], pfound->name );
					}

					d->__nextchar += strlen ( d->__nextchar );
					d->optopt = pfound->val;
					return optstring[0] == ':' ? ':' : '?';
				}
			}

			d->__nextchar += strlen ( d->__nextchar );

			if ( longind != NULL )
			{
				*longind = option_index;
			}

			if ( pfound->flag )
			{
				* ( pfound->flag ) = pfound->val;
				return 0;
			}

			return pfound->val;
		}

		if ( !long_only || argv[d->optind][1] == '-' || strchr ( optstring, *d->__nextchar ) == NULL )
		{
			if ( print_errors )
			{
				if ( argv[d->optind][1] == '-' )
				{
					fprintf ( stderr, "%s: unrecognized option '--%s'\n", argv[0], d->__nextchar );
				}
				else
				{
					fprintf ( stderr, "%s: unrecognized option '%c%s'\n", argv[0], argv[d->optind][0], d->__nextchar );
				}
			}

			d->__nextchar = ( char * ) "";
			d->optind++;
			d->optopt = 0;
			return '?';
		}
	}

	{
		char c = *d->__nextchar++;
		char *temp = ( char * ) strchr ( optstring, c );

		if ( *d->__nextchar == '\0' )
		{
			++d->optind;
		}

		if ( temp == NULL || c == ':' || c == ';' )
		{
			if ( print_errors )
			{
				fprintf ( stderr, "%s: invalid option -- '%c'\n", argv[0], c );
			}

			d->optopt = c;
			return '?';
		}

		if ( temp[0] == 'W' && temp[1] == ';' )
		{
			char *nameend;
			const struct option_a *p;
			const struct option_a *pfound = NULL;
			int exact = 0;
			int ambig = 0;
			int indfound = 0;
			int option_index;

			if ( longopts == NULL )
			{
				goto no_longs;
			}

			if ( *d->__nextchar != '\0' )
			{
				d->optarg = d->__nextchar;
				d->optind++;
			}
			else if ( d->optind == argc )
			{
				if ( print_errors )
				{
					fprintf ( stderr, "%s: option requires an argument -- '%c'\n", argv[0], c );
				}

				d->optopt = c;

				if ( optstring[0] == ':' )
				{
					c = ':';
				}
				else
				{
					c = '?';
				}

				return c;
			}
			else
			{
				d->optarg = argv[d->optind++];
			}

			for ( d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; nameend++ );

			for ( p = longopts, option_index = 0; p->name; p++, option_index++ )
				if ( !strncmp ( p->name, d->__nextchar, nameend - d->__nextchar ) )
				{
					if ( ( unsigned int ) ( nameend - d->__nextchar ) == strlen ( p->name ) )
					{
						pfound = p;
						indfound = option_index;
						exact = 1;
						break;
					}
					else if ( pfound == NULL )
					{
						pfound = p;
						indfound = option_index;
					}
					else if ( long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val )
					{
						ambig = 1;
					}
				}

			if ( ambig && !exact )
			{
				if ( print_errors )
				{
					fprintf ( stderr, "%s: option '-W %s' is ambiguous\n", argv[0], d->optarg );
				}

				d->__nextchar += strlen ( d->__nextchar );
				d->optind++;
				return '?';
			}

			if ( pfound != NULL )
			{
				option_index = indfound;

				if ( *nameend )
				{
					if ( pfound->has_arg )
					{
						d->optarg = nameend + 1;
					}
					else
					{
						if ( print_errors )
						{
							fprintf ( stderr, "%s: option '-W %s' doesn't allow an argument\n", argv[0], pfound->name );
						}

						d->__nextchar += strlen ( d->__nextchar );
						return '?';
					}
				}
				else if ( pfound->has_arg == 1 )
				{
					if ( d->optind < argc )
					{
						d->optarg = argv[d->optind++];
					}
					else
					{
						if ( print_errors )
						{
							fprintf ( stderr, "%s: option '-W %s' requires an argument\n", argv[0], pfound->name );
						}

						d->__nextchar += strlen ( d->__nextchar );
						return optstring[0] == ':' ? ':' : '?';
					}
				}
				else
				{
					d->optarg = NULL;
				}

				d->__nextchar += strlen ( d->__nextchar );

				if ( longind != NULL )
				{
					*longind = option_index;
				}

				if ( pfound->flag )
				{
					* ( pfound->flag ) = pfound->val;
					return 0;
				}

				return pfound->val;
			}

no_longs:
			d->__nextchar = NULL;
			return 'W';
		}

		if ( temp[1] == ':' )
		{
			if ( temp[2] == ':' )
			{
				if ( *d->__nextchar != '\0' )
				{
					d->optarg = d->__nextchar;
					d->optind++;
				}
				else
				{
					d->optarg = NULL;
				}

				d->__nextchar = NULL;
			}
			else
			{
				if ( *d->__nextchar != '\0' )
				{
					d->optarg = d->__nextchar;
					d->optind++;
				}
				else if ( d->optind == argc )
				{
					if ( print_errors )
					{
						fprintf ( stderr, "%s: option requires an argument -- '%c'\n", argv[0], c );
					}

					d->optopt = c;

					if ( optstring[0] == ':' )
					{
						c = ':';
					}
					else
					{
						c = '?';
					}
				}
				else
				{
					d->optarg = argv[d->optind++];
				}

				d->__nextchar = NULL;
			}
		}

		return c;
	}
}
コード例 #2
0
int _getopt_internal_r_a (int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, struct _getopt_data_a *d, int posixly_correct)
{
	int print_errors = d->opterr;

	if (argc < 1)
		return -1;

	d->optarg = NULL;

	if (d->optind == 0 || !d->__initialized)
	{
		if (d->optind == 0)
			d->optind = 1;
		optstring = _getopt_initialize_a (optstring, d, posixly_correct);
		d->__initialized = 1;
	}
	else if (optstring[0] == '-' || optstring[0] == '+')
		optstring++;
	if (optstring[0] == ':')
		print_errors = 0;

	if (d->__nextchar == NULL || *d->__nextchar == '\0')
	{
		if (d->__last_nonopt > d->optind)
			d->__last_nonopt = d->optind;
		if (d->__first_nonopt > d->optind)
			d->__first_nonopt = d->optind;

		if (d->__ordering == PERMUTE)
		{
			if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
				exchange_a ((char **) argv, d);
			else if (d->__last_nonopt != d->optind)
				d->__first_nonopt = d->optind;

			while (d->optind < argc && (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0'))
				d->optind++;
			d->__last_nonopt = d->optind;
		}

		if (d->optind != argc && !strcmp(argv[d->optind], "--"))
		{
			d->optind++;

			if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
				exchange_a((char **) argv, d);
			else if (d->__first_nonopt == d->__last_nonopt)
				d->__first_nonopt = d->optind;
			d->__last_nonopt = argc;

			d->optind = argc;
		}

		if (d->optind == argc)
		{
			if (d->__first_nonopt != d->__last_nonopt)
				d->optind = d->__first_nonopt;
			return -1;
		}

		if ((argv[d->optind][0] != '-' || argv[d->optind][1] == '\0'))
		{
			if (d->__ordering == REQUIRE_ORDER)
				return -1;
			d->optarg = argv[d->optind++];
			return 1;
		}

		d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == '-'));
	}

	if (longopts != NULL && (argv[d->optind][1] == '-' || (long_only && (argv[d->optind][2] || !strchr(optstring, argv[d->optind][1])))))
	{
		char *nameend;
		const struct option_a *p;
		const struct option_a *pfound = NULL;
		int exact = 0;
		int ambig = 0;
		int indfound = -1;
		int option_index;

		for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++);

		for (p = longopts, option_index = 0; p->name; p++, option_index++)
			if (!strncmp(p->name, d->__nextchar, nameend - d->__nextchar))
			{
				if ((unsigned int)(nameend - d->__nextchar) == (unsigned int)strlen(p->name))
				{
					pfound = p;
					indfound = option_index;
					exact = 1;
					break;
				}
				else if (pfound == NULL)
				{
					pfound = p;
					indfound = option_index;
				}
				else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
					ambig = 1;
			}

			if (ambig && !exact)
			{
				if (print_errors)
				{
					fprintf(stderr, "%s: option '%s' is ambiguous\n",
						argv[0], argv[d->optind]);
				}
				d->__nextchar += strlen(d->__nextchar);
				d->optind++;
				d->optopt = 0;
				return '?';
			}

			if (pfound != NULL)
			{
				option_index = indfound;
				d->optind++;
				if (*nameend)
				{
					if (pfound->has_arg)
						d->optarg = nameend + 1;
					else
					{
						if (print_errors)
						{
							if (argv[d->optind - 1][1] == '-')
							{
								fprintf(stderr, "%s: option '--%s' doesn't allow an argument\n",argv[0], pfound->name);
							}
							else
							{
								fprintf(stderr, "%s: option '%c%s' doesn't allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name);
							}

						}

						d->__nextchar += strlen(d->__nextchar);

						d->optopt = pfound->val;
						return '?';
					}
				}
				else if (pfound->has_arg == 1)
				{
					if (d->optind < argc)
						d->optarg = argv[d->optind++];
					else
					{
						if (print_errors)
						{
							fprintf(stderr,"%s: option '--%s' requires an argument\n",argv[0], pfound->name);
						}
						d->__nextchar += strlen(d->__nextchar);
						d->optopt = pfound->val;
						return optstring[0] == ':' ? ':' : '?';
					}
				}
				d->__nextchar += strlen(d->__nextchar);
				if (longind != NULL)
					*longind = option_index;
				if (pfound->flag)
				{
					*(pfound->flag) = pfound->val;
					return 0;
				}
				return pfound->val;
			}

			if (!long_only || argv[d->optind][1] == '-' || strchr(optstring, *d->__nextchar) == NULL)
			{
				if (print_errors)
				{
					if (argv[d->optind][1] == '-')
					{
						/* --option */
						fprintf(stderr, "%s: unrecognized option '--%s'\n",argv[0], d->__nextchar);
					}
					else
					{
						/* +option or -option */
						fprintf(stderr, "%s: unrecognized option '%c%s'\n",argv[0], argv[d->optind][0], d->__nextchar);
					}
				}
				d->__nextchar = (char *)"";
				d->optind++;
				d->optopt = 0;
				return '?';
			}
	}

	{
		char c = *d->__nextchar++;
		char *temp = (char*)strchr(optstring, c);

		if (*d->__nextchar == '\0')
			++d->optind;

		if (temp == NULL || c == ':' || c == ';')
		{
			if (print_errors)
			{
				fprintf(stderr, "%s: invalid option -- '%c'\n", argv[0], c);
			}
			d->optopt = c;
			return '?';
		}
		if (temp[0] == 'W' && temp[1] == ';')
		{
			char *nameend;
			const struct option_a *p;
			const struct option_a *pfound = NULL;
			int exact = 0;
			int ambig = 0;
			int indfound = 0;
			int option_index;

			if (*d->__nextchar != '\0')
			{
				d->optarg = d->__nextchar;
				d->optind++;
			}
			else if (d->optind == argc)
			{
				if (print_errors)
				{
					fprintf(stderr,
						"%s: option requires an argument -- '%c'\n",
						argv[0], c);
				}
				d->optopt = c;
				if (optstring[0] == ':')
					c = ':';
				else
					c = '?';
				return c;
			}
			else
				d->optarg = argv[d->optind++];

			for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != '='; nameend++);

			for (p = longopts, option_index = 0; p->name; p++, option_index++)
				if (!strncmp(p->name, d->__nextchar, nameend - d->__nextchar))
				{
					if ((unsigned int) (nameend - d->__nextchar) == strlen(p->name))
					{
						pfound = p;
						indfound = option_index;
						exact = 1;
						break;
					}
					else if (pfound == NULL)
					{
						pfound = p;
						indfound = option_index;
					}
					else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
						ambig = 1;
				}
				if (ambig && !exact)
				{
					if (print_errors)
					{
						fprintf(stderr, "%s: option '-W %s' is ambiguous\n",
							argv[0], d->optarg);
					}
					d->__nextchar += strlen(d->__nextchar);
					d->optind++;
					return '?';
				}
				if (pfound != NULL)
				{
					option_index = indfound;
					if (*nameend)
					{
						if (pfound->has_arg)
							d->optarg = nameend + 1;
						else
						{
							if (print_errors)
							{
								fprintf(stderr, "\
												%s: option '-W %s' doesn't allow an argument\n",
												argv[0], pfound->name);
							}

							d->__nextchar += strlen(d->__nextchar);
							return '?';
						}
					}
					else if (pfound->has_arg == 1)
					{
						if (d->optind < argc)
							d->optarg = argv[d->optind++];
						else
						{
							if (print_errors)
							{
								fprintf(stderr, "\
												%s: option '-W %s' requires an argument\n",
												argv[0], pfound->name);
							}
							d->__nextchar += strlen(d->__nextchar);
							return optstring[0] == ':' ? ':' : '?';
						}
					}
					else