get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/133789/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 133789,
    "url": "http://patchwork.dpdk.org/api/patches/133789/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20231102172849.7400-2-bruce.richardson@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": "<20231102172849.7400-2-bruce.richardson@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231102172849.7400-2-bruce.richardson@intel.com",
    "date": "2023-11-02T17:28:47",
    "name": "[24.03,RFC,1/3] args: new library to allow easier manipulation of cmdline args",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "f39125e9c2d7fbbc9dc30491fb0f72db1d1c2c92",
    "submitter": {
        "id": 20,
        "url": "http://patchwork.dpdk.org/api/people/20/?format=api",
        "name": "Bruce Richardson",
        "email": "bruce.richardson@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/20231102172849.7400-2-bruce.richardson@intel.com/mbox/",
    "series": [
        {
            "id": 30120,
            "url": "http://patchwork.dpdk.org/api/series/30120/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=30120",
            "date": "2023-11-02T17:28:46",
            "name": "Add argument manipulation library",
            "version": 1,
            "mbox": "http://patchwork.dpdk.org/series/30120/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/133789/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/133789/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 0E9F543270;\n\tThu,  2 Nov 2023 18:33:16 +0100 (CET)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 0028F42D91;\n\tThu,  2 Nov 2023 18:32:57 +0100 (CET)",
            "from mgamail.intel.com (mgamail.intel.com [192.198.163.8])\n by mails.dpdk.org (Postfix) with ESMTP id 6F12C42D35\n for <dev@dpdk.org>; Thu,  2 Nov 2023 18:32:55 +0100 (CET)",
            "from fmsmga002.fm.intel.com ([10.253.24.26])\n by fmvoesa102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 02 Nov 2023 10:29:04 -0700",
            "from silpixa00401385.ir.intel.com ([10.237.214.164])\n by fmsmga002.fm.intel.com with ESMTP; 02 Nov 2023 10:29:02 -0700"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/simple;\n d=intel.com; i=@intel.com; q=dns/txt; s=Intel;\n t=1698946376; x=1730482376;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=lr+V7YOx3crC5itNMnVReWv5EX4KoubrZnkpM6o8rrE=;\n b=PBfEVtqwkwR7ro5khnjs0cG6n/yLndTxretZOEWhy3dwqF6sbL86cTqk\n LxOqRSt62RTdQoW8PHN2BbLjp3gn8q+RGOhaXfoxHbtQ8OKiBkKe61cvQ\n nAcpDqGYR66rHXBxx344a4Z65ZmXit+v59q1+Mcfi6kkPGU009p7IKGKN\n a/evDRIB4Pe7SAxAFRwuUImTocrKPBYG+HVT8fRekotDYn24p18p2VwAi\n aqJ/Ylb9LEfU8adIWfag2q1ZKbXhHguXIQz6cVXpBSeP2llinGgrXgcaV\n eLblxtO/KaJEHhJqNyMSiwEphccHIgHGkL8InhVgQn+ibS2Gbp8P8PBb2 g==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10882\"; a=\"1645206\"",
            "E=Sophos;i=\"6.03,272,1694761200\";\n   d=\"scan'208\";a=\"1645206\"",
            "E=McAfee;i=\"6600,9927,10882\"; a=\"878330492\"",
            "E=Sophos;i=\"6.03,272,1694761200\"; d=\"scan'208\";a=\"878330492\""
        ],
        "X-ExtLoop1": "1",
        "From": "Bruce Richardson <bruce.richardson@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Bruce Richardson <bruce.richardson@intel.com>",
        "Subject": "[24.03 RFC 1/3] args: new library to allow easier manipulation of\n cmdline args",
        "Date": "Thu,  2 Nov 2023 17:28:47 +0000",
        "Message-Id": "<20231102172849.7400-2-bruce.richardson@intel.com>",
        "X-Mailer": "git-send-email 2.39.2",
        "In-Reply-To": "<20231102172849.7400-1-bruce.richardson@intel.com>",
        "References": "<20231102172849.7400-1-bruce.richardson@intel.com>",
        "MIME-Version": "1.0",
        "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 small library to make it easier for apps to work with cmdline\narguments and build up args to use when initializing EAL.\n\nThis library is optional, and can be disabled at build time using\nthe disable libraries meson option.\n\nSigned-off-by: Bruce Richardson <bruce.richardson@intel.com>\n---\n doc/api/doxy-api-index.md |   1 +\n doc/api/doxy-api.conf.in  |   1 +\n lib/args/args.c           | 179 ++++++++++++++++++++++++++++++++++\n lib/args/meson.build      |   5 +\n lib/args/rte_args.h       | 199 ++++++++++++++++++++++++++++++++++++++\n lib/args/version.map      |  19 ++++\n lib/meson.build           |   2 +\n 7 files changed, 406 insertions(+)\n create mode 100644 lib/args/args.c\n create mode 100644 lib/args/meson.build\n create mode 100644 lib/args/rte_args.h\n create mode 100644 lib/args/version.map",
    "diff": "diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md\nindex a6a768bd7c..6ba1bb40e9 100644\n--- a/doc/api/doxy-api-index.md\n+++ b/doc/api/doxy-api-index.md\n@@ -222,6 +222,7 @@ The public API headers are grouped by topics:\n   [key/value args](@ref rte_kvargs.h),\n   [string](@ref rte_string_fns.h),\n   [thread](@ref rte_thread.h)\n+  [cmdline args management](@ref rte_args.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..15b540553d 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/args \\\n                           @TOPDIR@/lib/bbdev \\\n                           @TOPDIR@/lib/bitratestats \\\n                           @TOPDIR@/lib/bpf \\\ndiff --git a/lib/args/args.c b/lib/args/args.c\nnew file mode 100644\nindex 0000000000..80eb6670da\n--- /dev/null\n+++ b/lib/args/args.c\n@@ -0,0 +1,179 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Intel Corporation\n+ */\n+\n+#include <stdint.h>\n+#include <malloc.h>\n+#include <getopt.h>\n+#include <stdarg.h>\n+#include <errno.h>\n+\n+#include <rte_eal.h>\n+#include <rte_errno.h>\n+#include <rte_common.h>\n+#include <rte_bitops.h>\n+#include \"rte_args.h\"\n+\n+struct rte_args {\n+\tint array_sz;\n+\tint arg_count;\n+\tchar **args;\n+};\n+\n+#define DEFAULT_SIZE_HINT 8\n+\n+struct rte_args *\n+rte_args_alloc(uint32_t size_hint)\n+{\n+\tstruct rte_args *a;\n+\n+\ta = malloc(sizeof(*a));\n+\tif (a == NULL)\n+\t\treturn NULL;\n+\n+\tif (size_hint == 0)\n+\t\tsize_hint = DEFAULT_SIZE_HINT;\n+\tsize_hint = rte_align32pow2(size_hint);\n+\ta->args = calloc(size_hint, sizeof(a->args[0]));\n+\tif (a->args == NULL) {\n+\t\tfree(a);\n+\t\treturn NULL;\n+\t}\n+\n+\tmemset(a->args, 0, sizeof(a->args[0]) * size_hint);\n+\ta->arg_count = 0;\n+\ta->array_sz = size_hint;\n+\treturn a;\n+}\n+\n+struct rte_args *\n+rte_args_create(int argc, char **argv)\n+{\n+\tstruct rte_args *a;\n+\n+\tif (argc <= 0 || argv == NULL)\n+\t\treturn NULL;\n+\n+\ta = rte_args_alloc(argc + DEFAULT_SIZE_HINT);\n+\tif (a == NULL)\n+\t\treturn NULL;\n+\n+\tif (rte_args_add_argv(a, argc, argv) != 0) {\n+\t\trte_args_free(a);\n+\t\treturn NULL;\n+\t}\n+\treturn a;\n+}\n+\n+\n+int\n+rte_args_add(struct rte_args *a, const char *arg)\n+{\n+\tif (a == NULL)\n+\t\treturn -1;\n+\n+\tif (a->arg_count == a->array_sz - 1) {  /* need null at end, so subtract 1 */\n+\t\tvoid *new_a = reallocarray(a->args, a->array_sz * 2, sizeof(a->args[0]));\n+\t\tif (new_a == NULL)\n+\t\t\treturn -1;\n+\n+\t\ta->args = new_a;\n+\t\t/* zero out only new portion of array */\n+\t\tmemset(&a->args[a->array_sz], 0, a->array_sz * sizeof(a->args[0]));\n+\t\ta->array_sz *= 2;\n+\t}\n+\n+\ta->args[a->arg_count] = strdup(arg);\n+\tif (a->args[a->arg_count] == NULL)\n+\t\treturn -1;\n+\ta->arg_count++;\n+\treturn 0;\n+}\n+\n+int\n+rte_args_add_list(struct rte_args *a, int n, ...)\n+{\n+\tva_list ap;\n+\tva_start(ap, n);\n+\twhile (n > 0) {\n+\t\tif (rte_args_add(a, va_arg(ap, char *)) != 0)\n+\t\t\tbreak;\n+\t\tn--;\n+\t}\n+\tva_end(ap);\n+\treturn n;  /* return the number failing, 0 if all ok */\n+}\n+\n+int\n+rte_args_add_argv(struct rte_args *a, int argc, char **argv)\n+{\n+\tint i;\n+\n+\tfor (i = 0; i < argc; i++)\n+\t\tif (rte_args_add(a, argv[i]) < 0)\n+\t\t\tbreak;\n+\treturn argc - i; /* return the number failing, 0 if all ok */\n+}\n+\n+bool\n+rte_args_has_arg(struct rte_args *a, const char *arg)\n+{\n+\tint i;\n+\n+\tif (a == NULL || arg == NULL)\n+\t\treturn false;\n+\n+\tfor (i = 0; i < a->arg_count; i++) {\n+\t\tif (strcmp(a->args[i], arg) == 0)\n+\t\t\treturn true;\n+\t}\n+\treturn false;\n+}\n+\n+char **\n+rte_args_get_argv(struct rte_args *a, int *argc)\n+{\n+\tif (a == NULL)\n+\t\treturn NULL;\n+\n+\tif (argc != NULL)\n+\t\t*argc = a->arg_count;\n+\treturn a->args;\n+}\n+\n+int\n+rte_args_get_argc(struct rte_args *a)\n+{\n+\tif (a == NULL)\n+\t\treturn -1;\n+\n+\treturn a->arg_count;\n+}\n+\n+void\n+rte_args_free(struct rte_args *a)\n+{\n+\tint i;\n+\n+\tif (a == NULL)\n+\t\treturn;\n+\n+\tfor (i = 0; i < a->arg_count; i++)\n+\t\tfree(a->args[i]);\n+\tfree(a->args);\n+\tfree(a);\n+}\n+\n+int\n+rte_args_eal_init(struct rte_args *a)\n+{\n+\tint argc;\n+\tchar **argv;\n+\n+\t/* rte_args_argv does the check for NULL for us */\n+\targv = rte_args_get_argv(a, &argc);\n+\tif (argv == NULL || argc <= 0)\n+\t\treturn -1;\n+\n+\treturn rte_eal_init(argc, argv);\n+}\ndiff --git a/lib/args/meson.build b/lib/args/meson.build\nnew file mode 100644\nindex 0000000000..997f76a8bb\n--- /dev/null\n+++ b/lib/args/meson.build\n@@ -0,0 +1,5 @@\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2023 Intel Corporation\n+\n+sources = files('args.c')\n+headers = files('rte_args.h')\ndiff --git a/lib/args/rte_args.h b/lib/args/rte_args.h\nnew file mode 100644\nindex 0000000000..3b80b9a39c\n--- /dev/null\n+++ b/lib/args/rte_args.h\n@@ -0,0 +1,199 @@\n+/* SPDX-License-Identifier: BSD-3-Clause\n+ * Copyright(c) 2023 Intel Corporation\n+ */\n+#ifndef RTE_EAL_ARGS_H\n+#define RTE_EAL_ARGS_H\n+\n+/**\n+ * @file\n+ *\n+ * Command-line argument manipulation functions\n+ *\n+ * Simple functions for manipulating sets of commandline arguments, and then\n+ * initializing DPDK / EAL based on those.\n+ */\n+\n+#ifdef __cplusplus\n+extern \"C\" {\n+#endif\n+\n+#include <stdint.h>\n+\n+#include <rte_compat.h>\n+\n+struct rte_args;\n+\n+/**\n+ * Allocate an argument structure\n+ *\n+ * This functions reserves memory for an argument structure. On success the returned structure\n+ * is guaranteed to hold at least size_hint arguments without being resized. It is a hint only -\n+ * if more elements are added than that hinted, the rte_args structure will be dynamically resized\n+ * as necessary (subject to memory being available to do so).\n+ *\n+ * @param size_hint\n+ *   The returned structure is guaranteed to hold at least this many arguments without resizing.\n+ *   If zero, a default non-zero size value will be used.\n+ * @return\n+ *   An empty rte_args structure, NULL on failure\n+ */\n+__rte_experimental\n+struct rte_args *\n+rte_args_alloc(uint32_t size_hint);\n+\n+/**\n+ * Create an argument structure containing the existing parameters\n+ *\n+ * This functions creates an rte_args structure and initializes it with \"argc\" values\n+ * from the \"argv\" array.\n+ *\n+ * @param argc\n+ *   The number of elements in argv\n+ * @param argv\n+ *   Array of arguments to add to the created rte_args structure\n+ * @return\n+ *   An rte_args structure holding argc elements from argv. NULL on failure.\n+ */\n+__rte_experimental\n+struct rte_args *\n+rte_args_create(int argc, char **argv);\n+\n+/**\n+ * Add a new argument to the rte_args structure\n+ *\n+ * Add the argument \"arg\" to the rte_args structure, resizing the structure as necessary.\n+ * The arg parameter will be copied using strdup, so the original string may be freed or\n+ * edited as necessary after the function returns.\n+ *\n+ * @param a\n+ *   The rte_arg structure to be modified\n+ * @param arg\n+ *   The argument to be added\n+ * @return\n+ *   0 on success, -1 on failure\n+ */\n+__rte_experimental\n+int\n+rte_args_add(struct rte_args *a, const char *arg);\n+\n+/**\n+ * Add a list of arguments to the rte_args structure\n+ *\n+ * Add \"n\" arguments, given as extra function parameters to the rte_args structure, resizing\n+ * the structure as necessary.\n+ * The argument parameters will be copied using strdup, so the original strings may be freed or\n+ * edited as necessary after the function returns.\n+ *\n+ * @param a\n+ *   The rte_arg structure to be modified\n+ * @param n\n+ *   The number of arguments to be added\n+ * @return\n+ *   0 on success.\n+ *   On failure, returns the number of elements NOT added.\n+ */\n+__rte_experimental\n+int\n+rte_args_add_list(struct rte_args *a, int n, ...);\n+\n+/**\n+ * Add an array of arguments to the rte_args structure\n+ *\n+ * Add arguments from an existing argv array to the rte_args structure.\n+ * The argument parameters will be copied using strdup, so the original strings/array may\n+ * be freed or edited as necessary after the function returns.\n+ *\n+ * @param a\n+ *   The rte_arg structure to be modified\n+ * @param argc\n+ *   The number of arguments to be added\n+ * @param argv\n+ *   The array containing the pointers to the elements to be added\n+ * @return\n+ *   0 on success.\n+ *   On failure, returns the number of elements NOT added.\n+ */\n+__rte_experimental\n+int\n+rte_args_add_argv(struct rte_args *a, int argc, char **argv);\n+\n+/**\n+ * Query if an args list contains a given argument parameter\n+ *\n+ * @param a\n+ *   The rte_arg structure to be modified\n+ * @param arg\n+ *   The argument to look for in the structure\n+ * @return\n+ *   True if parameters are valid and argument is found\n+ *   False otherwise\n+ */\n+__rte_experimental\n+bool\n+rte_args_has_arg(struct rte_args *a, const char *arg);\n+\n+/**\n+ * Get the array of arguments from the rte_args structure\n+ *\n+ * Returns an array of arguments from the structure, suitable for passing to a function which\n+ * takes (argc, argv) parameters. The argc value will be optionally returned in the final output\n+ * parameter if a valid pointer is passed in.\n+ *\n+ * NOTE: The return value points to the internals of the rte_args structure, and so the\n+ * structure should not be freed while the arguments are in use.\n+ *\n+ * @param a\n+ *   The rte_arg structure to be used\n+ * @param argc\n+ *   Pointer to store the count (argc) of elements returned. Ignored if NULL\n+ * @return\n+ *   Pointer to an array of arguments. NULL on failure.\n+ */\n+__rte_experimental\n+char **\n+rte_args_get_argv(struct rte_args *a, int *argc);\n+\n+/**\n+ * Gets the number of arguments stored in an rte_args structure\n+ *\n+ * @param a\n+ *   The rte_arg structure to be used\n+ * @return\n+ *   The number of arguments stored in the structure\n+ */\n+__rte_experimental\n+int\n+rte_args_get_argc(struct rte_args *a);\n+\n+/**\n+ * Frees an rte_args structure\n+ *\n+ * @param a\n+ *   The rte_arg structure to be freed\n+ */\n+__rte_experimental\n+void\n+rte_args_free(struct rte_args *a);\n+\n+/**\n+ * Initialize DPDK EAL using arguments from the rte_args structure\n+ *\n+ * This function calls rte_eal_init(), passing in to it as parameters the argc, and argv\n+ * values got from the rte_args structure \"a\".\n+ *\n+ * @param a\n+ *   The rte_args structure to be used. Must have at least one argument in it.\n+ * @return\n+ *   -1 on invalid parameter\n+ *   Otherwise, return value from rte_eal_init()\n+ */\n+__rte_experimental\n+int\n+rte_args_eal_init(struct rte_args *a);\n+\n+#ifdef __cplusplus\n+}\n+#endif\n+\n+\n+#endif /* RTE_EAL_ARGS_H */\ndiff --git a/lib/args/version.map b/lib/args/version.map\nnew file mode 100644\nindex 0000000000..776bd22b82\n--- /dev/null\n+++ b/lib/args/version.map\n@@ -0,0 +1,19 @@\n+DPDK_24 {\n+\tlocal: *;\n+};\n+\n+EXPERIMENTAL {\n+\tglobal:\n+\n+\t# added in 24.03\n+\trte_args_add;\n+\trte_args_add_argv;\n+\trte_args_add_list;\n+\trte_args_alloc;\n+\trte_args_create;\n+\trte_args_eal_init;\n+\trte_args_free;\n+\trte_args_get_argc;\n+\trte_args_get_argv;\n+\trte_args_has_arg;\n+};\ndiff --git a/lib/meson.build b/lib/meson.build\nindex 6c143ce5a6..7049a4b00e 100644\n--- a/lib/meson.build\n+++ b/lib/meson.build\n@@ -13,6 +13,7 @@ libraries = [\n         'kvargs', # eal depends on kvargs\n         'telemetry', # basic info querying\n         'eal', # everything depends on eal\n+        'args',\n         'ring',\n         'rcu', # rcu depends on ring\n         'mempool',\n@@ -76,6 +77,7 @@ if is_ms_compiler\n endif\n \n optional_libs = [\n+        'args',\n         'bbdev',\n         'bitratestats',\n         'bpf',\n",
    "prefixes": [
        "24.03",
        "RFC",
        "1/3"
    ]
}