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

📄 getopt.c

📁 prozgui是一款Linxu下著名的下载工具
💻 C
📖 第 1 页 / 共 2 页
字号:
    /*     * Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been     * moved back by the user (who may also have changed the arguments).       */    if (last_nonopt > optind)      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 + -