• 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  * Nevertheless, I would like to know about bugs in this library or
23  * suggestions for improvment.  Send bug reports and feedback to
24  * davegottner@delphi.com.
25  *---------------------------------------------------------------------------*/
26 
27 /* Modified to support --help and --version, as well as /? on Windows
28  * by Georg Brandl. */
29 
30 #include <Python.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <wchar.h>
34 #include "pycore_getopt.h"
35 
36 #ifdef __cplusplus
37 extern "C" {
38 #endif
39 
40 int _PyOS_opterr = 1;                 /* generate error messages */
41 Py_ssize_t _PyOS_optind = 1;          /* index into argv array   */
42 const wchar_t *_PyOS_optarg = NULL;   /* optional argument       */
43 
44 static const wchar_t *opt_ptr = L"";
45 
46 /* Python command line short and long options */
47 
48 #define SHORT_OPTS L"bBc:dEhiIJm:OqRsStuvVW:xX:?"
49 
50 static const _PyOS_LongOption longopts[] = {
51     {L"check-hash-based-pycs", 1, 0},
52     {NULL, 0, 0},
53 };
54 
55 
_PyOS_ResetGetOpt(void)56 void _PyOS_ResetGetOpt(void)
57 {
58     _PyOS_opterr = 1;
59     _PyOS_optind = 1;
60     _PyOS_optarg = NULL;
61     opt_ptr = L"";
62 }
63 
_PyOS_GetOpt(Py_ssize_t argc,wchar_t * const * argv,int * longindex)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             fprintf(stderr, "expected long option\n");
109             return -1;
110         }
111         *longindex = 0;
112         const _PyOS_LongOption *opt;
113         for (opt = &longopts[*longindex]; opt->name; opt = &longopts[++(*longindex)]) {
114             if (!wcscmp(opt->name, opt_ptr))
115                 break;
116         }
117         if (!opt->name) {
118             fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]);
119             return '_';
120         }
121         opt_ptr = L"";
122         if (!opt->has_arg) {
123             return opt->val;
124         }
125         if (_PyOS_optind >= argc) {
126             fprintf(stderr, "Argument expected for the %ls options\n",
127                     argv[_PyOS_optind - 1]);
128             return '_';
129         }
130         _PyOS_optarg = argv[_PyOS_optind++];
131         return opt->val;
132     }
133 
134     if (option == 'J') {
135         if (_PyOS_opterr)
136             fprintf(stderr, "-J is reserved for Jython\n");
137         return '_';
138     }
139 
140     if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) {
141         if (_PyOS_opterr)
142             fprintf(stderr, "Unknown option: -%c\n", (char)option);
143         return '_';
144     }
145 
146     if (*(ptr + 1) == L':') {
147         if (*opt_ptr != L'\0') {
148             _PyOS_optarg  = opt_ptr;
149             opt_ptr = L"";
150         }
151 
152         else {
153             if (_PyOS_optind >= argc) {
154                 if (_PyOS_opterr)
155                     fprintf(stderr,
156                         "Argument expected for the -%c option\n", (char)option);
157                 return '_';
158             }
159 
160             _PyOS_optarg = argv[_PyOS_optind++];
161         }
162     }
163 
164     return option;
165 }
166 
167 #ifdef __cplusplus
168 }
169 #endif
170 
171