libyang icon indicating copy to clipboard operation
libyang copied to clipboard

rpc input/output extensions are not printed

Open olivier-matz-6wind opened this issue 1 year ago • 0 comments

When using a lys_print_*() function on a yang model that contains extensions on rpc input or output nodes, these ones are not displayed.

The problem can be reproduced with the following example:

#include <stddef.h>
#include <stdio.h>
#include <stdint.h>
#include <errno.h>

#include <libyang/libyang.h>

const char *yang = "module my-mod {\n"
                "  yang-version 1.1;\n"
                "  namespace \"http://example.com/my-mod\";\n"
                "  prefix my-mod;\n"
                "\n"
                "  extension my-ext {\n"
                "    argument arg;\n"
                "    description \"my desc\";\n"
                "  }\n"
                "\n"
                "  extension my-ext2 {\n"
                "    description \"my desc\";\n"
                "  }\n"
                "\n"
                "  rpc my-rpc {\n"
                "    my-mod:my-ext arg-rpc;\n"
                "    input {\n"
                "      my-mod:my-ext arg-input;\n"
                "      my-mod:my-ext2;\n"
                "      leaf in-value {\n"
                "        my-mod:my-ext arg-in-value;\n"
                "        type uint32;\n"
                "      }\n"
                "    }\n"
                "    output {\n"
                "      my-mod:my-ext arg-output;\n"
                "      leaf out-value {\n"
                "        my-mod:my-ext arg-out-value;\n"
                "        type uint32;\n"
                "      }\n"
                "    }\n"
                "  }\n"
                "}\n";

int main(int argc, char **argv)
{
    struct lys_module *mod = NULL;
    struct ly_ctx *ctx = NULL;
    int exit_code = 1;
    int ret;

    (void)argc;
    (void)argv;

    ret = ly_ctx_new(NULL, 0, &ctx);
    if (ret != LY_SUCCESS) {
        fprintf(stderr, "ly_ctx_new() failed: %s\n", ly_strerrcode(ret));
        goto fail;
    }

    ret = lys_parse_mem(ctx, yang, LYS_IN_YANG, &mod);
    if (ret != LY_SUCCESS) {
        fprintf(stderr, "lys_parse_mem() failed: %s\n", ly_strerrcode(ret));
        goto fail;
    }

    printf("%s", yang);
    printf("----------------------\n");
    lys_print_file(stdout, mod, LYS_OUT_YANG, 0);

    exit_code = 0;

fail:
    ly_ctx_destroy(ctx);

    return exit_code;
}

The output of the program is:

module my-mod {
  yang-version 1.1;
  namespace "http://example.com/my-mod";
  prefix my-mod;

  extension my-ext {
    argument arg;
    description "my desc";
  }

  extension my-ext2 {
    description "my desc";
  }

  rpc my-rpc {
    my-mod:my-ext arg-rpc;
    input {
      my-mod:my-ext arg-input;
      my-mod:my-ext2;
      leaf in-value {
        my-mod:my-ext arg-in-value;
        type uint32;
      }
    }
    output {
      my-mod:my-ext arg-output;
      leaf out-value {
        my-mod:my-ext arg-out-value;
        type uint32;
      }
    }
  }
}
----------------------
module my-mod {
  yang-version 1.1;
  namespace "http://example.com/my-mod";
  prefix my-mod;

  extension my-ext {
    argument arg;
    description
      "my desc";
  }
  extension my-ext2 {
    description
      "my desc";
  }

  rpc my-rpc {
    my-mod:my-ext "arg-rpc";

    input {
      leaf in-value {
        my-mod:my-ext "arg-in-value";
        type uint32;
      }
    }
    output {
      leaf out-value {
        my-mod:my-ext "arg-out-value";
        type uint32;
      }
    }
  }
}

The extensions from rpc input and output disappeared on the printed yang.

Note that sysrepo uses a yang print function when installing a module with sr_install_module(), so the generated yang files in /etc/sysrepo/yang won't have any extensions on rpc input or output nodes.

The patch looks quite easy:

--- a/src/printer_yang.c
+++ b/src/printer_yang.c
@@ -1162,7 +1162,7 @@ yprp_inout(struct lys_ypr_ctx *pctx, const struct lysp_node_action_inout *inout,
     ly_print_(pctx->out, "%*s%s {\n", INDENT, inout->name);
     LEVEL++;
 
-    yprp_extension_instances(pctx, LY_STMT_MUST, 0, inout->exts, NULL);
+    yprp_extension_instances(pctx, lyplg_ext_nodetype2stmt(inout->nodetype), 0, inout->exts, NULL);
     LY_ARRAY_FOR(inout->musts, u) {
         yprp_restr(pctx, &inout->musts[u], LY_STMT_MUST, NULL);
     }

I'm submitting a PR for this.

olivier-matz-6wind avatar Aug 05 '24 11:08 olivier-matz-6wind