Coverage Report

Created: 2025-07-04 06:49

/src/cpython/Python/getopt.c
Line
Count
Source (jump to first uncovered line)
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
int _PyOS_opterr = 1;                 /* generate error messages */
33
Py_ssize_t _PyOS_optind = 1;          /* index into argv array   */
34
const wchar_t *_PyOS_optarg = NULL;   /* optional argument       */
35
36
static const wchar_t *opt_ptr = L"";
37
38
/* Python command line short and long options */
39
40
0
#define SHORT_OPTS L"bBc:dEhiIm:OPqRsStuvVW:xX:?"
41
42
static const _PyOS_LongOption longopts[] = {
43
    /* name, has_arg, val (used in switch in initconfig.c) */
44
    {L"check-hash-based-pycs", 1, 0},
45
    {L"help-all", 0, 1},
46
    {L"help-env", 0, 2},
47
    {L"help-xoptions", 0, 3},
48
    {NULL, 0, -1},                     /* sentinel */
49
};
50
51
52
void _PyOS_ResetGetOpt(void)
53
0
{
54
0
    _PyOS_opterr = 1;
55
0
    _PyOS_optind = 1;
56
0
    _PyOS_optarg = NULL;
57
0
    opt_ptr = L"";
58
0
}
59
60
int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
61
0
{
62
0
    wchar_t *ptr;
63
0
    wchar_t option;
64
65
0
    if (*opt_ptr == '\0') {
66
67
0
        if (_PyOS_optind >= argc)
68
0
            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
0
        else if (argv[_PyOS_optind][0] != L'-' ||
77
0
                 argv[_PyOS_optind][1] == L'\0' /* lone dash */ )
78
0
            return -1;
79
80
0
        else if (wcscmp(argv[_PyOS_optind], L"--") == 0) {
81
0
            ++_PyOS_optind;
82
0
            return -1;
83
0
        }
84
85
0
        else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) {
86
0
            ++_PyOS_optind;
87
0
            return 'h';
88
0
        }
89
90
0
        else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) {
91
0
            ++_PyOS_optind;
92
0
            return 'V';
93
0
        }
94
95
0
        opt_ptr = &argv[_PyOS_optind++][1];
96
0
    }
97
98
0
    if ((option = *opt_ptr++) == L'\0')
99
0
        return -1;
100
101
0
    if (option == L'-') {
102
        // Parse long option.
103
0
        if (*opt_ptr == L'\0') {
104
0
            if (_PyOS_opterr) {
105
0
                fprintf(stderr, "Expected long option\n");
106
0
            }
107
0
            return -1;
108
0
        }
109
0
        *longindex = 0;
110
0
        const _PyOS_LongOption *opt;
111
0
        for (opt = &longopts[*longindex]; opt->name; opt = &longopts[++(*longindex)]) {
112
0
            if (!wcscmp(opt->name, opt_ptr))
113
0
                break;
114
0
        }
115
0
        if (!opt->name) {
116
0
            if (_PyOS_opterr) {
117
0
                fprintf(stderr, "Unknown option: %ls\n", argv[_PyOS_optind - 1]);
118
0
            }
119
0
            return '_';
120
0
        }
121
0
        opt_ptr = L"";
122
0
        if (!opt->has_arg) {
123
0
            return opt->val;
124
0
        }
125
0
        if (_PyOS_optind >= argc) {
126
0
            if (_PyOS_opterr) {
127
0
                fprintf(stderr, "Argument expected for the %ls options\n",
128
0
                        argv[_PyOS_optind - 1]);
129
0
            }
130
0
            return '_';
131
0
        }
132
0
        _PyOS_optarg = argv[_PyOS_optind++];
133
0
        return opt->val;
134
0
    }
135
136
0
    if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) {
137
0
        if (_PyOS_opterr) {
138
0
            fprintf(stderr, "Unknown option: -%c\n", (char)option);
139
0
        }
140
0
        return '_';
141
0
    }
142
143
0
    if (*(ptr + 1) == L':') {
144
0
        if (*opt_ptr != L'\0') {
145
0
            _PyOS_optarg  = opt_ptr;
146
0
            opt_ptr = L"";
147
0
        }
148
149
0
        else {
150
0
            if (_PyOS_optind >= argc) {
151
0
                if (_PyOS_opterr) {
152
0
                    fprintf(stderr,
153
0
                        "Argument expected for the -%c option\n", (char)option);
154
0
                }
155
0
                return '_';
156
0
            }
157
158
0
            _PyOS_optarg = argv[_PyOS_optind++];
159
0
        }
160
0
    }
161
162
0
    return option;
163
0
}