Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/134929/?format=api
http://patchwork.dpdk.org/api/patches/134929/?format=api", "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20231207161818.2590661-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": "<20231207161818.2590661-2-euan.bourke@intel.com>", "list_archive_url": "https://inbox.dpdk.org/dev/20231207161818.2590661-2-euan.bourke@intel.com", "date": "2023-12-07T16:18:11", "name": "[v3,1/8] arg_parser: new library for command line parsing", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": true, "hash": "edfbdac0905783e9d4344cd039539bf4d050f339", "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/20231207161818.2590661-2-euan.bourke@intel.com/mbox/", "series": [ { "id": 30478, "url": "http://patchwork.dpdk.org/api/series/30478/?format=api", "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=30478", "date": "2023-12-07T16:18:10", "name": "add new command line argument parsing library", "version": 3, "mbox": "http://patchwork.dpdk.org/series/30478/mbox/" } ], "comments": "http://patchwork.dpdk.org/api/patches/134929/comments/", "check": "success", "checks": "http://patchwork.dpdk.org/api/patches/134929/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 0A44B4369D;\n\tThu, 7 Dec 2023 17:18:47 +0100 (CET)", "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2610442F29;\n\tThu, 7 Dec 2023 17:18:39 +0100 (CET)", "from mgamail.intel.com (mgamail.intel.com [134.134.136.24])\n by mails.dpdk.org (Postfix) with ESMTP id 958B042ECC\n for <dev@dpdk.org>; Thu, 7 Dec 2023 17:18:37 +0100 (CET)", "from orsmga007.jf.intel.com ([10.7.209.58])\n by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 07 Dec 2023 08:18:36 -0800", "from unknown (HELO silpixa00400630.ir.intel.com) ([10.237.213.151])\n by orsmga007.jf.intel.com with ESMTP; 07 Dec 2023 08:18:35 -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=1701965917; x=1733501917;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=WvUR/uHVSDOlQYyveiPgygJebg+yZCJpej0LIdC0uAU=;\n b=jt1W4CDSk/HB0mhhZ7PtP5595AN9++T/LXGSmK5uGVfHfFcJYq57x/X/\n iGyxwQa4JzGA5fVIk3Pl8IjN4ZkKaOdZKHzyXvr5vp482ZmVNnx8kJgHz\n +xqSkilweurS4OKDN0Oq+7Gwhoq4XI3N+IG0DDL057aZo8s7M47DMZQTd\n djWIHioag3e0tfpSvwkvwheyrvVRDjVMBZqXLbbuNcdc1afEZ87hbB/Wz\n QKv2i/pIsyrkjCylpXv7Nz+SWEZUSqUDX6523kP0HiHuTj0A9eKI8uu41\n T5CLX18DtosY92YENtus11N31ZPMlP9yewwWEIxXD3IrwvytVdj11Tc2o g==;", "X-IronPort-AV": [ "E=McAfee;i=\"6600,9927,10917\"; a=\"397048605\"", "E=Sophos;i=\"6.04,256,1695711600\"; d=\"scan'208\";a=\"397048605\"", "E=McAfee;i=\"6600,9927,10917\"; a=\"765153958\"", "E=Sophos;i=\"6.04,256,1695711600\"; d=\"scan'208\";a=\"765153958\"" ], "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 v3 1/8] arg_parser: new library for command line parsing", "Date": "Thu, 7 Dec 2023 16:18:11 +0000", "Message-Id": "<20231207161818.2590661-2-euan.bourke@intel.com>", "X-Mailer": "git-send-email 2.34.1", "In-Reply-To": "<20231207161818.2590661-1-euan.bourke@intel.com>", "References": "<20231207161818.2590661-1-euan.bourke@intel.com>", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8bit", "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 | 108 ++++++++++++++++++++++++++++++++\n lib/arg_parser/meson.build | 7 +++\n lib/arg_parser/rte_arg_parser.h | 66 +++++++++++++++++++\n lib/arg_parser/version.map | 10 +++\n lib/meson.build | 2 +\n 9 files changed, 201 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..240f63d8e1\n--- /dev/null\n+++ b/lib/arg_parser/arg_parser.c\n@@ -0,0 +1,108 @@\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 / CHAR_BIT] & (1 << (idx % CHAR_BIT)));\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 / CHAR_BIT] |= 1 << (idx % CHAR_BIT);\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_arg_parse_corelist(const char *corelist, uint16_t *cores, uint32_t cores_len)\n+{\n+\tstruct core_bits mask = {0};\n+\tint32_t min = -1;\n+\tchar *end = NULL;\n+\n+\tmin = -1;\n+\tdo {\n+\t\tint64_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\tif (min == -1)\n+\t\t\t\tmin = max = idx;\n+\t\t\telse if (min > idx) {\n+\t\t\t\tmax = min;\n+\t\t\t\tmin = idx;\n+\t\t\t} else\n+\t\t\t\tmax = idx;\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+\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..80579f8cf3\n--- /dev/null\n+++ b/lib/arg_parser/rte_arg_parser.h\n@@ -0,0 +1,66 @@\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 list up\n+ * to the \"cores_len\", and the number of unique cores present in the \"corelist\"\n+ * 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+ * NOTE: if the length of the input array is insufficient to hold the number of core ids\n+ * in \"corelist\" the input array is filled to capacity but the return value is the\n+ * number of elements which would have been written to the array, had enough space been\n+ * available. [This is similar to the behaviour of the snprintf function]. Because of\n+ * this, the number of core values in the \"corelist\" may be determined by calling the\n+ * function with a NULL array pointer and array length given as 0.\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_arg_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..b0caaac569\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_arg_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": [ "v3", "1/8" ] }{ "id": 134929, "url": "