• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:OqRsStuvVW:xX:?"
45  
46  static const _PyOS_LongOption longopts[] = {
47      {L"check-hash-based-pycs", 1, 0},
48      {NULL, 0, 0},
49  };
50  
51  
_PyOS_ResetGetOpt(void)52  void _PyOS_ResetGetOpt(void)
53  {
54      _PyOS_opterr = 1;
55      _PyOS_optind = 1;
56      _PyOS_optarg = NULL;
57      opt_ptr = L"";
58  }
59  
_PyOS_GetOpt(Py_ssize_t argc,wchar_t * const * argv,int * longindex)60  int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
61  {
62      wchar_t *ptr;
63      wchar_t option;
64  
65      if (*opt_ptr == '\0') {
66  
67          if (_PyOS_optind >= argc)
68              return -1;
69  #ifdef MS_WINDOWS
70          else if (wcscmp(argv[_PyOS_optind], L"/?") == 0) {
71              ++_PyOS_optind;
72              return 'h';
73          }
74  #endif
75  
76          else if (argv[_PyOS_optind][0] != L'-' ||
77                   argv[_PyOS_optind][1] == L'\0' /* lone dash */ )
78              return -1;
79  
80          else if (wcscmp(argv[_PyOS_optind], L"--") == 0) {
81              ++_PyOS_optind;
82              return -1;
83          }
84  
85          else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) {
86              ++_PyOS_optind;
87              return 'h';
88          }
89  
90          else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) {
91              ++_PyOS_optind;
92              return 'V';
93          }
94  
95          opt_ptr = &argv[_PyOS_optind++][1];
96      }
97  
98      if ((option = *opt_ptr++) == L'\0')
99          return -1;
100  
101      if (option == L'-') {
102          // Parse long option.
103          if (*opt_ptr == L'\0') {
104              if (_PyOS_opterr) {
105                  fprintf(stderr, "expected long option\n");
106              }
107              return -1;
108          }
109          *longindex = 0;
110          const _PyOS_LongOption *opt;
111          for (opt = &longopts[*longindex]; opt->name; opt = &longopts[++(*longindex)]) {
112              if (!wcscmp(opt->name, opt_ptr))
113                  break;
114          }
115          if (!opt->name) {
116              if (_PyOS_opterr) {
117                  fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]);
118              }
119              return '_';
120          }
121          opt_ptr = L"";
122          if (!opt->has_arg) {
123              return opt->val;
124          }
125          if (_PyOS_optind >= argc) {
126              if (_PyOS_opterr) {
127                  fprintf(stderr, "Argument expected for the %ls options\n",
128                          argv[_PyOS_optind - 1]);
129              }
130              return '_';
131          }
132          _PyOS_optarg = argv[_PyOS_optind++];
133          return opt->val;
134      }
135  
136      if (option == 'J') {
137          if (_PyOS_opterr) {
138              fprintf(stderr, "-J is reserved for Jython\n");
139          }
140          return '_';
141      }
142  
143      if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) {
144          if (_PyOS_opterr) {
145              fprintf(stderr, "Unknown option: -%c\n", (char)option);
146          }
147          return '_';
148      }
149  
150      if (*(ptr + 1) == L':') {
151          if (*opt_ptr != L'\0') {
152              _PyOS_optarg  = opt_ptr;
153              opt_ptr = L"";
154          }
155  
156          else {
157              if (_PyOS_optind >= argc) {
158                  if (_PyOS_opterr) {
159                      fprintf(stderr,
160                          "Argument expected for the -%c option\n", (char)option);
161                  }
162                  return '_';
163              }
164  
165              _PyOS_optarg = argv[_PyOS_optind++];
166          }
167      }
168  
169      return option;
170  }
171  
172  #ifdef __cplusplus
173  }
174  #endif
175  
176