Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/134692/?format=api
http://patchwork.dpdk.org/api/patches/134692/?format=api", "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20231128140745.595481-2-euan.bourke@intel.com/", "project": { "id": 1, "url": "http://patchwork.dpdk.org/api/projects/1/?format=api", "name": "DPDK", "link_name": "dpdk", "list_id": "dev.dpdk.org", "list_email": "dev@dpdk.org", "web_url": "http://core.dpdk.org", "scm_url": "git://dpdk.org/dpdk", "webscm_url": "http://git.dpdk.org/dpdk", "list_archive_url": "https://inbox.dpdk.org/dev", "list_archive_url_format": "https://inbox.dpdk.org/dev/{}", "commit_url_format": "" }, "msgid": "<20231128140745.595481-2-euan.bourke@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20231128140745.595481-2-euan.bourke@intel.com", "date": "2023-11-28T14:07:41", "name": "[24.03,v2,1/5] arg_parser: new library for command line parsing", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "a6c86a7fac15aafcbd1f2e9b6807f53135b4e9eb", "submitter": { "id": 3231, "url": "http://patchwork.dpdk.org/api/people/3231/?format=api", "name": "Euan Bourke", "email": "euan.bourke@intel.com" }, "delegate": { "id": 1, "url": "http://patchwork.dpdk.org/api/users/1/?format=api", "username": "tmonjalo", "first_name": "Thomas", "last_name": "Monjalon", "email": "thomas@monjalon.net" }, "mbox": "http://patchwork.dpdk.org/project/dpdk/patch/20231128140745.595481-2-euan.bourke@intel.com/mbox/", "series": [ { "id": 30412, "url": "http://patchwork.dpdk.org/api/series/30412/?format=api", "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=30412", "date": "2023-11-28T14:07:40", "name": "add new command line argument parsing library", "version": 2, "mbox": "http://patchwork.dpdk.org/series/30412/mbox/" } ], "comments": "http://patchwork.dpdk.org/api/patches/134692/comments/", "check": "success", "checks": "http://patchwork.dpdk.org/api/patches/134692/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<dev-bounces@dpdk.org>", "X-Original-To": "patchwork@inbox.dpdk.org", "Delivered-To": "patchwork@inbox.dpdk.org", "Received": [ "from mails.dpdk.org (mails.dpdk.org [217.70.189.124])\n\tby inbox.dpdk.org (Postfix) with ESMTP id 8F00843402;\n\tWed, 29 Nov 2023 17:06:44 +0100 (CET)", "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2F30F42E34;\n\tWed, 29 Nov 2023 17:06:39 +0100 (CET)", "from mgamail.intel.com (mgamail.intel.com [134.134.136.24])\n by mails.dpdk.org (Postfix) with ESMTP id AAD1342D89\n for <dev@dpdk.org>; Tue, 28 Nov 2023 15:08:13 +0100 (CET)", "from fmsmga001.fm.intel.com ([10.253.24.23])\n by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 28 Nov 2023 06:07:52 -0800", "from unknown (HELO silpixa00400630.ir.intel.com) ([10.237.213.151])\n by fmsmga001.fm.intel.com with ESMTP; 28 Nov 2023 06:07:50 -0800" ], "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1701180493; x=1732716493;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=QbYdaPGNXoLY6Fr+VjU9HEuWmyg9z/vp6syFAK9Ubz0=;\n b=jWgtjKzZHqcqii4zd3HWoQU2HYRPlQHllLLG+coqnCbxkfzaqqcmXGAm\n v8YBEKTI6DoqJD1ntxQrmOcI4BJNQc9jE48nw+L69Khswrc8wI+MVeV5y\n kJ13aEonxOZcU/bOAxFpO2wyW2IHP18eq4cbbKia33gWDVNVm/MeOlFlm\n gLRgeXppdVHdpi3dBWwmpODMtxSOCy0RKTqMR3bwac2VTOhmm/C0neeD5\n mdxYSk2pHXBl2o9RqMGqTjLfHtvwE7GzOv6rfUuwC7O6+KgCEYcLXnd9j\n 55bRRT0hrkGbXbkkHu7qrF2imtmIm1AWfgTnv+iOnbXV1aG2lQNnxTHqP w==;", "X-IronPort-AV": [ "E=McAfee;i=\"6600,9927,10907\"; a=\"395747342\"", "E=Sophos;i=\"6.04,234,1695711600\"; d=\"scan'208\";a=\"395747342\"", "E=McAfee;i=\"6600,9927,10907\"; a=\"912450871\"", "E=Sophos;i=\"6.04,234,1695711600\"; d=\"scan'208\";a=\"912450871\"" ], "X-ExtLoop1": "1", "From": "Euan Bourke <euan.bourke@intel.com>", "To": "dev@dpdk.org", "Cc": "Euan Bourke <euan.bourke@intel.com>,\n Thomas Monjalon <thomas@monjalon.net>,\n Bruce Richardson <bruce.richardson@intel.com>", "Subject": "[PATCH 24.03 v2 1/5] arg_parser: new library for command line parsing", "Date": "Tue, 28 Nov 2023 14:07:41 +0000", "Message-Id": "<20231128140745.595481-2-euan.bourke@intel.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20231128140745.595481-1-euan.bourke@intel.com>", "References": "<20231122164550.3873633-1-euan.bourke@intel.com>\n <20231128140745.595481-1-euan.bourke@intel.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "X-Mailman-Approved-At": "Wed, 29 Nov 2023 17:06:37 +0100", "X-BeenThere": "dev@dpdk.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "DPDK patches and discussions <dev.dpdk.org>", "List-Unsubscribe": "<https://mails.dpdk.org/options/dev>,\n <mailto:dev-request@dpdk.org?subject=unsubscribe>", "List-Archive": "<http://mails.dpdk.org/archives/dev/>", "List-Post": "<mailto:dev@dpdk.org>", "List-Help": "<mailto:dev-request@dpdk.org?subject=help>", "List-Subscribe": "<https://mails.dpdk.org/listinfo/dev>,\n <mailto:dev-request@dpdk.org?subject=subscribe>", "Errors-To": "dev-bounces@dpdk.org" }, "content": "Add a new library to make it easier for eal and other libraries to parse\ncommand line arguments.\n\nThe first function in this library is one to parse a corelist string\ninto an array of individual core ids. The function will then return the\ntotal number of cores described in the corelist.\n\nSigned-off-by: Euan Bourke <euan.bourke@intel.com>\n---\n .mailmap | 1 +\n MAINTAINERS | 4 ++\n doc/api/doxy-api-index.md | 3 +-\n doc/api/doxy-api.conf.in | 1 +\n lib/arg_parser/arg_parser.c | 113 ++++++++++++++++++++++++++++++++\n lib/arg_parser/meson.build | 7 ++\n lib/arg_parser/rte_arg_parser.h | 65 ++++++++++++++++++\n lib/arg_parser/version.map | 10 +++\n lib/meson.build | 2 +\n 9 files changed, 205 insertions(+), 1 deletion(-)\n create mode 100644 lib/arg_parser/arg_parser.c\n create mode 100644 lib/arg_parser/meson.build\n create mode 100644 lib/arg_parser/rte_arg_parser.h\n create mode 100644 lib/arg_parser/version.map", "diff": "diff --git a/.mailmap b/.mailmap\nindex ab0742a382..528bc68a30 100644\n--- a/.mailmap\n+++ b/.mailmap\n@@ -379,6 +379,7 @@ Eric Zhang <eric.zhang@windriver.com>\n Erik Gabriel Carrillo <erik.g.carrillo@intel.com>\n Erik Ziegenbalg <eziegenb@brocade.com>\n Erlu Chen <erlu.chen@intel.com>\n+Euan Bourke <euan.bourke@intel.com>\n Eugenio Pérez <eperezma@redhat.com>\n Eugeny Parshutin <eugeny.parshutin@linux.intel.com>\n Evan Swanson <evan.swanson@intel.com>\ndiff --git a/MAINTAINERS b/MAINTAINERS\nindex 0d1c8126e3..68ef5ba14b 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -1756,6 +1756,10 @@ M: Nithin Dabilpuram <ndabilpuram@marvell.com>\n M: Pavan Nikhilesh <pbhagavatula@marvell.com>\n F: lib/node/\n \n+Argument parsing\n+M: Bruce Richardson <bruce.richardson@intel.com>\n+F: lib/arg_parser/\n+\n \n Test Applications\n -----------------\ndiff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md\nindex a6a768bd7c..f711010140 100644\n--- a/doc/api/doxy-api-index.md\n+++ b/doc/api/doxy-api-index.md\n@@ -221,7 +221,8 @@ The public API headers are grouped by topics:\n [config file](@ref rte_cfgfile.h),\n [key/value args](@ref rte_kvargs.h),\n [string](@ref rte_string_fns.h),\n- [thread](@ref rte_thread.h)\n+ [thread](@ref rte_thread.h),\n+ [argument parsing](@ref rte_arg_parser.h)\n \n - **debug**:\n [jobstats](@ref rte_jobstats.h),\ndiff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in\nindex e94c9e4e46..05718ba6ed 100644\n--- a/doc/api/doxy-api.conf.in\n+++ b/doc/api/doxy-api.conf.in\n@@ -28,6 +28,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api-index.md \\\n @TOPDIR@/lib/eal/include \\\n @TOPDIR@/lib/eal/include/generic \\\n @TOPDIR@/lib/acl \\\n+ @TOPDIR@/lib/arg_parser \\\n @TOPDIR@/lib/bbdev \\\n @TOPDIR@/lib/bitratestats \\\n @TOPDIR@/lib/bpf \\\ndiff --git a/lib/arg_parser/arg_parser.c b/lib/arg_parser/arg_parser.c\nnew file mode 100644\nindex 0000000000..4aa876b4ed\n--- /dev/null\n+++ b/lib/arg_parser/arg_parser.c\n@@ -0,0 +1,113 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Intel Corporation\n+ */\n+\n+#include \"errno.h\"\n+#include \"stdlib.h\"\n+#include \"ctype.h\"\n+#include \"string.h\"\n+#include \"stdbool.h\"\n+\n+#include <rte_arg_parser.h>\n+#include <rte_common.h>\n+\n+\n+struct core_bits {\n+\tuint8_t bits[(UINT16_MAX + 1)/CHAR_BIT];\n+\tuint16_t max_bit_set;\n+\tuint16_t min_bit_set;\n+\tuint32_t total_bits_set;\n+};\n+\n+static inline bool\n+get_core_bit(struct core_bits *mask, uint16_t idx)\n+{\n+\treturn !!(mask->bits[idx / 8] & (1 << (idx % 8)));\n+}\n+\n+static inline void\n+set_core_bit(struct core_bits *mask, uint16_t idx)\n+{\n+\tif (get_core_bit(mask, idx))\n+\t\treturn;\n+\n+\tmask->bits[idx/8] |= 1 << (idx % 8);\n+\t/* Update min and max bit if its first time setting a bit */\n+\tif (++(mask->total_bits_set) == 1) {\n+\t\tmask->min_bit_set = idx;\n+\t\tmask->max_bit_set = idx;\n+\t\treturn;\n+\t}\n+\n+\tif (idx > mask->max_bit_set)\n+\t\tmask->max_bit_set = idx;\n+\n+\tif (idx < mask->min_bit_set)\n+\t\tmask->min_bit_set = idx;\n+}\n+\n+static inline uint32_t\n+corebits_to_array(struct core_bits *mask, uint16_t *cores, size_t max_cores)\n+{\n+\tuint32_t count = 0;\n+\tfor (uint32_t i = mask->min_bit_set; i <= mask->max_bit_set && count < max_cores; i++) {\n+\t\tif (get_core_bit(mask, i))\n+\t\t\tcores[count++] = i;\n+\t}\n+\treturn mask->total_bits_set;\n+}\n+\n+\n+int\n+rte_parse_corelist(const char *corelist, uint16_t *cores, uint32_t cores_len)\n+{\n+\tint32_t min = -1;\n+\tchar *end = NULL;\n+\n+\tstruct core_bits *mask = malloc(sizeof(struct core_bits));\n+\tif (mask == NULL)\n+\t\treturn -1;\n+\tmemset(mask, 0, sizeof(struct core_bits));\n+\n+\tmin = -1;\n+\tdo {\n+\t\tuint32_t idx;\n+\t\tint32_t max;\n+\n+\t\twhile (isblank(*corelist))\n+\t\t\tcorelist++;\n+\t\tif (!isdigit(*corelist))\n+\t\t\treturn -1;\n+\n+\t\terrno = 0;\n+\t\tidx = strtol(corelist, &end, 10);\n+\t\tif (errno || end == NULL || idx > UINT16_MAX)\n+\t\t\treturn -1;\n+\t\twhile (isblank(*end))\n+\t\t\tend++;\n+\t\tif (*end == '-')\n+\t\t\tmin = idx;\n+\n+\t\telse if (*end == ',' || *end == '\\0') {\n+\t\t\tmax = idx;\n+\t\t\tif (min == -1)\n+\t\t\t\tmin = idx;\n+\n+\t\t\t/* Swap min and max if min is larger than max */\n+\t\t\tif (min > max)\n+\t\t\t\tRTE_SWAP(min, max);\n+\n+\t\t\tfor (; min <= max; min++)\n+\t\t\t\tset_core_bit(mask, min);\n+\n+\t\t\tmin = -1;\n+\t\t} else\n+\t\t\treturn -1;\n+\t\tcorelist = end + 1;\n+\t} while (*end != '\\0');\n+\n+\tuint32_t total_count = corebits_to_array(mask, cores, cores_len);\n+\tfree(mask);\n+\n+\treturn total_count;\n+}\ndiff --git a/lib/arg_parser/meson.build b/lib/arg_parser/meson.build\nnew file mode 100644\nindex 0000000000..6ee228bd69\n--- /dev/null\n+++ b/lib/arg_parser/meson.build\n@@ -0,0 +1,7 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2023 Intel Corporation\n+\n+sources = files('arg_parser.c')\n+headers = files('rte_arg_parser.h')\n+\n+includes += global_inc\ndiff --git a/lib/arg_parser/rte_arg_parser.h b/lib/arg_parser/rte_arg_parser.h\nnew file mode 100644\nindex 0000000000..cf9291d13a\n--- /dev/null\n+++ b/lib/arg_parser/rte_arg_parser.h\n@@ -0,0 +1,65 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Intel Corporation\n+ */\n+\n+#ifndef _RTE_ARG_PARSER_H_\n+#define _RTE_ARG_PARSER_H_\n+\n+/**\n+ * @file\n+ *\n+ * RTE Argument Parsing API\n+ *\n+ * The argument parsing API is a collection of functions to help parse\n+ * command line arguments. The API takes a string input and will return\n+ * it to the user in a more usable format.\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <stdint.h>\n+\n+#include <rte_compat.h>\n+\n+\n+/**\n+ * Convert a string describing a list of core ids into an array of core ids.\n+ *\n+ * On success, the passed array is filled with the core ids present in the\n+ * list up to the \"cores_len\", and the length of the array is returned.\n+ * For example, passing a 1-3,6 \"corelist\" results in an array of [1, 2, 3, 6]\n+ * and would return 4.\n+ *\n+ * Like the snprintf function for strings, if the length of the input array is\n+ * insufficient to hold the number of cores in the \"corelist\", the input array is\n+ * filled to capacity and the return value is the number of elements which would\n+ * be returned if the array had been big enough.\n+ * Function can also be called with a NULL array and 0 \"cores_len\" to find out\n+ * the \"cores_len\" required.\n+ *\n+ * @param corelist\n+ * Input string describing a list of core ids.\n+ * @param cores\n+ * An array where to store the core ids.\n+ * Array can be NULL if \"cores_len\" is 0.\n+ * @param cores_len\n+ * The length of the \"cores\" array.\n+ * If the size is smaller than that needed to hold all cores from \"corelist\",\n+ * only \"cores_len\" elements will be written to the array.\n+ * @return\n+ * n: the number of unique cores present in \"corelist\".\n+ * -1 if the string was invalid.\n+ * NOTE: if n > \"cores_len\", then only \"cores_len\" elements in the \"cores\" array are valid.\n+ */\n+__rte_experimental\n+int\n+rte_parse_corelist(const char *corelist, uint16_t *cores, uint32_t cores_len);\n+\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+#endif /* _RTE_ARG_PARSER_H_ */\ndiff --git a/lib/arg_parser/version.map b/lib/arg_parser/version.map\nnew file mode 100644\nindex 0000000000..588e14c7ad\n--- /dev/null\n+++ b/lib/arg_parser/version.map\n@@ -0,0 +1,10 @@\n+DPDK_24 {\n+\tlocal: *;\n+};\n+\n+EXPERIMENTAL {\n+\tglobal:\n+\n+\t# added in 24.03\n+\trte_parse_corelist;\n+};\ndiff --git a/lib/meson.build b/lib/meson.build\nindex 6c143ce5a6..db9e769033 100644\n--- a/lib/meson.build\n+++ b/lib/meson.build\n@@ -11,6 +11,7 @@\n libraries = [\n 'log',\n 'kvargs', # eal depends on kvargs\n+ 'arg_parser',\n 'telemetry', # basic info querying\n 'eal', # everything depends on eal\n 'ring',\n@@ -72,6 +73,7 @@ if is_ms_compiler\n 'log',\n 'kvargs',\n 'telemetry',\n+ 'arg_parser',\n ]\n endif\n \n", "prefixes": [ "24.03", "v2", "1/5" ] }{ "id": 134692, "url": "