libxcoder 5.8.0
Loading...
Searching...
No Matches
ni_getopt.c
Go to the documentation of this file.
1/*******************************************************************************
2 *
3 * Copyright (C) 2022 NETINT Technologies
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
17 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
18 * SOFTWARE.
19 *
20 ******************************************************************************/
21
22/*!*****************************************************************************
23 * \file ni_getopt.c
24 *
25 * \brief Implementation of getopt() and getopt_long() for Windows environment
26 ******************************************************************************/
27
28#include <stdio.h>
29#include <string.h>
30
31#include "ni_getopt.h"
32
33char *optarg = NULL; // global argument pointer
34int optind = 0; // global argv index
35int opterr = 1; // global erroneous switch
36int optopt = 0; // global erroneous option character
37
38int getopt(int argc, char *argv[], const char *optstring)
39{
40 static char *nextchar = NULL;
41
42 if (nextchar == NULL || *nextchar == '\0')
43 {
44 if (optind == 0)
45 optind++;
46
47 if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
48 {
49 optarg = NULL;
50 if (optind < argc)
51 optarg = argv[optind];
52 return EOF;
53 }
54
55 if (strncmp(argv[optind], "--", strlen("--")) == 0)
56 {
57 optind++;
58 optarg = NULL;
59 if (optind < argc)
60 optarg = argv[optind];
61 return EOF;
62 }
63
64 nextchar = argv[optind];
65 nextchar += strlen("-");
66 optind++;
67 }
68
69 char c = *nextchar++;
70 char *cp = strchr(optstring, c);
71 optopt = (int)c;
72 if (cp == NULL || c == ':')
73 {
74 return '?';
75 }
76
77 cp++;
78 if (*cp == ':')
79 {
80 if (*nextchar != '\0')
81 {
82 optarg = nextchar;
83 nextchar = NULL; // for next invocation
84 }
85 else if (optind < argc)
86 {
87 optarg = argv[optind];
88 optind++;
89 }
90 else
91 {
92 return '?';
93 }
94 }
95
96 return c;
97}
98
99int getopt_long(int argc, char* argv[], const char* optstring,
100 const struct option* longopts, int* longindex)
101{
102 (void)longindex; /* not implemented; part of standard POSIX getopt_long signature */
103 int i, parse_long_mismatch = 0;
104 static char* nextchar = NULL;
105
106 if (nextchar == NULL || *nextchar == '\0')
107 {
108 if (optind == 0)
109 {
110 optind++;
111 }
112
113 if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
114 {
115 optarg = NULL;
116 if (optind < argc)
117 {
118 optarg = argv[optind];
119 }
120 return EOF;
121 }
122
123 nextchar = argv[optind];
124 if (strncmp(argv[optind], "--", 2) == 0)
125 {
126 parse_long_mismatch = 1;
127 nextchar += strlen("--");
128 optarg = NULL;
129 if (optind < argc)
130 {
131 optarg = argv[optind];
132 }
133 }
134 else
135 {
136 nextchar += strlen("-");
137 }
138
139 optind++;
140 }
141
142 // Parse long option string
143 for (i = 0; longopts != NULL && longopts[i].name != NULL; i++)
144 {
145 size_t optlen = strlen(longopts[i].name);
146 if (strncmp(nextchar, longopts[i].name, optlen) == 0)
147 {
148 nextchar += optlen;
149 switch (longopts[i].has_arg)
150 {
151 case 0:
152 if (*nextchar != '\0' || (optind < argc && argv[optind][0] != '-'))
153 {
154 optind++;
155 return '?';
156 }
157 else
158 {
159 optind++;
160 return longopts[i].flag == NULL ? longopts[i].val : 0;
161 }
162 case 1:
163 if (*nextchar == '=')
164 {
165 optarg = nextchar + 1;
166 optind++;
167 return longopts[i].flag == NULL ? longopts[i].val : 0;
168 }
169 else if (*nextchar != '\0' || (optind < argc && argv[optind][0] == '-'))
170 {
171 optind++;
172 return '?';
173 }
174 else if (optind < argc)
175 {
176 optarg = argv[optind];
177 optind++;
178 return longopts[i].flag == NULL ? longopts[i].val : 0;
179 }
180 else
181 {
182 return '?';
183 }
184 case 2:
185 if (*nextchar == '=')
186 {
187 optarg = nextchar + 1;
188 }
189 else if (*nextchar == '\0' || (optind < argc && argv[optind][0] == '-'))
190 {
191 optarg = NULL;
192 }
193 else if (optind < argc)
194 {
195 optarg = argv[optind];
196 }
197
198 optind++;
199 return longopts[i].flag == NULL ? longopts[i].val : 0;
200 default:
201 return '?';
202 }
203 }
204 }
205
206 if (parse_long_mismatch)
207 {
208 return '?';
209 }
210
211 // Parse short option string
212 char c = *nextchar++;
213 char* cp = strchr(optstring, c);
214 optopt = (int)c;
215 if (cp == NULL || c == ':')
216 {
217 return '?';
218 }
219
220 cp++;
221 // Whether there is any argument
222 if (*cp == ':')
223 {
224 if (*nextchar != '\0')
225 {
226 optarg = nextchar;
227 nextchar = NULL; // for next invocation
228 }
229 else if (optind < argc)
230 {
231 optarg = argv[optind];
232 optind++;
233 }
234 else
235 {
236 return '?';
237 }
238 }
239
240 return c;
241}
int getopt(int argc, char *argv[], const char *optstring)
Definition ni_getopt.c:38
int optopt
Definition ni_getopt.c:36
int optind
Definition ni_getopt.c:34
char * optarg
Definition ni_getopt.c:33
int opterr
Definition ni_getopt.c:35
int getopt_long(int argc, char *argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition ni_getopt.c:99
Implementation of getopt() and getopt_long() for Windows environment.
int * flag
Definition ni_getopt.h:79
const char * name
Definition ni_getopt.h:75
int val
Definition ni_getopt.h:80