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 33extern "C" { 34#endif 35 36int _PyOS_opterr = 1; /* generate error messages */ 37Py_ssize_t _PyOS_optind = 1; /* index into argv array */ 38const wchar_t *_PyOS_optarg = NULL; /* optional argument */ 39 40static 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 46static 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 56void _PyOS_ResetGetOpt(void) 57{ 58 _PyOS_opterr = 1; 59 _PyOS_optind = 1; 60 _PyOS_optarg = NULL; 61 opt_ptr = L""; 62} 63 64int _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 180