[v2,6/9] eal: getopt implementation for windows

Message ID 20190926202924.6876-7-pallavi.kadam@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Thomas Monjalon
Headers
Series Windows patchset with additional EAL functionalities |

Checks

Context Check Description
ci/Intel-compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Kadam, Pallavi Sept. 26, 2019, 8:29 p.m. UTC
  Adding getopt_long.c and getopt.c files to support parsing
option on Windows.
The original contribution is under MIT license.

Signed-off-by: Antara Ganesh Kolar <antara.ganesh.kolar@intel.com>
Signed-off-by: Pallavi Kadam <pallavi.kadam@intel.com>
Reviewed-by: Ranjit Menon <ranjit.menon@intel.com>
Reviewed-by: Keith Wiles <keith.wiles@intel.com>
---
 lib/librte_eal/windows/eal/getopt.c      | 132 +++++++++++++++
 lib/librte_eal/windows/eal/getopt_long.c | 196 +++++++++++++++++++++++
 lib/librte_eal/windows/eal/meson.build   |   2 +
 3 files changed, 330 insertions(+)
 create mode 100644 lib/librte_eal/windows/eal/getopt.c
 create mode 100644 lib/librte_eal/windows/eal/getopt_long.c
  

Comments

Stephen Hemminger Sept. 26, 2019, 9:27 p.m. UTC | #1
On Thu, 26 Sep 2019 13:29:21 -0700
Pallavi Kadam <pallavi.kadam@intel.com> wrote:

> Adding getopt_long.c and getopt.c files to support parsing
> option on Windows.
> The original contribution is under MIT license.
> 
> Signed-off-by: Antara Ganesh Kolar <antara.ganesh.kolar@intel.com>
> Signed-off-by: Pallavi Kadam <pallavi.kadam@intel.com>
> Reviewed-by: Ranjit Menon <ranjit.menon@intel.com>
> Reviewed-by: Keith Wiles <keith.wiles@intel.com>

This would require a licensing exception from the governing board.
And the license should be in LICENSES directory and put a SPDX tag here.
  
Kadam, Pallavi Sept. 26, 2019, 11:26 p.m. UTC | #2
Hi Stephen,

On 9/26/2019 2:27 PM, Stephen Hemminger wrote:
> On Thu, 26 Sep 2019 13:29:21 -0700
> Pallavi Kadam <pallavi.kadam@intel.com> wrote:
>
>> Adding getopt_long.c and getopt.c files to support parsing
>> option on Windows.
>> The original contribution is under MIT license.
>>
>> Signed-off-by: Antara Ganesh Kolar <antara.ganesh.kolar@intel.com>
>> Signed-off-by: Pallavi Kadam <pallavi.kadam@intel.com>
>> Reviewed-by: Ranjit Menon <ranjit.menon@intel.com>
>> Reviewed-by: Keith Wiles <keith.wiles@intel.com>
> This would require a licensing exception from the governing board.
> And the license should be in LICENSES directory and put a SPDX tag here.

Planning to include this topic in the upcoming Tech board meeting's agenda.

Hope we can discuss more on receiving an exception for the licensing or 
any other

better solution for such Windows specific files.
  

Patch

diff --git a/lib/librte_eal/windows/eal/getopt.c b/lib/librte_eal/windows/eal/getopt.c
new file mode 100644
index 000000000..760c00eef
--- /dev/null
+++ b/lib/librte_eal/windows/eal/getopt.c
@@ -0,0 +1,132 @@ 
+/* musl as a whole is licensed under the following standard MIT license:
+ *
+ * ----------------------------------------------------------------------
+ * Copyright (c) 2005-2014 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <unistd.h>
+#include <wchar.h>
+#include <string.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+char *optarg;
+int optind = 1, opterr = 1, optopt, __optpos, __optreset = 0;
+
+#define optpos __optpos
+
+void
+__getopt_msg(const char *a, const char *b, const char *c, size_t l)
+{
+	FILE *f = stderr;
+	fputs(a, f) >= 0
+	&& fwrite(b, strlen(b), 1, f)
+	&& fwrite(c, 1, l, f) == l
+	&& putc('\n', f);
+}
+
+int
+getopt(int argc, char * const argv[], const char *optstring)
+{
+	int i;
+	wchar_t c, d;
+	int k, l;
+	char *optchar;
+
+	if (!optind || __optreset) {
+		__optreset = 0;
+		__optpos = 0;
+		optind = 1;
+	}
+
+	if (optind >= argc || !argv[optind])
+		return -1;
+
+	if (argv[optind][0] != '-') {
+		if (optstring[0] == '-') {
+			optarg = argv[optind++];
+			return 1;
+		}
+		return -1;
+	}
+
+	if (!argv[optind][1])
+		return -1;
+
+	if (argv[optind][1] == '-' && !argv[optind][2])
+		return optind++, -1;
+
+	if (!optpos)
+		optpos++;
+	k = mbtowc(&c, argv[optind] + optpos, MB_LEN_MAX);
+	if (k < 0) {
+		k = 1;
+		c = 0xfffd; /* replacement char */
+	}
+	optchar = argv[optind]+optpos;
+	optpos += k;
+
+	if (!argv[optind][optpos]) {
+		optind++;
+		optpos = 0;
+	}
+
+	if (optstring[0] == '-' || optstring[0] == '+')
+		optstring++;
+
+	i = 0;
+	d = 0;
+	do {
+		l = mbtowc(&d, optstring+i, MB_LEN_MAX);
+		if (l > 0)
+			i += l;
+		else
+			i++;
+	} while (l && d != c);
+
+	if (d != c || c == ':') {
+		optopt = c;
+		if (optstring[0] != ':' && opterr)
+			__getopt_msg(argv[0], ": unrecognized option: ",
+				optchar, k);
+		return '?';
+	}
+	if (optstring[i] == ':') {
+		optarg = 0;
+		if (optstring[i+1] != ':' || optpos) {
+			optarg = argv[optind++] + optpos;
+			optpos = 0;
+		}
+		if (optind > argc) {
+			optopt = c;
+			if (optstring[0] == ':')
+				return ':';
+			if (opterr)
+				__getopt_msg(argv[0],
+				": option requires an argument: ",
+				optchar, k);
+			return '?';
+		}
+	}
+	return c;
+}
diff --git a/lib/librte_eal/windows/eal/getopt_long.c b/lib/librte_eal/windows/eal/getopt_long.c
new file mode 100644
index 000000000..583190783
--- /dev/null
+++ b/lib/librte_eal/windows/eal/getopt_long.c
@@ -0,0 +1,196 @@ 
+/* musl as a whole is licensed under the following standard MIT license:
+ *
+ * ----------------------------------------------------------------------
+ * Copyright (c) 2005-2014 Rich Felker, et al.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <getopt.h>
+#include <stdio.h>
+#include <string.h>
+
+extern int __optpos, __optreset;
+
+static void
+permute(char **argv, int dest, int src)
+{
+	char **av = (char **)argv;
+	char *tmp = av[src];
+	int i;
+	for (i = src; i > dest; i--)
+		av[i] = av[i-1];
+	av[dest] = tmp;
+}
+
+static int __getopt_long_core(int argc, char **argv,
+	const char *optstring, const struct option *longopts,
+	int *idx, int longonly);
+
+static int
+__getopt_long(int argc, char **argv, const char *optstring,
+	const struct option *longopts, int *idx, int longonly)
+{
+	int ret, skipped, resumed;
+	if (!optind || __optreset) {
+		__optreset = 0;
+		__optpos = 0;
+		optind = 1;
+	}
+	if (optind >= argc || !argv[optind])
+		return -1;
+	skipped = optind;
+	if (optstring[0] != '+' && optstring[0] != '-') {
+		int i;
+		for (i = optind; ; i++) {
+			if (i >= argc || !argv[i])
+				return -1;
+			if (argv[i][0] == '-' && argv[i][1])
+				break;
+		}
+		optind = i;
+	}
+	resumed = optind;
+	ret = __getopt_long_core(argc, argv, optstring, longopts,
+		idx, longonly);
+	if (resumed > skipped) {
+		int i, cnt = optind-resumed;
+		for (i = 0; i < cnt; i++)
+			permute(argv, skipped, optind-1);
+		optind = skipped + cnt;
+	}
+	return ret;
+}
+
+static int
+__getopt_long_core(int argc, char **argv, const char *optstring,
+	const struct option *longopts, int *idx, int longonly)
+{
+	optarg = 0;
+	if (longopts && argv[optind][0] == '-' &&
+		((longonly && argv[optind][1] && argv[optind][1] != '-') ||
+		 (argv[optind][1] == '-' && argv[optind][2]))) {
+
+		int colon = optstring[optstring[0] == '+' || optstring[0] ==
+			'-'] == ':';
+		int i, cnt, match;
+		char *arg, *opt, *start = argv[optind]+1;
+		for (cnt = i = 0; longopts[i].name; i++) {
+			const char *name = longopts[i].name;
+			opt = start;
+			if (*opt == '-')
+				opt++;
+			while (*opt && *opt != '=' && *opt == *name)
+				name++, opt++;
+			if (*opt && *opt != '=')
+				continue;
+			arg = opt;
+			match = i;
+			if (!*name) {
+				cnt = 1;
+				break;
+			}
+			cnt++;
+		}
+		if (cnt == 1 && longonly && arg-start ==
+			mblen(start, MB_LEN_MAX)) {
+			int l = arg - start;
+			for (i = 0; optstring[i]; i++) {
+				int j;
+				for (j = 0; j < l && start[j] ==
+					optstring[i + j]; j++)
+					;
+				if (j == l) {
+					cnt++;
+					break;
+				}
+			}
+		}
+		if (cnt == 1) {
+			i = match;
+			opt = arg;
+			optind++;
+			if (*opt == '=') {
+				if (!longopts[i].has_arg) {
+					optopt = longopts[i].val;
+					if (colon || !opterr)
+						return '?';
+					__getopt_msg(argv[0],
+						": option does not take an argument: ",
+						longopts[i].name,
+						strlen(longopts[i].name));
+					return '?';
+				}
+				optarg = opt+1;
+			} else if (longopts[i].has_arg == required_argument) {
+				optarg = argv[optind];
+				if (!optarg) {
+					optopt = longopts[i].val;
+					if (colon)
+						return ':';
+					if (!opterr)
+						return '?';
+					__getopt_msg(argv[0],
+						": option requires an argument: ",
+						longopts[i].name,
+						strlen(longopts[i].name));
+					return '?';
+				}
+				optind++;
+			}
+			if (idx)
+				*idx = i;
+			if (longopts[i].flag) {
+				*longopts[i].flag = longopts[i].val;
+				return 0;
+			}
+			return longopts[i].val;
+		}
+		if (argv[optind][1] == '-') {
+			optopt = 0;
+			if (!colon && opterr)
+				__getopt_msg(argv[0], cnt ?
+					": option is ambiguous: " :
+					": unrecognized option: ",
+					argv[optind]+2,
+					strlen(argv[optind]+2));
+			optind++;
+			return '?';
+		}
+	}
+	return getopt(argc, argv, optstring);
+}
+
+int
+getopt_long(int argc, char **argv, const char *optstring,
+	const struct option *longopts, int *idx)
+{
+	return __getopt_long(argc, argv, optstring, longopts, idx, 0);
+}
+
+int
+getopt_long_only(int argc, char **argv, const char *optstring,
+	const struct option *longopts, int *idx)
+{
+	return __getopt_long(argc, argv, optstring, longopts, idx, 1);
+}
diff --git a/lib/librte_eal/windows/eal/meson.build b/lib/librte_eal/windows/eal/meson.build
index af4f70f00..aa29e2e97 100644
--- a/lib/librte_eal/windows/eal/meson.build
+++ b/lib/librte_eal/windows/eal/meson.build
@@ -17,4 +17,6 @@  env_sources = files('eal.c',
 	'eal_debug.c',
 	'eal_lcore.c',
 	'eal_thread.c',
+	'getopt.c',
+	'getopt_long.c'
 )