get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 114300,
    "url": "https://patches.dpdk.org/api/patches/114300/?format=api",
    "web_url": "https://patches.dpdk.org/project/dpdk/patch/20220727225431.600913-5-cristian.dumitrescu@intel.com/",
    "project": {
        "id": 1,
        "url": "https://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": "<20220727225431.600913-5-cristian.dumitrescu@intel.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/20220727225431.600913-5-cristian.dumitrescu@intel.com",
    "date": "2022-07-27T22:54:19",
    "name": "[V4,05/17] pipeline: generate the code for pipeline specification structure",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "65d3b88c3460915f0778af8bd4f8d6504264b333",
    "submitter": {
        "id": 19,
        "url": "https://patches.dpdk.org/api/people/19/?format=api",
        "name": "Cristian Dumitrescu",
        "email": "cristian.dumitrescu@intel.com"
    },
    "delegate": {
        "id": 1,
        "url": "https://patches.dpdk.org/api/users/1/?format=api",
        "username": "tmonjalo",
        "first_name": "Thomas",
        "last_name": "Monjalon",
        "email": "thomas@monjalon.net"
    },
    "mbox": "https://patches.dpdk.org/project/dpdk/patch/20220727225431.600913-5-cristian.dumitrescu@intel.com/mbox/",
    "series": [
        {
            "id": 24107,
            "url": "https://patches.dpdk.org/api/series/24107/?format=api",
            "web_url": "https://patches.dpdk.org/project/dpdk/list/?series=24107",
            "date": "2022-07-27T22:54:15",
            "name": "[V4,01/17] pipeline: add pipeline name",
            "version": 4,
            "mbox": "https://patches.dpdk.org/series/24107/mbox/"
        }
    ],
    "comments": "https://patches.dpdk.org/api/patches/114300/comments/",
    "check": "success",
    "checks": "https://patches.dpdk.org/api/patches/114300/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 40E3EA00C4;\n\tThu, 28 Jul 2022 00:55:00 +0200 (CEST)",
            "from [217.70.189.124] (localhost [127.0.0.1])\n\tby mails.dpdk.org (Postfix) with ESMTP id 09D3F42B80;\n\tThu, 28 Jul 2022 00:54:41 +0200 (CEST)",
            "from mga11.intel.com (mga11.intel.com [192.55.52.93])\n by mails.dpdk.org (Postfix) with ESMTP id 068C042B71\n for <dev@dpdk.org>; Thu, 28 Jul 2022 00:54:37 +0200 (CEST)",
            "from orsmga008.jf.intel.com ([10.7.209.65])\n by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384;\n 27 Jul 2022 15:54:37 -0700",
            "from silpixa00400573.ir.intel.com (HELO\n silpixa00400573.ger.corp.intel.com.) ([10.237.223.157])\n by orsmga008.jf.intel.com with ESMTP; 27 Jul 2022 15:54:36 -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=1658962478; x=1690498478;\n h=from:to:cc:subject:date:message-id:in-reply-to:\n references:mime-version:content-transfer-encoding;\n bh=kV8l83wbMRr+LMoXR2nwmAq9SLVd4xV9uLu3kZf6vKM=;\n b=ESWU+Sy2gQQq5dn7bRbTdHQjq1W01bBJvAVfr8ge9fKMJBz7eJKMwzUD\n OCWpZXpcplECer3r7z1SKq5KVgh+lDCQdTRdKkYl87Bhhc06CO2HHkCWp\n OdgCJ9zpVhzx225rLFurhh8qDkY5XaHAlnsflEuETEatr8RbTjWy7qgIx\n ZZgaZm9ohEVqgRmzdXz3dcpBpTuDZE7dgY2C5mASraN6W7ybylkRYi1Of\n cBlzZYSEHoCqU+oZ6Lsn6RKJiORs6fOpIALMt0e05/upWEu0jjogF2dan\n oL1Jh6QaAmHC0RQ101YkBDxVY8Ja4ig+uRS/3t2lPE5DcL7tn6flunvcc g==;",
        "X-IronPort-AV": [
            "E=McAfee;i=\"6400,9594,10421\"; a=\"285912163\"",
            "E=Sophos;i=\"5.93,196,1654585200\"; d=\"scan'208\";a=\"285912163\"",
            "E=Sophos;i=\"5.93,196,1654585200\"; d=\"scan'208\";a=\"628572576\""
        ],
        "X-ExtLoop1": "1",
        "From": "Cristian Dumitrescu <cristian.dumitrescu@intel.com>",
        "To": "dev@dpdk.org",
        "Cc": "\"Kamalakannan R .\" <kamalakannan.r@intel.com>",
        "Subject": "[PATCH V4 05/17] pipeline: generate the code for pipeline\n specification structure",
        "Date": "Wed, 27 Jul 2022 22:54:19 +0000",
        "Message-Id": "<20220727225431.600913-5-cristian.dumitrescu@intel.com>",
        "X-Mailer": "git-send-email 2.34.1",
        "In-Reply-To": "<20220727225431.600913-1-cristian.dumitrescu@intel.com>",
        "References": "<20220727223639.598932-1-cristian.dumitrescu@intel.com>\n <20220727225431.600913-1-cristian.dumitrescu@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 support to export the pipeline specification data structure to a C\nsource code file.\n\nSigned-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>\nSigned-off-by: Kamalakannan R. <kamalakannan.r@intel.com>\n---\n lib/pipeline/rte_swx_pipeline_spec.c | 622 +++++++++++++++++++++++++++\n lib/pipeline/rte_swx_pipeline_spec.h |   5 +\n 2 files changed, 627 insertions(+)",
    "diff": "diff --git a/lib/pipeline/rte_swx_pipeline_spec.c b/lib/pipeline/rte_swx_pipeline_spec.c\nindex 62929a9da6..bf21fe17ba 100644\n--- a/lib/pipeline/rte_swx_pipeline_spec.c\n+++ b/lib/pipeline/rte_swx_pipeline_spec.c\n@@ -2,6 +2,7 @@\n  * Copyright(c) 2020 Intel Corporation\n  */\n #include <stdint.h>\n+#include <inttypes.h>\n #include <stdlib.h>\n #include <stdio.h>\n #include <string.h>\n@@ -2103,6 +2104,627 @@ pipeline_spec_free(struct pipeline_spec *s)\n \tmemset(s, 0, sizeof(struct pipeline_spec));\n }\n \n+static const char *\n+match_type_string_get(enum rte_swx_table_match_type match_type)\n+{\n+\tswitch (match_type) {\n+\tcase RTE_SWX_TABLE_MATCH_WILDCARD: return \"RTE_SWX_TABLE_MATCH_WILDCARD\";\n+\tcase RTE_SWX_TABLE_MATCH_LPM: return \"RTE_SWX_TABLE_MATCH_LPM\";\n+\tcase RTE_SWX_TABLE_MATCH_EXACT: return \"RTE_SWX_TABLE_MATCH_EXACT\";\n+\tdefault: return \"RTE_SWX_TABLE_MATCH_UNKNOWN\";\n+\t}\n+}\n+\n+void\n+pipeline_spec_codegen(FILE *f,\n+\t\t      struct pipeline_spec *s)\n+{\n+\tuint32_t i;\n+\n+\t/* Check the input arguments. */\n+\tif (!f || !s)\n+\t\treturn;\n+\n+\t/* extobj. */\n+\tfprintf(f, \"static struct extobj_spec extobjs[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_extobjs; i++) {\n+\t\tstruct extobj_spec *extobj_spec = &s->extobjs[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", extobj_spec->name);\n+\t\tfprintf(f, \"\\t\\t.extern_type_name = \\\"%s\\\",\\n\", extobj_spec->extern_type_name);\n+\t\tif (extobj_spec->pragma)\n+\t\t\tfprintf(f, \"\\t\\t.pragma = \\\"%s\\\",\\n\", extobj_spec->pragma);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t.pragma = NULL,\\n\");\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* regarray. */\n+\tfprintf(f, \"static struct regarray_spec regarrays[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_regarrays; i++) {\n+\t\tstruct regarray_spec *regarray_spec = &s->regarrays[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", regarray_spec->name);\n+\t\tfprintf(f, \"\\t\\t.init_val = %\" PRIu64 \",\\n\", regarray_spec->init_val);\n+\t\tfprintf(f, \"\\t\\t.size = %u,\\n\", regarray_spec->size);\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* metarray. */\n+\tfprintf(f, \"static struct metarray_spec metarrays[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_metarrays; i++) {\n+\t\tstruct metarray_spec *metarray_spec = &s->metarrays[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", metarray_spec->name);\n+\t\tfprintf(f, \"\\t\\t.size = %u,\\n\", metarray_spec->size);\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* struct. */\n+\tfor (i = 0; i < s->n_structs; i++) {\n+\t\tstruct struct_spec *struct_spec = &s->structs[i];\n+\t\tuint32_t j;\n+\n+\t\tfprintf(f, \"static struct rte_swx_field_params struct_%s_fields[] = {\\n\",\n+\t\t\tstruct_spec->name);\n+\n+\t\tfor (j = 0; j < struct_spec->n_fields; j++) {\n+\t\t\tstruct rte_swx_field_params *field = &struct_spec->fields[j];\n+\n+\t\t\tfprintf(f, \"\\t[%d] = {\\n\", j);\n+\t\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", field->name);\n+\t\t\tfprintf(f, \"\\t\\t.n_bits = %u,\\n\", field->n_bits);\n+\t\t\tfprintf(f, \"\\t},\\n\");\n+\t\t}\n+\n+\t\tfprintf(f, \"};\\n\\n\");\n+\t}\n+\n+\tfprintf(f, \"static struct struct_spec structs[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_structs; i++) {\n+\t\tstruct struct_spec *struct_spec = &s->structs[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", struct_spec->name);\n+\t\tfprintf(f, \"\\t\\t.fields = struct_%s_fields,\\n\", struct_spec->name);\n+\t\tfprintf(f, \"\\t\\t.n_fields = \"\n+\t\t\t\"sizeof(struct_%s_fields) / sizeof(struct_%s_fields[0]),\\n\",\n+\t\t\tstruct_spec->name,\n+\t\t\tstruct_spec->name);\n+\t\tfprintf(f, \"\\t\\t.varbit = %d,\\n\", struct_spec->varbit);\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* header. */\n+\tfprintf(f, \"static struct header_spec headers[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_headers; i++) {\n+\t\tstruct header_spec *header_spec = &s->headers[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", header_spec->name);\n+\t\tfprintf(f, \"\\t\\t.struct_type_name = \\\"%s\\\",\\n\", header_spec->struct_type_name);\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* metadata. */\n+\tfprintf(f, \"static struct metadata_spec metadata[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_metadata; i++) {\n+\t\tstruct metadata_spec *metadata_spec = &s->metadata[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.struct_type_name = \\\"%s\\\",\\n\", metadata_spec->struct_type_name);\n+\t\tfprintf(f, \"\\t},\\n\");\n+\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* action. */\n+\tfor (i = 0; i < s->n_actions; i++) {\n+\t\tstruct action_spec *action_spec = &s->actions[i];\n+\t\tuint32_t j;\n+\n+\t\tfprintf(f, \"static const char *action_%s_initial_instructions[] = {\\n\",\n+\t\t\taction_spec->name);\n+\n+\t\tfor (j = 0; j < action_spec->n_instructions; j++) {\n+\t\t\tconst char *instr = action_spec->instructions[j];\n+\n+\t\t\tfprintf(f, \"\\t[%d] = \\\"%s\\\",\\n\", j, instr);\n+\t\t}\n+\n+\t\tfprintf(f, \"};\\n\\n\");\n+\t}\n+\n+\tfprintf(f, \"static struct action_spec actions[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_actions; i++) {\n+\t\tstruct action_spec *action_spec = &s->actions[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", action_spec->name);\n+\n+\t\tif (action_spec->args_struct_type_name)\n+\t\t\tfprintf(f, \"\\t\\t.args_struct_type_name = \\\"%s\\\",\\n\",\n+\t\t\t\taction_spec->args_struct_type_name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t.args_struct_type_name = NULL,\\n\");\n+\n+\t\tfprintf(f, \"\\t\\t.instructions = action_%s_initial_instructions,\\n\",\n+\t\t\taction_spec->name);\n+\t\tfprintf(f, \"\\t\\t.n_instructions = \"\n+\t\t\t\"sizeof(action_%s_initial_instructions) / \"\n+\t\t\t\"sizeof(action_%s_initial_instructions[0]),\\n\",\n+\t\t\taction_spec->name,\n+\t\t\taction_spec->name);\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* table. */\n+\tfor (i = 0; i < s->n_tables; i++) {\n+\t\tstruct table_spec *table_spec = &s->tables[i];\n+\t\tuint32_t j;\n+\n+\t\t/* fields. */\n+\t\tif (table_spec->params.fields && table_spec->params.n_fields) {\n+\t\t\tfprintf(f, \"static struct rte_swx_match_field_params \"\n+\t\t\t\t\"table_%s_fields[] = {\\n\",\n+\t\t\t\ttable_spec->name);\n+\n+\t\t\tfor (j = 0; j < table_spec->params.n_fields; j++) {\n+\t\t\t\tstruct rte_swx_match_field_params *field =\n+\t\t\t\t\t&table_spec->params.fields[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = {\\n\", j);\n+\t\t\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", field->name);\n+\t\t\t\tfprintf(f, \"\\t\\t.match_type = %s,\\n\",\n+\t\t\t\t\tmatch_type_string_get(field->match_type));\n+\t\t\t\tfprintf(f, \"\\t},\\n\");\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\n+\t\t/* action_names. */\n+\t\tif (table_spec->params.action_names && table_spec->params.n_actions) {\n+\t\t\tfprintf(f, \"static const char *table_%s_action_names[] = {\\n\",\n+\t\t\t\ttable_spec->name);\n+\n+\t\t\tfor (j = 0; j < table_spec->params.n_actions; j++) {\n+\t\t\t\tconst char *action_name = table_spec->params.action_names[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = \\\"%s\\\",\\n\", j, action_name);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\n+\t\t/* action_is_for_table_entries. */\n+\t\tif (table_spec->params.action_is_for_table_entries &&\n+\t\t    table_spec->params.n_actions) {\n+\t\t\tfprintf(f, \"static int table_%s_action_is_for_table_entries[] = {\\n\",\n+\t\t\t\ttable_spec->name);\n+\n+\t\t\tfor (j = 0; j < table_spec->params.n_actions; j++) {\n+\t\t\t\tint value = table_spec->params.action_is_for_table_entries[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = %d,\\n\", j, value);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\n+\t\t/* action_is_for_default_entry. */\n+\t\tif (table_spec->params.action_is_for_default_entry &&\n+\t\t    table_spec->params.n_actions) {\n+\t\t\tfprintf(f, \"static int table_%s_action_is_for_default_entry[] = {\\n\",\n+\t\t\t\ttable_spec->name);\n+\n+\t\t\tfor (j = 0; j < table_spec->params.n_actions; j++) {\n+\t\t\t\tint value = table_spec->params.action_is_for_default_entry[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = %d,\\n\", j, value);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\t}\n+\n+\tfprintf(f, \"static struct table_spec tables[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_tables; i++) {\n+\t\tstruct table_spec *table_spec = &s->tables[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", table_spec->name);\n+\n+\t\tfprintf(f, \"\\t\\t.params = {\\n\");\n+\n+\t\tif (table_spec->params.fields && table_spec->params.n_fields) {\n+\t\t\tfprintf(f, \"\\t\\t\\t.fields = table_%s_fields,\\n\", table_spec->name);\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_fields = \"\n+\t\t\t\t\"sizeof(table_%s_fields) / sizeof(table_%s_fields[0]),\\n\",\n+\t\t\t\ttable_spec->name,\n+\t\t\t\ttable_spec->name);\n+\t\t} else {\n+\t\t\tfprintf(f, \"\\t\\t\\t.fields = NULL,\\n\");\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_fields = 0,\\n\");\n+\t\t}\n+\n+\t\tif (table_spec->params.action_names && table_spec->params.n_actions)\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_names = table_%s_action_names,\\n\",\n+\t\t\t\ttable_spec->name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_names = NULL,\\n\");\n+\n+\t\tif (table_spec->params.action_is_for_table_entries && table_spec->params.n_actions)\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_is_for_table_entries = \"\n+\t\t\t\t\"table_%s_action_is_for_table_entries,\\n\",\n+\t\t\t\ttable_spec->name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_is_for_table_entries = NULL,\\n\");\n+\n+\t\tif (table_spec->params.action_is_for_default_entry && table_spec->params.n_actions)\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_is_for_default_entry = \"\n+\t\t\t\t\"table_%s_action_is_for_default_entry,\\n\",\n+\t\t\t\ttable_spec->name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_is_for_default_entry = NULL,\\n\");\n+\n+\t\tif (table_spec->params.n_actions)\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_actions = sizeof(table_%s_action_names) / \"\n+\t\t\t\t\"sizeof(table_%s_action_names[0]),\\n\",\n+\t\t\t\ttable_spec->name,\n+\t\t\t\ttable_spec->name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_actions = 0,\\n\");\n+\n+\t\tif (table_spec->params.default_action_name)\n+\t\t\tfprintf(f, \"\\t\\t\\t.default_action_name = \\\"%s\\\",\\n\",\n+\t\t\t\ttable_spec->params.default_action_name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.default_action_name = NULL,\\n\");\n+\n+\t\tif (table_spec->params.default_action_args)\n+\t\t\tfprintf(f, \"\\t\\t\\t.default_action_args = \\\"%s\\\",\\n\",\n+\t\t\t\ttable_spec->params.default_action_args);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.default_action_args = NULL,\\n\");\n+\n+\t\tfprintf(f, \"\\t\\t\\t.default_action_is_const = %d,\\n\",\n+\t\t\ttable_spec->params.default_action_is_const);\n+\t\tfprintf(f, \"\\t\\t},\\n\");\n+\n+\t\tif (table_spec->recommended_table_type_name)\n+\t\t\tfprintf(f, \"\\t\\t.recommended_table_type_name = \\\"%s\\\",\\n\",\n+\t\t\t\ttable_spec->recommended_table_type_name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t.recommended_table_type_name = NULL,\\n\");\n+\n+\t\tif (table_spec->args)\n+\t\t\tfprintf(f, \"\\t\\t.args = \\\"%s\\\",\\n\", table_spec->args);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t.args = NULL,\\n\");\n+\n+\t\tfprintf(f, \"\\t\\t.size = %u,\\n\", table_spec->size);\n+\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* selector. */\n+\tfor (i = 0; i < s->n_selectors; i++) {\n+\t\tstruct selector_spec *selector_spec = &s->selectors[i];\n+\t\tuint32_t j;\n+\n+\t\tif (selector_spec->params.selector_field_names &&\n+\t\t    selector_spec->params.n_selector_fields) {\n+\t\t\tfprintf(f, \"static const char *selector_%s_field_names[] = {\\n\",\n+\t\t\t\tselector_spec->name);\n+\n+\t\t\tfor (j = 0; j < selector_spec->params.n_selector_fields; j++) {\n+\t\t\t\tconst char *field_name =\n+\t\t\t\t\tselector_spec->params.selector_field_names[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = \\\"%s\\\",\\n\", j, field_name);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\t}\n+\n+\tfprintf(f, \"static struct selector_spec selectors[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_selectors; i++) {\n+\t\tstruct selector_spec *selector_spec = &s->selectors[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", selector_spec->name);\n+\t\tfprintf(f, \"\\t\\t.params = {\\n\");\n+\n+\t\tif (selector_spec->params.group_id_field_name)\n+\t\t\tfprintf(f, \"\\t\\t\\t.group_id_field_name = \\\"%s\\\",\\n\",\n+\t\t\t\tselector_spec->params.group_id_field_name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.group_id_field_name = NULL,\\n\");\n+\n+\t\tif (selector_spec->params.selector_field_names &&\n+\t\t    selector_spec->params.n_selector_fields) {\n+\t\t\tfprintf(f, \"\\t\\t\\t.selector_field_names = selector_%s_field_names,\\n\",\n+\t\t\t\tselector_spec->name);\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_selector_fields = \"\n+\t\t\t\t\"sizeof(selector_%s_field_names) / sizeof(selector_%s_field_names[0]),\\n\",\n+\t\t\t\tselector_spec->name,\n+\t\t\t\tselector_spec->name);\n+\t\t} else {\n+\t\t\tfprintf(f, \"\\t\\t\\t.selector_field_names = NULL,\\n\");\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_selector_fields = 0,\\n\");\n+\t\t}\n+\n+\t\tif (selector_spec->params.member_id_field_name)\n+\t\t\tfprintf(f, \"\\t\\t\\t.member_id_field_name = \\\"%s\\\",\\n\",\n+\t\t\t\tselector_spec->params.member_id_field_name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.member_id_field_name = NULL,\\n\");\n+\n+\t\tfprintf(f, \"\\t\\t\\t.n_groups_max = %u,\\n\", selector_spec->params.n_groups_max);\n+\n+\t\tfprintf(f, \"\\t\\t\\t.n_members_per_group_max = %u,\\n\",\n+\t\t\tselector_spec->params.n_members_per_group_max);\n+\n+\t\tfprintf(f, \"\\t\\t},\\n\");\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* learner. */\n+\tfor (i = 0; i < s->n_learners; i++) {\n+\t\tstruct learner_spec *learner_spec = &s->learners[i];\n+\t\tuint32_t j;\n+\n+\t\t/* field_names. */\n+\t\tif (learner_spec->params.field_names && learner_spec->params.n_fields) {\n+\t\t\tfprintf(f, \"static const char *learner_%s_field_names[] = {\\n\",\n+\t\t\t\tlearner_spec->name);\n+\n+\t\t\tfor (j = 0; j < learner_spec->params.n_fields; j++) {\n+\t\t\t\tconst char *field_name = learner_spec->params.field_names[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = \\\"%s\\\",\\n\", j, field_name);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\n+\t\t/* action_names. */\n+\t\tif (learner_spec->params.action_names && learner_spec->params.n_actions) {\n+\t\t\tfprintf(f, \"static const char *learner_%s_action_names[] = {\\n\",\n+\t\t\t\tlearner_spec->name);\n+\n+\t\t\tfor (j = 0; j < learner_spec->params.n_actions; j++) {\n+\t\t\t\tconst char *action_name = learner_spec->params.action_names[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = \\\"%s\\\",\\n\", j, action_name);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\n+\t\t/* action_is_for_table_entries. */\n+\t\tif (learner_spec->params.action_is_for_table_entries &&\n+\t\t    learner_spec->params.n_actions) {\n+\t\t\tfprintf(f, \"static int learner_%s_action_is_for_table_entries[] = {\\n\",\n+\t\t\t\tlearner_spec->name);\n+\n+\t\t\tfor (j = 0; j < learner_spec->params.n_actions; j++) {\n+\t\t\t\tint value = learner_spec->params.action_is_for_table_entries[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = %d,\\n\", j, value);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\n+\t\t/* action_is_for_default_entry. */\n+\t\tif (learner_spec->params.action_is_for_default_entry &&\n+\t\t    learner_spec->params.n_actions) {\n+\t\t\tfprintf(f, \"static int learner_%s_action_is_for_default_entry[] = {\\n\",\n+\t\t\t\tlearner_spec->name);\n+\n+\t\t\tfor (j = 0; j < learner_spec->params.n_actions; j++) {\n+\t\t\t\tint value = learner_spec->params.action_is_for_default_entry[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = %d,\\n\", j, value);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\n+\t\t/* timeout. */\n+\t\tif (learner_spec->timeout && learner_spec->n_timeouts) {\n+\t\t\tfprintf(f, \"static uint32_t learner_%s_timeout[] = {\\n\",\n+\t\t\t\tlearner_spec->name);\n+\n+\t\t\tfor (j = 0; j < learner_spec->n_timeouts; j++) {\n+\t\t\t\tuint32_t value = learner_spec->timeout[j];\n+\n+\t\t\t\tfprintf(f, \"\\t[%d] = %u,\\n\", j, value);\n+\t\t\t}\n+\n+\t\t\tfprintf(f, \"};\\n\\n\");\n+\t\t}\n+\t}\n+\n+\tfprintf(f, \"static struct learner_spec learners[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_learners; i++) {\n+\t\tstruct learner_spec *learner_spec = &s->learners[i];\n+\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t\\t.name = \\\"%s\\\",\\n\", learner_spec->name);\n+\n+\t\tfprintf(f, \"\\t\\t.params = {\\n\");\n+\n+\t\tif (learner_spec->params.field_names && learner_spec->params.n_fields) {\n+\t\t\tfprintf(f, \"\\t\\t\\t.field_names = learner_%s_field_names,\\n\",\n+\t\t\t\tlearner_spec->name);\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_fields = \"\n+\t\t\t\t\"sizeof(learner_%s_field_names) / \"\n+\t\t\t\t\"sizeof(learner_%s_field_names[0]),\\n\",\n+\t\t\t\tlearner_spec->name,\n+\t\t\t\tlearner_spec->name);\n+\t\t} else {\n+\t\t\tfprintf(f, \"\\t\\t\\t.field_names = NULL,\\n\");\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_fields = 0,\\n\");\n+\t\t}\n+\n+\t\tif (learner_spec->params.action_names && learner_spec->params.n_actions)\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_names = learner_%s_action_names,\\n\",\n+\t\t\t\tlearner_spec->name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_names = NULL,\\n\");\n+\n+\t\tif (learner_spec->params.action_is_for_table_entries &&\n+\t\t    learner_spec->params.n_actions)\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_is_for_table_entries = \"\n+\t\t\t\t\"learner_%s_action_is_for_table_entries,\\n\",\n+\t\t\t\tlearner_spec->name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_is_for_table_entries = NULL,\\n\");\n+\n+\t\tif (learner_spec->params.action_is_for_default_entry &&\n+\t\t    learner_spec->params.n_actions)\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_is_for_default_entry = \"\n+\t\t\t\t\"learner_%s_action_is_for_default_entry,\\n\",\n+\t\t\t\tlearner_spec->name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.action_is_for_default_entry = NULL,\\n\");\n+\n+\t\tif (learner_spec->params.action_names && learner_spec->params.n_actions)\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_actions = \"\n+\t\t\t\t\"sizeof(learner_%s_action_names) / sizeof(learner_%s_action_names[0]),\\n\",\n+\t\t\t\tlearner_spec->name,\n+\t\t\t\tlearner_spec->name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_actions = NULL,\\n\");\n+\n+\t\tif (learner_spec->params.default_action_name)\n+\t\t\tfprintf(f, \"\\t\\t\\t.default_action_name = \\\"%s\\\",\\n\",\n+\t\t\t\tlearner_spec->params.default_action_name);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.default_action_name = NULL,\\n\");\n+\n+\t\tif (learner_spec->params.default_action_args)\n+\t\t\tfprintf(f, \"\\t\\t\\t.default_action_args = \\\"%s\\\",\\n\",\n+\t\t\t\tlearner_spec->params.default_action_args);\n+\t\telse\n+\t\t\tfprintf(f, \"\\t\\t\\t.default_action_args = NULL,\\n\");\n+\n+\t\tfprintf(f, \"\\t\\t\\t.default_action_is_const = %d,\\n\",\n+\t\t\tlearner_spec->params.default_action_is_const);\n+\n+\t\tfprintf(f, \"\\t\\t},\\n\");\n+\n+\t\tfprintf(f, \"\\t\\t.size = %u,\\n\", learner_spec->size);\n+\n+\t\tif (learner_spec->timeout && learner_spec->n_timeouts) {\n+\t\t\tfprintf(f, \"\\t\\t.timeout = learner_%s_timeout,\\n\", learner_spec->name);\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_timeouts = \"\n+\t\t\t\t\"sizeof(learner_%s_timeout) / sizeof(learner_%s_timeout[0]),\\n\",\n+\t\t\t\tlearner_spec->name,\n+\t\t\t\tlearner_spec->name);\n+\t\t} else {\n+\t\t\tfprintf(f, \"\\t\\t.timeout = NULL,\\n\");\n+\t\t\tfprintf(f, \"\\t\\t\\t.n_timeouts = 0,\\n\");\n+\t\t}\n+\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* apply. */\n+\tfor (i = 0; i < s->n_apply; i++) {\n+\t\tstruct apply_spec *apply_spec = &s->apply[i];\n+\t\tuint32_t j;\n+\n+\t\tfprintf(f, \"static const char *apply%u_initial_instructions[] = {\\n\", i);\n+\n+\t\tfor (j = 0; j < apply_spec->n_instructions; j++) {\n+\t\t\tconst char *instr = apply_spec->instructions[j];\n+\n+\t\t\tfprintf(f, \"\\t[%d] = \\\"%s\\\",\\n\", j, instr);\n+\t\t}\n+\n+\t\tfprintf(f, \"};\\n\\n\");\n+\t}\n+\n+\tfprintf(f, \"static struct apply_spec apply[] = {\\n\");\n+\n+\tfor (i = 0; i < s->n_apply; i++) {\n+\t\tfprintf(f, \"\\t[%d] = {\\n\", i);\n+\t\tfprintf(f, \"\\t.instructions = apply%u_initial_instructions,\\n\", i);\n+\t\tfprintf(f, \"\\t.n_instructions = \"\n+\t\t\t\"sizeof(apply%u_initial_instructions) / \"\n+\t\t\t\"sizeof(apply%u_initial_instructions[0]),\\n\",\n+\t\t\ti,\n+\t\t\ti);\n+\t\tfprintf(f, \"\\t},\\n\");\n+\t}\n+\n+\tfprintf(f, \"};\\n\\n\");\n+\n+\t/* pipeline. */\n+\tfprintf(f, \"struct pipeline_spec pipeline_spec = {\\n\");\n+\tfprintf(f, \"\\t.extobjs = extobjs,\\n\");\n+\tfprintf(f, \"\\t.structs = structs,\\n\");\n+\tfprintf(f, \"\\t.headers = headers,\\n\");\n+\tfprintf(f, \"\\t.metadata = metadata,\\n\");\n+\tfprintf(f, \"\\t.actions = actions,\\n\");\n+\tfprintf(f, \"\\t.tables = tables,\\n\");\n+\tfprintf(f, \"\\t.selectors = selectors,\\n\");\n+\tfprintf(f, \"\\t.learners = learners,\\n\");\n+\tfprintf(f, \"\\t.regarrays = regarrays,\\n\");\n+\tfprintf(f, \"\\t.metarrays = metarrays,\\n\");\n+\tfprintf(f, \"\\t.apply = apply,\\n\");\n+\tfprintf(f, \"\\t.n_extobjs = sizeof(extobjs) / sizeof(extobjs[0]),\\n\");\n+\tfprintf(f, \"\\t.n_structs = sizeof(structs) / sizeof(structs[0]),\\n\");\n+\tfprintf(f, \"\\t.n_headers = sizeof(headers) / sizeof(headers[0]),\\n\");\n+\tfprintf(f, \"\\t.n_metadata = sizeof(metadata) / sizeof(metadata[0]),\\n\");\n+\tfprintf(f, \"\\t.n_actions = sizeof(actions) / sizeof(actions[0]),\\n\");\n+\tfprintf(f, \"\\t.n_tables = sizeof(tables) / sizeof(tables[0]),\\n\");\n+\tfprintf(f, \"\\t.n_selectors = sizeof(selectors) / sizeof(selectors[0]),\\n\");\n+\tfprintf(f, \"\\t.n_learners = sizeof(learners) / sizeof(learners[0]),\\n\");\n+\tfprintf(f, \"\\t.n_regarrays = sizeof(regarrays) / sizeof(regarrays[0]),\\n\");\n+\tfprintf(f, \"\\t.n_metarrays = sizeof(metarrays) / sizeof(metarrays[0]),\\n\");\n+\tfprintf(f, \"\\t.n_apply = sizeof(apply) / sizeof(apply[0]),\\n\");\n+\tfprintf(f, \"};\\n\");\n+}\n+\n struct pipeline_spec *\n pipeline_spec_parse(FILE *spec,\n \t\t    uint32_t *err_line,\ndiff --git a/lib/pipeline/rte_swx_pipeline_spec.h b/lib/pipeline/rte_swx_pipeline_spec.h\nindex 4f3a0b5958..707b99ba09 100644\n--- a/lib/pipeline/rte_swx_pipeline_spec.h\n+++ b/lib/pipeline/rte_swx_pipeline_spec.h\n@@ -206,6 +206,11 @@ struct pipeline_spec {\n \n void\n pipeline_spec_free(struct pipeline_spec *s);\n+\n+void\n+pipeline_spec_codegen(FILE *f,\n+\t\t      struct pipeline_spec *s);\n+\n struct pipeline_spec *\n pipeline_spec_parse(FILE *spec,\n \t\t    uint32_t *err_line,\n",
    "prefixes": [
        "V4",
        "05/17"
    ]
}