(root)/
Python-3.12.0/
Python/
getopt.c
       1  /*---------------------------------------------------------------------------*
       2   * <RCS keywords>
       3   *
       4   * C++ Library
       5   *
       6   * Copyright 1992-1994, David Gottner
       7   *
       8   *                    All Rights Reserved
       9   *
      10   * Permission to use, copy, modify, and distribute this software and its
      11   * documentation for any purpose and without fee is hereby granted,
      12   * provided that the above copyright notice, this permission notice and
      13   * the following disclaimer notice appear unmodified in all copies.
      14   *
      15   * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
      16   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL I
      17   * BE LIABLE FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
      18   * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER
      19   * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
      20   * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      21   *---------------------------------------------------------------------------*/
      22  
      23  /* Modified to support --help and --version, as well as /? on Windows
      24   * by Georg Brandl. */
      25  
      26  #include <Python.h>
      27  #include <stdio.h>
      28  #include <string.h>
      29  #include <wchar.h>
      30  #include "pycore_getopt.h"
      31  
      32  #ifdef __cplusplus
      33  extern "C" {
      34  #endif
      35  
      36  int _PyOS_opterr = 1;                 /* generate error messages */
      37  Py_ssize_t _PyOS_optind = 1;          /* index into argv array   */
      38  const wchar_t *_PyOS_optarg = NULL;   /* optional argument       */
      39  
      40  static const wchar_t *opt_ptr = L"";
      41  
      42  /* Python command line short and long options */
      43  
      44  #define SHORT_OPTS L"bBc:dEhiIJm:OPqRsStuvVW:xX:?"
      45  
      46  static const _PyOS_LongOption longopts[] = {
      47      /* name, has_arg, val (used in switch in initconfig.c) */
      48      {L"check-hash-based-pycs", 1, 0},
      49      {L"help-all", 0, 1},
      50      {L"help-env", 0, 2},
      51      {L"help-xoptions", 0, 3},
      52      {NULL, 0, -1},                     /* sentinel */
      53  };
      54  
      55  
      56  void _PyOS_ResetGetOpt(void)
      57  {
      58      _PyOS_opterr = 1;
      59      _PyOS_optind = 1;
      60      _PyOS_optarg = NULL;
      61      opt_ptr = L"";
      62  }
      63  
      64  int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
      65  {
      66      wchar_t *ptr;
      67      wchar_t option;
      68  
      69      if (*opt_ptr == '\0') {
      70  
      71          if (_PyOS_optind >= argc)
      72              return -1;
      73  #ifdef MS_WINDOWS
      74          else if (wcscmp(argv[_PyOS_optind], L"/?") == 0) {
      75              ++_PyOS_optind;
      76              return 'h';
      77          }
      78  #endif
      79  
      80          else if (argv[_PyOS_optind][0] != L'-' ||
      81                   argv[_PyOS_optind][1] == L'\0' /* lone dash */ )
      82              return -1;
      83  
      84          else if (wcscmp(argv[_PyOS_optind], L"--") == 0) {
      85              ++_PyOS_optind;
      86              return -1;
      87          }
      88  
      89          else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) {
      90              ++_PyOS_optind;
      91              return 'h';
      92          }
      93  
      94          else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) {
      95              ++_PyOS_optind;
      96              return 'V';
      97          }
      98  
      99          opt_ptr = &argv[_PyOS_optind++][1];
     100      }
     101  
     102      if ((option = *opt_ptr++) == L'\0')
     103          return -1;
     104  
     105      if (option == L'-') {
     106          // Parse long option.
     107          if (*opt_ptr == L'\0') {
     108              if (_PyOS_opterr) {
     109                  fprintf(stderr, "expected long option\n");
     110              }
     111              return -1;
     112          }
     113          *longindex = 0;
     114          const _PyOS_LongOption *opt;
     115          for (opt = &longopts[*longindex]; opt->name; opt = &longopts[++(*longindex)]) {
     116              if (!wcscmp(opt->name, opt_ptr))
     117                  break;
     118          }
     119          if (!opt->name) {
     120              if (_PyOS_opterr) {
     121                  fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]);
     122              }
     123              return '_';
     124          }
     125          opt_ptr = L"";
     126          if (!opt->has_arg) {
     127              return opt->val;
     128          }
     129          if (_PyOS_optind >= argc) {
     130              if (_PyOS_opterr) {
     131                  fprintf(stderr, "Argument expected for the %ls options\n",
     132                          argv[_PyOS_optind - 1]);
     133              }
     134              return '_';
     135          }
     136          _PyOS_optarg = argv[_PyOS_optind++];
     137          return opt->val;
     138      }
     139  
     140      if (option == 'J') {
     141          if (_PyOS_opterr) {
     142              fprintf(stderr, "-J is reserved for Jython\n");
     143          }
     144          return '_';
     145      }
     146  
     147      if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) {
     148          if (_PyOS_opterr) {
     149              fprintf(stderr, "Unknown option: -%c\n", (char)option);
     150          }
     151          return '_';
     152      }
     153  
     154      if (*(ptr + 1) == L':') {
     155          if (*opt_ptr != L'\0') {
     156              _PyOS_optarg  = opt_ptr;
     157              opt_ptr = L"";
     158          }
     159  
     160          else {
     161              if (_PyOS_optind >= argc) {
     162                  if (_PyOS_opterr) {
     163                      fprintf(stderr,
     164                          "Argument expected for the -%c option\n", (char)option);
     165                  }
     166                  return '_';
     167              }
     168  
     169              _PyOS_optarg = argv[_PyOS_optind++];
     170          }
     171      }
     172  
     173      return option;
     174  }
     175  
     176  #ifdef __cplusplus
     177  }
     178  #endif
     179