libxcoder 5.6.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 int i, parse_long_mismatch = 0;
103 static char* nextchar = NULL;
104
105 if (nextchar == NULL || *nextchar == '\0')
106 {
107 if (optind == 0)
108 {
109 optind++;
110 }
111
112 if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
113 {
114 optarg = NULL;
115 if (optind < argc)
116 {
117 optarg = argv[optind];
118 }
119 return EOF;
120 }
121
122 nextchar = argv[optind];
123 if (strncmp(argv[optind], "--", 2) == 0)
124 {
125 parse_long_mismatch = 1;
126 nextchar += strlen("--");
127 optarg = NULL;
128 if (optind < argc)
129 {
130 optarg = argv[optind];
131 }
132 }
133 else
134 {
135 nextchar += strlen("-");
136 }
137
138 optind++;
139 }
140
141 // Parse long option string
142 for (i = 0; longopts != NULL && longopts[i].name != NULL; i++)
143 {
144 size_t optlen = strlen(longopts[i].name);
145 if (strncmp(nextchar, longopts[i].name, optlen) == 0)
146 {
147 nextchar += optlen;
148 switch (longopts[i].has_arg)
149 {
150 case 0:
151 if (*nextchar != '\0' || (optind < argc && argv[optind][0] != '-'))
152 {
153 optind++;
154 return '?';
155 }
156 else
157 {
158 optind++;
159 return longopts[i].flag == NULL ? longopts[i].val : 0;
160 }
161 case 1:
162 if (*nextchar == '=')
163 {
164 optarg = nextchar + 1;
165 optind++;
166 return longopts[i].flag == NULL ? longopts[i].val : 0;
167 }
168 else if (*nextchar != '\0' || (optind < argc && argv[optind][0] == '-'))
169 {
170 optind++;
171 return '?';
172 }
173 else if (optind < argc)
174 {
175 optarg = argv[optind];
176 optind++;
177 return longopts[i].flag == NULL ? longopts[i].val : 0;
178 }
179 else
180 {
181 return '?';
182 }
183 case 2:
184 if (*nextchar == '=')
185 {
186 optarg = nextchar + 1;
187 }
188 else if (*nextchar == '\0' || (optind < argc && argv[optind][0] == '-'))
189 {
190 optarg = NULL;
191 }
192 else if (optind < argc)
193 {
194 optarg = argv[optind];
195 }
196
197 optind++;
198 return longopts[i].flag == NULL ? longopts[i].val : 0;
199 default:
200 return '?';
201 }
202 }
203 }
204
205 if (parse_long_mismatch)
206 {
207 return '?';
208 }
209
210 // Parse short option string
211 char c = *nextchar++;
212 char* cp = strchr(optstring, c);
213 optopt = (int)c;
214 if (cp == NULL || c == ':')
215 {
216 return '?';
217 }
218
219 cp++;
220 // Whether there is any argument
221 if (*cp == ':')
222 {
223 if (*nextchar != '\0')
224 {
225 optarg = nextchar;
226 nextchar = NULL; // for next invocation
227 }
228 else if (optind < argc)
229 {
230 optarg = argv[optind];
231 optind++;
232 }
233 else
234 {
235 return '?';
236 }
237 }
238
239 return c;
240}
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