get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 131570,
    "url": "http://patchwork.dpdk.org/api/patches/131570/?format=api",
    "web_url": "http://patchwork.dpdk.org/project/dpdk/patch/20230918130352.379478-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": "<20230918130352.379478-2-bruce.richardson@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20230918130352.379478-2-bruce.richardson@intel.com",
    "date": "2023-09-18T13:03:48",
    "name": "[RFC,v2,1/5] buildtools/dpdk-cmdline-gen: generate boilerplate for simple cmds",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "f9011fad7f61c2b894f82b1199b981cebe45fc35",
    "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/20230918130352.379478-2-bruce.richardson@intel.com/mbox/",
    "series": [
        {
            "id": 29536,
            "url": "http://patchwork.dpdk.org/api/series/29536/?format=api",
            "web_url": "http://patchwork.dpdk.org/project/dpdk/list/?series=29536",
            "date": "2023-09-18T13:03:47",
            "name": "use script to simplify use of cmdline lib",
            "version": 2,
            "mbox": "http://patchwork.dpdk.org/series/29536/mbox/"
        }
    ],
    "comments": "http://patchwork.dpdk.org/api/patches/131570/comments/",
    "check": "success",
    "checks": "http://patchwork.dpdk.org/api/patches/131570/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 6C7E5425D1;\n\tMon, 18 Sep 2023 15:04:09 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id D5BFE406B6;\n\tMon, 18 Sep 2023 15:04:05 +0200 (CEST)",
            "from mgamail.intel.com (mgamail.intel.com [134.134.136.20])\n by mails.dpdk.org (Postfix) with ESMTP id EDA69402E9\n for <dev@dpdk.org>; Mon, 18 Sep 2023 15:04:03 +0200 (CEST)",
            "from orsmga007.jf.intel.com ([10.7.209.58])\n by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 18 Sep 2023 06:04:03 -0700",
            "from silpixa00401385.ir.intel.com ([10.237.214.14])\n by orsmga007.jf.intel.com with ESMTP; 18 Sep 2023 06:04:00 -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=1695042244; x=1726578244;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=Q6X4+XrTZnGqehR8VOKiHBDU2cKd9vL1tM0DiwP18Fw=;\n b=eaJuG7IZfl4nO0Ev1DQI33YLImBL+BcuG57ShnOcxKpuwu8zSZYaOtMd\n ZV1WDnMVTBfPR1oUcDE6xiXVkc+lV+jLFSYmtxxdoUsOYxh8y6jauFCft\n zUsth+tRmLLCZ2licHEZaBxcSTAQcAiVyMlOS+A9/rNXOJyi0h9AXXZ2U\n hEZyrPopGN7bF7cfpJ4iF1rI/jazykE8ZjCwCUe/iv2wpHHt4lDRa9M+b\n uqJaLlANy2noUG/n0V6J4Aq0ikXj62XcL89XgJ2PDE3rn+oVU76Nv2HOi\n ju6sDbd1aLRc2Oad0QfXWCZ/BYFZ9YQg3vI5ClKMM0m2jstvnd8A3Zzce Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10837\"; a=\"369969378\"",
            "E=Sophos;i=\"6.02,156,1688454000\"; d=\"scan'208\";a=\"369969378\"",
            "E=McAfee;i=\"6600,9927,10837\"; a=\"739130631\"",
            "E=Sophos;i=\"6.02,156,1688454000\"; d=\"scan'208\";a=\"739130631\""
        ],
        "X-ExtLoop1": "1",
        "From": "Bruce Richardson <bruce.richardson@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "Olivier Matz <olivier.matz@6wind.com>,\n Bruce Richardson <bruce.richardson@intel.com>",
        "Subject": "[RFC PATCH v2 1/5] buildtools/dpdk-cmdline-gen: generate boilerplate\n for simple cmds",
        "Date": "Mon, 18 Sep 2023 14:03:48 +0100",
        "Message-Id": "<20230918130352.379478-2-bruce.richardson@intel.com>",
        "X-Mailer": "git-send-email 2.39.2",
        "In-Reply-To": "<20230918130352.379478-1-bruce.richardson@intel.com>",
        "References": "<20230802170052.955323-1-bruce.richardson@intel.com>\n <20230918130352.379478-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": "Provide a script for application developers to quickly generate the\nboilerplate code necessary for using the cmdline library.\n\nThis initial version works only with commands using simple strings and\nnumbers, but this is sufficient for many use-cases. Future extensions\ncould, no doubt, expand support to expose more capabilities of the\nlibrary.\n\nExample of use:\nThe script takes an input file with a list of commands the user wants in\nthe app, where the parameter variables are tagged with the type.\nFor example:\n\n\t$ cat commands.list\n\tlist\n\tadd <UINT16>x <UINT16>y\n\techo <STRING>message\n\tadd socket <STRING>path\n\tquit\n\nWhen run through the script as \"./dpdk-cmdline-gen.py commands.list\",\nthe output will be the contents of a header file with all the\nboilerplate necessary for a commandline instance with those commands.\n\nIf the flag --stubs is passed, an output header filename must also be\npassed, in which case both a header file with the definitions and a C\nfile with function stubs in it is written to disk. The separation is so\nthat the header file can be rewritten at any future point to add more\ncommands, while the C file can be kept as-is and extended by the user\nwith any additional functions needed.\n\nSigned-off-by: Bruce Richardson <bruce.richardson@intel.com>\n---\n buildtools/dpdk-cmdline-gen.py | 146 +++++++++++++++++++++++++++++++++\n buildtools/meson.build         |   7 ++\n 2 files changed, 153 insertions(+)\n create mode 100755 buildtools/dpdk-cmdline-gen.py",
    "diff": "diff --git a/buildtools/dpdk-cmdline-gen.py b/buildtools/dpdk-cmdline-gen.py\nnew file mode 100755\nindex 0000000000..1ddd8b6bbb\n--- /dev/null\n+++ b/buildtools/dpdk-cmdline-gen.py\n@@ -0,0 +1,146 @@\n+#!/usr/bin/env python3\n+# SPDX-License-Identifier: BSD-3-Clause\n+# Copyright(c) 2023 Intel Corporation\n+#\n+\n+import sys\n+import os\n+import argparse\n+\n+PARSE_FN_PARAMS = \"void *parsed_result, struct cmdline *cl, void *data\"\n+PARSE_FN_BODY = \"\"\"\n+    /* TODO: command action */\n+    RTE_SET_USED(parsed_result);\n+    RTE_SET_USED(cl);\n+    RTE_SET_USED(data);\n+\"\"\"\n+\n+def process_command(tokens, cfile):\n+    name = []\n+\n+    if tokens[0].startswith('<'):\n+        print(\"Error: each command must start with at least one literal string\",\n+                file=sys.stderr)\n+        sys.exit(1)\n+    for t in tokens:\n+        if t.startswith('<'):\n+            break;\n+        name.append(t)\n+    name = \"_\".join(name)\n+\n+    result_struct = []\n+    initializers = []\n+    token_list = []\n+    for t in tokens:\n+        if t.startswith('<'):\n+            t_type, t_name = t[1:].split('>')\n+            t_val = \"NULL\"\n+        else:\n+            t_type = \"STRING\"\n+            t_name = t\n+            t_val = f'\"{t}\"'\n+\n+        if t_type == \"STRING\":\n+            result_struct.append(f\"\\tcmdline_fixed_string_t {t_name};\")\n+            initializers.append(f\"static cmdline_parse_token_string_t cmd_{name}_{t_name}_tok =\\n\"\n+                    + f\"\\tTOKEN_STRING_INITIALIZER(struct cmd_{name}_result, {t_name}, {t_val});\")\n+        elif t_type in ['UINT8', 'UINT16', 'UINT32', 'UINT64',\n+                    'INT8', 'INT16', 'INT32', 'INT64']:\n+            result_struct.append(f\"\\t{t_type.lower()}_t {t_name};\")\n+            initializers.append(f\"static cmdline_parse_token_num_t cmd_{name}_{t_name}_tok =\\n\"\n+                    + f\"\\tTOKEN_NUM_INITIALIZER(struct cmd_{name}_result, {t_name}, RTE_{t_type});\")\n+        else:\n+            print(f\"Error: unknown token-type {t}\", file=sys.stderr)\n+            sys.exit(1)\n+        token_list.append(f\"cmd_{name}_{t_name}_tok\")\n+\n+    print(f\"/* Auto-generated handling for command '{' '.join(tokens)}' */\")\n+    # output function prototype\n+    func_sig = f\"void\\ncmd_{name}_parsed({PARSE_FN_PARAMS})\"\n+    print(f\"extern {func_sig};\\n\")\n+    # output function template if C file being written\n+    if (cfile):\n+        print(f\"{func_sig}\\n{{{PARSE_FN_BODY}}}\\n\", file=cfile)\n+    # output result data structure\n+    print(f\"struct cmd_{name}_result {{\\n\"\n+            + '\\n'.join(result_struct)\n+            + \"\\n};\\n\")\n+    # output the initializer tokens\n+    print(\"\\n\".join(initializers) + '\\n')\n+    # output the instance structure\n+    print(f\"static cmdline_parse_inst_t cmd_{name} = {{\\n\"\n+            + f'\\t.f = cmd_{name}_parsed,\\n'\n+            + f'\\t.data = NULL,\\n'\n+            + f'\\t.help_str = \"\",\\n'\n+            + f'\\t.tokens = {{')\n+    for t in token_list:\n+        print(f\"\\t\\t(void *)&{t},\")\n+    print(\"\\t\\tNULL\\n\"\n+            + \"\\t}\\n\"\n+            + \"};\\n\")\n+\n+    # return the instance structure name\n+    return f\"cmd_{name}\"\n+\n+def process_commands(infile, hfile, cfile, ctxname):\n+    instances = []\n+\n+    # redirect stdout to output the header, to save passing file= each print\n+    old_sys_stdout = sys.stdout\n+    sys.stdout = hfile\n+\n+    print(f\"/* File autogenerated by {sys.argv[0]} */\")\n+    print('#ifndef GENERATED_COMMANDS_H')\n+    print('#define GENERATED_COMMANDS_H')\n+    print(\"#include <rte_common.h>\")\n+    print(\"#include <cmdline.h>\")\n+    print(\"#include <cmdline_parse_string.h>\")\n+    print(\"#include <cmdline_parse_num.h>\")\n+    print(\"\")\n+\n+    for line in infile.readlines():\n+        if line.lstrip().startswith('#'):\n+            continue\n+        instances.append(process_command(line.strip().split(), cfile))\n+\n+    print(f'static __rte_used cmdline_parse_ctx_t {ctxname}[] = {{')\n+    for inst in instances:\n+        print(f'\\t&{inst},')\n+    print('\\tNULL')\n+    print('};\\n')\n+    print('#endif /* GENERATED_COMMANDS_H */')\n+\n+    sys.stdout = old_sys_stdout\n+\n+def main():\n+    ap = argparse.ArgumentParser()\n+    ap.add_argument(\"--stubs\", action=\"store_true\",\n+            help=\"Produce C file with empty function stubs for each command\")\n+    ap.add_argument(\"--output-file\", \"-o\", default=\"-\",\n+            help=\"Output header filename [default to stdout]\")\n+    ap.add_argument(\"--context-name\", default=\"ctx\",\n+            help=\"Name given to the cmdline context variable in the output header [default=ctx]\")\n+    ap.add_argument(\"infile\", type=argparse.FileType('r'),\n+            help=\"File with list of commands\")\n+    args = ap.parse_args()\n+\n+    if not args.stubs:\n+        if args.output_file == '-':\n+            process_commands(args.infile, sys.stdout, None, args.context_name)\n+        else:\n+            with open(args.output_file, \"w\") as hfile:\n+                process_commands(args.infile, hfile, None, args.context_name)\n+    else:\n+        if not args.output_file.endswith('.h'):\n+            print(\"Error: output filename must end with '.h' extension when creating stubs\",\n+                    file=sys.stderr)\n+            sys.exit(1)\n+\n+        cfilename = args.output_file[:-2] + '.c'\n+        with open(args.output_file, \"w\") as hfile:\n+            with open(cfilename, \"w\") as cfile:\n+                print(f\"#include \\\"{args.output_file}\\\"\\n\", file=cfile)\n+                process_commands(args.infile, hfile, cfile, args.context_name)\n+\n+if __name__ == \"__main__\":\n+    main()\ndiff --git a/buildtools/meson.build b/buildtools/meson.build\nindex 948ac17dd2..72447b60a0 100644\n--- a/buildtools/meson.build\n+++ b/buildtools/meson.build\n@@ -19,6 +19,13 @@ get_cpu_count_cmd = py3 + files('get-cpu-count.py')\n get_numa_count_cmd = py3 + files('get-numa-count.py')\n get_test_suites_cmd = py3 + files('get-test-suites.py')\n has_hugepages_cmd = py3 + files('has-hugepages.py')\n+cmdline_gen_cmd = py3 + files('dpdk-cmdline-gen.py')\n+\n+# install any build tools that end-users might want also\n+install_data([\n+            'dpdk-cmdline-gen.py',\n+        ],\n+        install_dir: 'bin')\n \n # select library and object file format\n pmdinfo = py3 + files('gen-pmdinfo-cfile.py') + [meson.current_build_dir()]\n",
    "prefixes": [
        "RFC",
        "v2",
        "1/5"
    ]
}