Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/lib/libc/stdlib/getopt.c
39530 views
1
/* $NetBSD: getopt.c,v 1.29 2014/06/05 22:00:22 christos Exp $ */
2
3
/*-
4
* SPDX-License-Identifier: BSD-3-Clause
5
*
6
* Copyright (c) 1987, 1993, 1994
7
* The Regents of the University of California. All rights reserved.
8
*
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted provided that the following conditions
11
* are met:
12
* 1. Redistributions of source code must retain the above copyright
13
* notice, this list of conditions and the following disclaimer.
14
* 2. Redistributions in binary form must reproduce the above copyright
15
* notice, this list of conditions and the following disclaimer in the
16
* documentation and/or other materials provided with the distribution.
17
* 3. Neither the name of the University nor the names of its contributors
18
* may be used to endorse or promote products derived from this software
19
* without specific prior written permission.
20
*
21
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31
* SUCH DAMAGE.
32
*/
33
34
#include "namespace.h"
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <string.h>
38
#include <unistd.h>
39
#include "un-namespace.h"
40
41
#include "libc_private.h"
42
43
int opterr = 1, /* if error message should be printed */
44
optind = 1, /* index into parent argv vector */
45
optopt, /* character checked for validity */
46
optreset; /* reset getopt */
47
char *optarg; /* argument associated with option */
48
49
#define BADCH (int)'?'
50
#define BADARG (int)':'
51
static char EMSG[] = "";
52
/*
53
* getopt --
54
* Parse argc/argv argument vector.
55
*/
56
int
57
getopt(int nargc, char * const nargv[], const char *ostr)
58
{
59
static char *place = EMSG; /* option letter processing */
60
char *oli; /* option letter list index */
61
62
if (optreset || *place == 0) { /* update scanning pointer */
63
optreset = 0;
64
place = nargv[optind];
65
if (optind >= nargc || *place++ != '-') {
66
/* Argument is absent or is not an option */
67
place = EMSG;
68
return (-1);
69
}
70
optopt = *place++;
71
if (optopt == '-' && *place == 0) {
72
/* "--" => end of options */
73
++optind;
74
place = EMSG;
75
return (-1);
76
}
77
if (optopt == 0) {
78
/* Solitary '-', treat as a '-' option
79
if the program (eg su) is looking for it. */
80
place = EMSG;
81
if (strchr(ostr, '-') == NULL)
82
return (-1);
83
optopt = '-';
84
}
85
} else
86
optopt = *place++;
87
88
/* See if option letter is one the caller wanted... */
89
if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
90
if (*place == 0)
91
++optind;
92
if (opterr && *ostr != ':')
93
(void)fprintf(stderr,
94
"%s: illegal option -- %c\n", _getprogname(),
95
optopt);
96
return (BADCH);
97
}
98
99
/* Does this option need an argument? */
100
if (oli[1] != ':') {
101
/* don't need argument */
102
optarg = NULL;
103
if (*place == 0)
104
++optind;
105
} else {
106
/* Option-argument is either the rest of this argument or the
107
entire next argument. */
108
if (*place)
109
optarg = place;
110
else if (oli[2] == ':')
111
/*
112
* GNU Extension, for optional arguments if the rest of
113
* the argument is empty, we return NULL
114
*/
115
optarg = NULL;
116
else if (nargc > ++optind)
117
optarg = nargv[optind];
118
else {
119
/* option-argument absent */
120
place = EMSG;
121
if (*ostr == ':')
122
return (BADARG);
123
if (opterr)
124
(void)fprintf(stderr,
125
"%s: option requires an argument -- %c\n",
126
_getprogname(), optopt);
127
return (BADCH);
128
}
129
place = EMSG;
130
++optind;
131
}
132
return (optopt); /* return option letter */
133
}
134
135