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

📄 getopt.c

📁 AAC编解码源码
💻 C
📖 第 1 页 / 共 2 页
字号:

      /* Now skip any additional non-options
         and extend the range of non-options previously skipped.  */

      while (optind < argc
         && (argv[optind][0] != '-' || argv[optind][1] == '\0')
#ifdef GETOPT_COMPAT
         && (longopts == NULL
             || argv[optind][0] != '+' || argv[optind][1] == '\0')
#endif              /* GETOPT_COMPAT */
         )
        optind++;
      last_nonopt = optind;
    }

      /* 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 EOF;
    }

      /* 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 ((argv[optind][0] != '-' || argv[optind][1] == '\0')
#ifdef GETOPT_COMPAT
      && (longopts == NULL
          || argv[optind][0] != '+' || argv[optind][1] == '\0')
#endif              /* GETOPT_COMPAT */
      )
    {
      if (ordering == REQUIRE_ORDER)
        return EOF;
      optarg = argv[optind++];
      return 1;
    }

      /* We have found another option-ARGV-element.
     Start decoding its characters.  */

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

  if (longopts != NULL
      && ((argv[optind][0] == '-'
       && (argv[optind][1] == '-' || long_only))
#ifdef GETOPT_COMPAT
      || argv[optind][0] == '+'
#endif              /* GETOPT_COMPAT */
      ))
    {
      const struct option *p;
      char *s = nextchar;
      int exact = 0;
      int ambig = 0;
      const struct option *pfound = NULL;
      int indfound = 0;

      while (*s && *s != '=')
    s++;

      /* Test all options for either exact match or abbreviated matches.  */
      for (p = longopts, option_index = 0; p->name;
       p++, option_index++)
    if (!strncmp (p->name, nextchar, s - nextchar))
      {
        if (s - nextchar == my_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 nonexact match found.  */
          ambig = 1;
      }

      if (ambig && !exact)
    {
      if (opterr)
        fprintf (stderr, "%s: option `%s' is ambiguous\n",
             argv[0], argv[optind]);
      nextchar += my_strlen (nextchar);
      optind++;
      return BAD_OPTION;
    }

      if (pfound != NULL)
    {
      option_index = indfound;
      optind++;
      if (*s)
        {
          /* Don't test has_arg with >, because some C compilers don't
         allow it to be used on enums.  */
          if (pfound->has_arg)
        optarg = s + 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 += my_strlen (nextchar);
          return BAD_OPTION;
        }
        }
      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 += my_strlen (nextchar);
          return optstring[0] == ':' ? ':' : BAD_OPTION;
        }
        }
      nextchar += my_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] == '-'
#ifdef GETOPT_COMPAT
      || argv[optind][0] == '+'
#endif              /* GETOPT_COMPAT */
      || 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++;
      return BAD_OPTION;
    }
    }

  /* Look at and handle the next 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 0
        if (c < 040 || c >= 0177)
          fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
               argv[0], c);
        else
          fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
#else
        /* 1003.2 specifies the format of this message.  */
        fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
#endif
      }
    optopt = c;
    return BAD_OPTION;
      }
    if (temp[1] == ':')
      {
    if (temp[2] == ':')
      {
        /* This is an option that accepts an argument optionally.  */
        if (*nextchar != '\0')
          {
        optarg = nextchar;
        optind++;
          }
        else
          optarg = 0;
        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)
          {
#if 0
            fprintf (stderr, "%s: option `-%c' requires an argument\n",
                 argv[0], c);
#else
            /* 1003.2 specifies the format of this message.  */
            fprintf (stderr, "%s: option requires an argument -- %c\n",
                 argv[0], c);
#endif
          }
        optopt = c;
        if (optstring[0] == ':')
          c = ':';
        else
          c = BAD_OPTION;
          }
        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);
}

int
getopt_long (argc, argv, options, long_options, opt_index)
     int argc;
     char *const *argv;
     const char *options;
     const struct option *long_options;
     int *opt_index;
{
  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
}

#endif  /* _LIBC or not __GNU_LIBRARY__.  */

#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 == EOF)
    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 BAD_OPTION:
      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 + -