diff mbox

[PATCHv6,11/38] helper: adding a function to merge getopt parameters

Message ID 1462984942-53326-12-git-send-email-christophe.milard@linaro.org
State New
Headers show

Commit Message

Christophe Milard May 11, 2016, 4:41 p.m. UTC
A function merging two sets to getopt parmameters (command line argument
description) into one single set is added

Signed-off-by: Christophe Milard <christophe.milard@linaro.org>
---
 helper/include/odp/helper/linux.h | 42 ++++++++++++++++++++++
 helper/linux.c                    | 74 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 116 insertions(+)
diff mbox

Patch

diff --git a/helper/include/odp/helper/linux.h b/helper/include/odp/helper/linux.h
index f67aa30..9767af4 100644
--- a/helper/include/odp/helper/linux.h
+++ b/helper/include/odp/helper/linux.h
@@ -194,6 +194,48 @@  int odph_odpthreads_create(odph_odpthread_t *thread_tbl,
  */
 int odph_odpthreads_join(odph_odpthread_t *thread_tbl);
 
+/**
+ * Merge getopt options
+ *
+ * Given two sets of getopt options (each containing possibly both short
+ * options -a string- and long options -a option array-) this function
+ * return a single set (i.e. a string for short and an array for long)
+ * being the concatenation of the two given sets.
+ * Due to the fact that the size of these arrays is unknown at compilation
+ * time, this function actually mallocs the the resulting arrays.
+ * The fourth and fith parameters are actually pointers where these malloc'ed
+ * areas are returned.
+ * This means that the caller of this function has to free the two returned
+ * areas!
+ *
+ * @param shortopts1 first set of short options (a string)
+ * @param shortopts2 second set of short options (a string)
+ * @param longopts1  first set of long options (a getopt option array)
+ * @param longopts2  second set of long options (a getopt option array)
+ * @param shortopts  a pointer where the address of the short options list
+ *		     (a string) is returned. It contains the concatenation of
+ *		     the two given short option strings.
+ * @param longopts   a pointer where the address of the long options list
+ *		     (a getopt option array) is returned.
+ *		     It contains the concatenation of the two given long
+ *		     option arrays.
+ * if any of shortopts1, shortopts2, longopts1, longopts2 is NULL, the
+ * corresponding list as assumed to be empty.
+ * if any of shortopts, longopts is NULL, the corresponding malloc is not
+ * performed.
+ *
+ * @return On success: 0 : both shortopts and longopts are returned (assuming
+ *			   the given pointer where not null), possibly
+ *			   pointing to an empty string or an empty option array.
+ *			   On success, the caller is due to free these areas.
+ *	   On failure: -1: Nothing is malloc'ed.
+ */
+int odph_merge_getopt_options(const char *shortopts1,
+			      const char *shortopts2,
+			      const struct option *longopts1,
+			      const struct option *longopts2,
+			      char **shortopts,
+			      struct option **longopts);
 
 /**
  * Parse linux helper options
diff --git a/helper/linux.c b/helper/linux.c
index b8d4f49..d1b7825 100644
--- a/helper/linux.c
+++ b/helper/linux.c
@@ -500,6 +500,80 @@  int odph_odpthreads_join(odph_odpthread_t *thread_tbl)
 }
 
 /*
+ * return the number of elements in an array of getopt options, excluding the
+ * terminating {0,0,0,0}
+ */
+static int get_getopt_options_length(const struct option *longopts)
+{
+	int l = 0;
+
+	if (!longopts)
+		return 0;
+
+	while (longopts[l].name)
+		l++;
+
+	return l;
+}
+
+/* Merge getopt options */
+int odph_merge_getopt_options(const char *shortopts1,
+			      const char *shortopts2,
+			      const struct option *longopts1,
+			      const struct option *longopts2,
+			      char **shortopts,
+			      struct option **longopts)
+{
+	int shortopts1_len;
+	int shortopts2_len;
+	int longopts1_len;
+	int longopts2_len;
+	int index;
+	int res_index = 0;
+	struct option termination = {0, 0, 0, 0};
+
+	/* merge short options: */
+	if (shortopts) {
+		shortopts1_len = (shortopts1) ? strlen(shortopts1) : 0;
+		shortopts2_len = (shortopts2) ? strlen(shortopts2) : 0;
+		*shortopts = malloc(shortopts1_len + shortopts2_len + 1);
+		if (!*shortopts)
+			return -1;
+
+		(*shortopts)[0] = 0;
+
+		if (shortopts1)
+			strcpy((*shortopts), shortopts1);
+		if (shortopts2)
+			strcat((*shortopts), shortopts2);
+	}
+
+	/* merge long options */
+	if (!longopts)
+		return 0;
+
+	longopts1_len = get_getopt_options_length(longopts1);
+	longopts2_len = get_getopt_options_length(longopts2);
+	*longopts = malloc(sizeof(struct option) *
+					(longopts1_len + longopts2_len + 1));
+	if (!*longopts) {
+		if (shortopts)
+			free(*shortopts);
+		return -1;
+	}
+
+	for (index = 0; (longopts1) && (longopts1[index].name); index++)
+		(*longopts)[res_index++] = longopts1[index];
+
+	for (index = 0; (longopts2) && (longopts2[index].name); index++)
+		(*longopts)[res_index++] = longopts2[index];
+
+	(*longopts)[res_index] = termination;
+
+	return 0;
+}
+
+/*
  * Parse command line options to extract options affecting helpers.
  */
 int odph_parse_options(int argc, char *argv[])