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