32#ifndef OPENVPN_COMMON_GETOPT_H
33#define OPENVPN_COMMON_GETOPT_H
39#if !defined(OPENVPN_PLATFORM_WIN)
45#define GETOPT_BADCH (int)'?'
46#define GETOPT_BADARG (int)':'
58const char *optarg =
nullptr;
71 required_argument = 1,
75namespace getopt_private {
76inline void error(
const char *prefix,
int arg)
78 std::string err = prefix;
81 throw getopt_exception(err);
84inline void error(
const char *prefix,
const char *arg)
86 std::string err = prefix;
89 throw getopt_exception(err);
96inline int getopt_internal(
int nargc,
char *
const *nargv,
const char *ostr)
98 static const char *place = GETOPT_EMSG;
102 throw getopt_assert();
104 if (optreset || !*place)
107 if (optind >= nargc || *(place = nargv[optind]) !=
'-')
112 if (place[1] && *++place ==
'-')
119 if ((optopt = (
int)*place++) == (
int)
':' || !(oli = std::strchr(ostr, optopt)))
125 if (optopt == (
int)
'-')
129 if (opterr && *ostr !=
':')
130 getopt_private::error(
"illegal option", optopt);
131 return (GETOPT_BADCH);
143 else if (nargc <= ++optind)
146 if ((opterr) && (*ostr !=
':'))
147 getopt_private::error(
"option requires an argument", optopt);
148 return (GETOPT_BADARG);
151 optarg = nargv[optind];
163inline int getopt_long(
int nargc,
166 const struct option *long_options,
171 if (!nargv || !options || !long_options)
172 throw getopt_assert();
174 if ((retval = getopt_private::getopt_internal(nargc, nargv, options)) == -2)
176 char *current_argv = nargv[optind++] + 2;
179 size_t current_argv_len;
182 if (*current_argv ==
'\0')
184 if ((has_equal = std::strchr(current_argv,
'=')) !=
nullptr)
186 current_argv_len = has_equal - current_argv;
190 current_argv_len = std::strlen(current_argv);
192 for (i = 0; long_options[i].name; i++)
194 if (std::strncmp(current_argv, long_options[i].name, current_argv_len))
197 if (std::strlen(long_options[i].name) == (
unsigned)current_argv_len)
207 if (long_options[match].has_arg == required_argument
208 || long_options[match].has_arg == optional_argument)
213 optarg = nargv[optind++];
215 if ((long_options[match].has_arg == required_argument)
216 && (optarg ==
nullptr))
222 if ((opterr) && (*options !=
':'))
223 getopt_private::error(
"option requires an argument", current_argv);
224 return (GETOPT_BADARG);
229 if ((opterr) && (*options !=
':'))
230 getopt_private::error(
"illegal option", current_argv);
231 return (GETOPT_BADCH);
233 if (long_options[match].flag)
235 *long_options[match].flag = long_options[match].val;
239 retval = long_options[match].val;
#define OPENVPN_SIMPLE_EXCEPTION(C)
#define OPENVPN_EXCEPTION(C)
Error error(CFStringRef domain, CFIndex code, CFDictionaryRef userInfo)
const char * name(const KeyDerivation kd)