Commit b0f8e1f1 authored by Khushal Chitturi's avatar Khushal Chitturi Committed by Chuck Lever
Browse files

xdrgen: handle _XdrString in union encoder/decoder



Running xdrgen on xdrgen/tests/test.x fails when
generating encoder or decoder functions for union
members of type _XdrString. It was because _XdrString
does not have a spec attribute like _XdrBasic,
leading to AttributeError.

This patch updates emit_union_case_spec_definition
and emit_union_case_spec_decoder/encoder to handle
_XdrString by assigning type_name = "char *" and
avoiding referencing to spec.

Testing: Fixed xdrgen tool was run on originally failing
test file (tools/net/sunrpc/xdrgen/tests/test.x) and now
completes without AttributeError. Modified xdrgen tool was
also run against nfs4_1.x (Documentation/sunrpc/xdr/nfs4_1.x).
The output header file matches with nfs4_1.h
(include/linux/sunrpc/xdrgen/nfs4_1.h).
This validates the patch for all XDR input files currently
within the kernel.

Changes since v2:
- Moved the shebang to the first line
- Removed SPDX header to match style of current xdrgen files

Changes since v1:
- Corrected email address in Signed-off-by.
- Wrapped patch description lines to 72 characters.

Signed-off-by: default avatarKhushal Chitturi <kc9282016@gmail.com>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 42ba5bd2
Loading
Loading
Loading
Loading
+25 −9
Original line number Diff line number Diff line
@@ -8,7 +8,7 @@ from jinja2 import Environment
from generators import SourceGenerator
from generators import create_jinja2_environment, get_jinja2_template

from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid, get_header_name
from xdr_ast import _XdrBasic, _XdrUnion, _XdrVoid, _XdrString, get_header_name
from xdr_ast import _XdrDeclaration, _XdrCaseSpec, public_apis, big_endian


@@ -40,13 +40,20 @@ def emit_union_case_spec_definition(
    """Emit a definition for an XDR union's case arm"""
    if isinstance(node.arm, _XdrVoid):
        return
    assert isinstance(node.arm, _XdrBasic)
    if isinstance(node.arm, _XdrString):
        type_name = "char *"
        classifier = ""
    else:
        type_name = node.arm.spec.type_name
        classifier = node.arm.spec.c_classifier

    assert isinstance(node.arm, (_XdrBasic, _XdrString))
    template = get_jinja2_template(environment, "definition", "case_spec")
    print(
        template.render(
            name=node.arm.name,
            type=node.arm.spec.type_name,
            classifier=node.arm.spec.c_classifier,
            type=type_name,
            classifier=classifier,
        )
    )

@@ -84,6 +91,12 @@ def emit_union_case_spec_decoder(

    if isinstance(node.arm, _XdrVoid):
        return
    if isinstance(node.arm, _XdrString):
        type_name = "char *"
        classifier = ""
    else:
        type_name = node.arm.spec.type_name
        classifier = node.arm.spec.c_classifier

    if big_endian_discriminant:
        template = get_jinja2_template(environment, "decoder", "case_spec_be")
@@ -92,13 +105,13 @@ def emit_union_case_spec_decoder(
    for case in node.values:
        print(template.render(case=case))

    assert isinstance(node.arm, _XdrBasic)
    assert isinstance(node.arm, (_XdrBasic, _XdrString))
    template = get_jinja2_template(environment, "decoder", node.arm.template)
    print(
        template.render(
            name=node.arm.name,
            type=node.arm.spec.type_name,
            classifier=node.arm.spec.c_classifier,
            type=type_name,
            classifier=classifier,
        )
    )

@@ -169,7 +182,10 @@ def emit_union_case_spec_encoder(

    if isinstance(node.arm, _XdrVoid):
        return

    if isinstance(node.arm, _XdrString):
        type_name = "char *"
    else:
        type_name = node.arm.spec.type_name
    if big_endian_discriminant:
        template = get_jinja2_template(environment, "encoder", "case_spec_be")
    else:
@@ -181,7 +197,7 @@ def emit_union_case_spec_encoder(
    print(
        template.render(
            name=node.arm.name,
            type=node.arm.spec.type_name,
            type=type_name,
        )
    )

+6 −0
Original line number Diff line number Diff line
{# SPDX-License-Identifier: GPL-2.0 #}
{% if annotate %}
		/* member {{ name }} (variable-length string) */
{% endif %}
		if (!xdrgen_encode_string(xdr, ptr->u.{{ name }}, {{ maxsize }}))
			return false;