get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 132628,
    "url": "http://patches.dpdk.org/api/patches/132628/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/20231016140612.664853-2-bruce.richardson@intel.com/",
    "project": {
        "id": 1,
        "url": "http://patches.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": "<20231016140612.664853-2-bruce.richardson@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20231016140612.664853-2-bruce.richardson@intel.com",
    "date": "2023-10-16T14:06:06",
    "name": "[v4,1/7] doc/prog_guide: new chapter on cmdline library",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "cd5a3b25965a5c5f4bf4a0c79a2a9c831834620b",
    "submitter": {
        "id": 20,
        "url": "http://patches.dpdk.org/api/people/20/?format=api",
        "name": "Bruce Richardson",
        "email": "bruce.richardson@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/20231016140612.664853-2-bruce.richardson@intel.com/mbox/",
    "series": [
        {
            "id": 29852,
            "url": "http://patches.dpdk.org/api/series/29852/?format=api",
            "web_url": "http://patches.dpdk.org/project/dpdk/list/?series=29852",
            "date": "2023-10-16T14:06:05",
            "name": "document and simplify use of cmdline",
            "version": 4,
            "mbox": "http://patches.dpdk.org/series/29852/mbox/"
        }
    ],
    "comments": "http://patches.dpdk.org/api/patches/132628/comments/",
    "check": "success",
    "checks": "http://patches.dpdk.org/api/patches/132628/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 36F244317F;\n\tMon, 16 Oct 2023 16:06:33 +0200 (CEST)",
            "from mails.dpdk.org (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 2E60440695;\n\tMon, 16 Oct 2023 16:06:32 +0200 (CEST)",
            "from mgamail.intel.com (mgamail.intel.com [192.55.52.115])\n by mails.dpdk.org (Postfix) with ESMTP id EACB740691\n for <dev@dpdk.org>; Mon, 16 Oct 2023 16:06:29 +0200 (CEST)",
            "from fmsmga008.fm.intel.com ([10.253.24.58])\n by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 16 Oct 2023 07:06:29 -0700",
            "from silpixa00401385.ir.intel.com ([10.237.214.154])\n by fmsmga008.fm.intel.com with ESMTP; 16 Oct 2023 07:06:27 -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=1697465190; x=1729001190;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=zYs/j+i0x2Evu12BS3CXCVNXHOoSmhFrNuolq1OsTos=;\n b=GlXUdhUBEUIYTg1jskwuwK3gRmfDvK+AY/BWK7q8TeI2nOjlF36Q6v5f\n mLCTaMK2SnB20nHLyrVFwmD+ukoMjJIkudapr/Rx/JLlMZ3wU24LE/RLg\n CHrRUGAm4o5R/LqGVI7WxSsINRFOv6Sfyc1KbaD5lEaNMinaOyPuWjnS3\n Gx1dgVL1Q4LfGDdPDDiY7pcHjT7SWmIRUos+uGoD3HOYX3m3OqsdnGArJ\n 2pDk8BhKLVTSRWXs0xhLaiuPsNpvE9lsbZx6xrbExHGVo9VMK2R2DL2oZ\n MbiEyk6N27/gtpny4XAOjyHpOBsAd1/GsFYa2i7F0A9xF0/tkz4zm3xt4 Q==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6600,9927,10863\"; a=\"385370283\"",
            "E=Sophos;i=\"6.03,229,1694761200\"; d=\"scan'208\";a=\"385370283\"",
            "E=McAfee;i=\"6600,9927,10863\"; a=\"821583909\"",
            "E=Sophos;i=\"6.03,229,1694761200\"; d=\"scan'208\";a=\"821583909\""
        ],
        "X-ExtLoop1": "1",
        "From": "Bruce Richardson <bruce.richardson@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "david.marchand@redhat.com, rjarry@redhat.com,\n Bruce Richardson <bruce.richardson@intel.com>",
        "Subject": "[PATCH v4 1/7] doc/prog_guide: new chapter on cmdline library",
        "Date": "Mon, 16 Oct 2023 15:06:06 +0100",
        "Message-Id": "<20231016140612.664853-2-bruce.richardson@intel.com>",
        "X-Mailer": "git-send-email 2.39.2",
        "In-Reply-To": "<20231016140612.664853-1-bruce.richardson@intel.com>",
        "References": "<20230802170052.955323-1-bruce.richardson@intel.com>\n <20231016140612.664853-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": "The cmdline library was not documented in our programmers guide, so add\na new chapter on it. This chapter covers step-by-step how to use the\nlibrary, rather than focusing on the library internals. This complements\nthe existing cmdline example app document, providing more details on the\nprocess of using the library.\n\nSigned-off-by: Bruce Richardson <bruce.richardson@intel.com>\n---\n app/test/commands.c               |   2 +\n doc/guides/prog_guide/cmdline.rst | 337 ++++++++++++++++++++++++++++++\n doc/guides/prog_guide/index.rst   |   1 +\n 3 files changed, 340 insertions(+)\n create mode 100644 doc/guides/prog_guide/cmdline.rst",
    "diff": "diff --git a/app/test/commands.c b/app/test/commands.c\nindex 31259e5c21..497d8e9952 100644\n--- a/app/test/commands.c\n+++ b/app/test/commands.c\n@@ -108,6 +108,7 @@ dump_struct_sizes(void)\n #undef DUMP_SIZE\n }\n \n+/* Add the dump_* tests cases 8< */\n static void cmd_dump_parsed(void *parsed_result,\n \t\t\t    __rte_unused struct cmdline *cl,\n \t\t\t    __rte_unused void *data)\n@@ -155,6 +156,7 @@ cmdline_parse_inst_t cmd_dump = {\n \t\tNULL,\n \t},\n };\n+/* >8 End of add the dump_* tests cases */\n \n /****************/\n \ndiff --git a/doc/guides/prog_guide/cmdline.rst b/doc/guides/prog_guide/cmdline.rst\nnew file mode 100644\nindex 0000000000..40f49a30cc\n--- /dev/null\n+++ b/doc/guides/prog_guide/cmdline.rst\n@@ -0,0 +1,337 @@\n+..  SPDX-License-Identifier: BSD-3-Clause\n+    Copyright(c) 2023 Intel Corporation.\n+\n+Command-line Library\n+====================\n+\n+Since its earliest versions, DPDK has included a command-line library -\n+primarily for internal use by, for example, ``dpdk-testpmd`` and the ``dpdk-test`` binaries,\n+but the library is also exported on install and can be used by any end application.\n+This chapter covers the basics of the command-line library and how to use it in an application.\n+\n+Library Features\n+----------------\n+\n+The DPDK command-line library supports the following features:\n+\n+* Tab-completion available for interactive terminal sessions\n+\n+* Ability to read and process commands taken from an input file, e.g. startup script\n+\n+* Parameterized commands able to take multiple parameters with different datatypes:\n+\n+   * Strings\n+   * Signed/unsigned 16/32/64-bit integers\n+   * IP Addresses\n+   * Ethernet Addresses\n+\n+* Ability to multiplex multiple commands to a single callback function\n+\n+Adding Command-line to an Application\n+-------------------------------------\n+\n+Adding a command-line instance to an application involves a number of coding steps.\n+\n+1. Define the result structure for the command, specifying the command parameters\n+\n+2. Provide an initializer for each field in the result\n+\n+3. Define the callback function for the command\n+\n+4. Provide a parse result structure instance for the command, linking the callback to the command\n+\n+5. Add the parse result structure to a command-line context\n+\n+6. Within your main application code, create a new command-line instance passing in the context.\n+\n+The next few subsections will cover each of these steps in more detail,\n+working through an example to add two commands to a command-line instance.\n+Those two commands will be:\n+\n+1. ``quit`` - as the name suggests, to close the application\n+\n+2. ``show port stats <n>`` - to display on-screen the statistics for a given ethernet port\n+\n+.. note::\n+\n+   For further examples of use of the command-line, see\n+   :doc:`cmdline example application <../sample_app_ug/cmd_line>`\n+\n+Defining Command Result Structure\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+The first structure to be defined is the structure which will be created on successful parse of a command.\n+This structure contains one member field for each token, or word, in the command.\n+The simplest case is for a one-word command, like ``quit``.\n+For this, we only need to define a structure with a single string parameter to contain that word.\n+\n+.. code-block:: c\n+\n+   struct cmd_quit_result {\n+              cmdline_fixed_string_t quit;\n+   };\n+\n+For readability, the name of the struct member should match that of the token in the command.\n+\n+For our second command, we need a structure with four member fields in it,\n+as there are four words/tokens in our command.\n+The first three are strings, and the final one is a 16-bit numeric value.\n+The resulting struct looks like:\n+\n+.. code-block:: c\n+\n+   struct cmd_show_port_stats_result {\n+      cmdline_fixed_string_t show;\n+      cmdline_fixed_string_t port;\n+      cmdline_fixed_string_t stats;\n+      uint16_t n;\n+   };\n+\n+As before, we choose names to match the tokens in the command.\n+Since our numeric parameter is a 16-bit value, we use ``uint16_t`` type for it.\n+Any of the standard sized integer types can be used as parameters, depending on the desired result.\n+\n+Beyond the standard integer types,\n+the library also allows variable parameters to be of a number of other types,\n+as called out in the feature list above.\n+\n+* For variable string parameters,\n+  the type should be ``cmdline_fixed_string_t`` - the same as for fixed tokens,\n+  but these will be initialized differently (as described below).\n+\n+* For ethernet addresses use type ``struct rte_ether_addr``\n+\n+* For IP addresses use type ``cmdline_ipaddr_t``\n+\n+Providing Field Initializers\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+Each field of our result structure needs an initializer.\n+For fixed string tokens, like \"quit\", \"show\" and \"port\", the initializer will be the string itself.\n+\n+.. code-block:: c\n+\n+   static cmdline_parse_token_string_t cmd_quit_quit_tok =\n+      TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, \"quit\");\n+\n+The convention for naming used here is to include the base name of the overall result structure -\n+``cmd_quit`` in this case,\n+as well as the name of the field within that structure - ``quit`` in this case, followed by ``_tok``.\n+(This is why there is a double ``quit`` in the name above).\n+\n+This naming convention is seen in our second example,\n+which also demonstrates how to define a numeric initializer.\n+\n+\n+.. code-block:: c\n+\n+   static cmdline_parse_token_string_t cmd_show_port_stats_show_tok =\n+      TOKEN_STRING_INITIALIZER(struct cmd_show_port_stats_result, show, \"show\");\n+   static cmdline_parse_token_string_t cmd_show_port_stats_port_tok =\n+      TOKEN_STRING_INITIALIZER(struct cmd_show_port_stats_result, port, \"port\");\n+   static cmdline_parse_token_string_t cmd_show_port_stats_stats_tok =\n+      TOKEN_STRING_INITIALIZER(struct cmd_show_port_stats_result, stats, \"stats\");\n+   static cmdline_parse_token_num_t cmd_show_port_stats_n_tok =\n+      TOKEN_NUM_INITIALIZER(struct cmd_show_port_stats_result, n, RTE_UINT16);\n+\n+For variable string tokens, the same ``TOKEN_STRING_INITIALIZER`` macro should be used.\n+However, the final parameter should be ``NULL`` rather than a hard-coded token string.\n+\n+For numeric parameters, the final parameter to the ``TOKEN_NUM_INITIALIZER`` macro should be the\n+cmdline type matching the variable type defined in the result structure,\n+e.g. RTE_UINT8, RTE_UINT32, etc.\n+\n+For IP addresses, the macro ``TOKEN_IPADDR_INITIALIZER`` should be used.\n+\n+For ethernet addresses, the macro ``TOKEN_ETHERADDR_INITIALIZER`` should be used.\n+\n+Defining Callback Function\n+~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+For each command, we need to define a function to be called once the command has been recognised.\n+The callback function should have type:\n+\n+.. code:: c\n+\n+   void (*f)(void *, struct cmdline *, void *)\n+\n+where the first parameter is a pointer to the result structure defined above,\n+the second parameter is the command-line instance,\n+and the final parameter is a user-defined pointer provided when we associate the callback with the command.\n+Most callback functions only use the first parameter, or none at all,\n+but the additional two parameters provide some extra flexibility,\n+to allow the callback to work with non-global state in your application.\n+\n+For our two example commands, the relevant callback functions would look very similar in definition.\n+However, within the function body,\n+we assume that the user would need to reference the result structure to extract the port number in\n+the second case.\n+\n+.. code:: c\n+\n+   void\n+   cmd_quit_parsed(void *parsed_result, struct cmdline *cl, void *data)\n+   {\n+      quit = 1;\n+   }\n+   void\n+   cmd_show_port_stats_parsed(void *parsed_result, struct cmdline *cl, void *data)\n+   {\n+      struct cmd_show_port_stats_result *res = parsed_result;\n+      uint16_t port_id = res->n;\n+      ...\n+   }\n+\n+\n+Associating Callback and Command\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+The ``cmdline_parse_inst_t`` type defines a \"parse instance\",\n+i.e. a sequence of tokens to be matched and then an associated function to be called.\n+Also included in the instance type are a field for help text for the command,\n+and any additional user-defined parameter to be passed to the callback functions referenced above.\n+For example, for our simple \"quit\" command:\n+\n+.. code-block:: c\n+\n+   static cmdline_parse_inst_t cmd_quit = {\n+       .f = cmd_quit_parsed,\n+       .data = NULL,\n+       .help_str = \"Close the application\",\n+       .tokens = {\n+           (void *)&cmd_quit_quit_tok,\n+           NULL\n+       }\n+   };\n+\n+In this case, we firstly identify the callback function to be called,\n+then set the user-defined parameter to NULL,\n+provide a help message to be given, on request, to the user explaining the command,\n+before finally listing out the single token to be matched for this command instance.\n+\n+For our second, port stats, example,\n+as well as making things a little more complicated by having multiple tokens to be matched,\n+we can also demonstrate passing in a parameter to the function.\n+Let us suppose that our application does not always use all the ports available to it,\n+but instead only uses a subset of the ports, stored in an array called ``active_ports``.\n+Our stats command, therefore, should only display stats for the currently in-use ports,\n+so we pass this ``active_ports`` array.\n+(For simplicity of illustration, we shall assume that the array uses a terminating marker,\n+e.g. -1 for the end of the port list, so we don't need to pass in a length parameter too.)\n+\n+.. code-block:: c\n+\n+   extern int16_t active_ports[];\n+   ...\n+   static cmdline_parse_inst_t cmd_show_port_stats = {\n+       .f = cmd_show_port_stats_parsed,\n+       .data = active_ports,\n+       .help_str = \"Show statistics for active network ports\",\n+       .tokens = {\n+           (void *)&cmd_show_port_stats_show_tok,\n+           (void *)&cmd_show_port_stats_port_tok,\n+           (void *)&cmd_show_port_stats_stats_tok,\n+           (void *)&cmd_show_port_stats_n_tok,\n+           NULL\n+       }\n+   };\n+\n+\n+Adding Command to Command-line Context\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+Now that we have configured each individual command and callback,\n+we need to merge these into a single array of command-line \"contexts\".\n+This context array will be used to create the actual command-line instance in the application.\n+Thankfully, each context entry is the same as each parse instance,\n+so our array is defined by simply listing out the previously defined command parse instances.\n+\n+.. code-block:: c\n+\n+   static cmdline_parse_ctx_t ctx[] = {\n+       &cmd_quit,\n+       &cmd_show_port_stats,\n+       NULL\n+   };\n+\n+The context list must be terminated by a NULL entry.\n+\n+Creating a Command-line Instance\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+Once we have our ``ctx`` variable defined,\n+we now just need to call the API to create the new command-line instance in our application.\n+The basic API is ``cmdline_new`` which will create an interactive command-line with all commands available.\n+However, if additional features for interactive use - such as tab-completion -\n+are desired, it is recommended that ``cmdline_new_stdin`` be used instead.\n+\n+A pattern that can be used in applications is to use ``cmdline_new`` for processing any startup commands,\n+either from file or from the environment (as is done in the \"dpdk-test\" application),\n+and then using ``cmdline_stdin_new`` thereafter to handle the interactive part.\n+For example, to handle a startup file and then provide an interactive prompt:\n+\n+.. code-block:: c\n+\n+   struct cmdline *cl;\n+   int fd = open(startup_file, O_RDONLY);\n+\n+   if (fd >= 0) {\n+       cl = cmdline_new(ctx, \"\", fd, STDOUT_FILENO);\n+       if (cl == NULL) {\n+           /* error handling */\n+       }\n+       cmdline_interact(cl);\n+       cmdline_quit(cl);\n+       close(fd);\n+   }\n+\n+   cl = cmdline_stdin_new(ctx, \"Proxy>> \");\n+   if (cl == NULL) {\n+       /* error handling */\n+   }\n+   cmdline_interact(cl);\n+   cmdline_stdin_exit(cl);\n+\n+\n+Multiplexing Multiple Commands to a Single Function\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+To reduce the amount of boiler-plate code needed when creating a command-line for an application,\n+it is possible to merge a number of commands together to have them call a separate function.\n+This can be done in a number of different ways:\n+\n+* A callback function can be used as the target for a number of different commands.\n+  Which command was used for entry to the function can be determined by examining the first parameter,\n+  ``parsed_result`` in our examples above.\n+\n+* For simple string commands, multiple options can be concatenated using the \"#\" character.\n+  For example: ``exit#quit``, specified as a token initializer,\n+  will match either on the string \"exit\" or the string \"quit\".\n+\n+As a concrete example,\n+these two techniques are used in the DPDK unit test application ``dpdk-test``,\n+where a single command ``cmdline_parse_t`` instance is used for all the \"dump_<item>\" test cases.\n+\n+.. literalinclude:: ../../../app/test/commands.c\n+    :language: c\n+    :start-after: Add the dump_* tests cases 8<\n+    :end-before: >8 End of add the dump_* tests cases\n+\n+\n+Examples of Command-line Use in DPDK\n+------------------------------------\n+\n+To help the user follow the steps provided above,\n+the following DPDK files can be consulted for examples of command-line use.\n+\n+.. note::\n+\n+   This is not an exhaustive list of examples of command-line use in DPDK.\n+   It is simply a list of a few files that may be of use to the application developer.\n+   Some of these referenced files contain more complex examples of use that others.\n+\n+* ``commands.c/.h`` in ``examples/cmdline``\n+\n+* ``mp_commands.c/.h`` in ``examples/multi_process/simple_mp``\n+\n+* ``commands.c`` in ``app/test``\ndiff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst\nindex e517f0e259..94964357ff 100644\n--- a/doc/guides/prog_guide/index.rst\n+++ b/doc/guides/prog_guide/index.rst\n@@ -13,6 +13,7 @@ Programmer's Guide\n     source_org\n     env_abstraction_layer\n     log_lib\n+    cmdline\n     service_cores\n     trace_lib\n     rcu_lib\n",
    "prefixes": [
        "v4",
        "1/7"
    ]
}