Browse Source

Add show command. Unfinished

Serj Kalichev 1 year ago
parent
commit
df869c7918
6 changed files with 280 additions and 19 deletions
  1. 3 1
      src/Makefile.am
  2. 23 17
      src/pline.c
  3. 7 0
      src/pline.h
  4. 169 0
      src/show.c
  5. 11 0
      src/show.h
  6. 67 1
      src/syms.c

+ 3 - 1
src/Makefile.am

@@ -15,4 +15,6 @@ kplugin_sysrepo_la_SOURCES += \
 	src/sr_copypaste.h \
 	src/sr_copypaste.c \
 	src/pline.h \
-	src/pline.c
+	src/pline.c \
+	src/show.h \
+	src/show.c

+ 23 - 17
src/pline.c

@@ -20,8 +20,6 @@
 #include "sr_copypaste.h"
 #include "pline.h"
 
-#define NODETYPE_CONF (LYS_CONTAINER | LYS_LIST | LYS_LEAF | LYS_LEAFLIST)
-
 
 static pexpr_t *pexpr_new(void)
 {
@@ -179,7 +177,7 @@ static void pline_add_compl_subtree(pline_t *pline, const struct lys_module *mod
 		subtree = module->compiled->data;
 
 	LY_LIST_FOR(subtree, iter) {
-		if (!(iter->nodetype & NODETYPE_CONF))
+		if (!(iter->nodetype & SRP_NODETYPE_CONF))
 			continue;
 		if (!(iter->flags & LYS_CONFIG_W))
 			continue;
@@ -273,7 +271,7 @@ static const struct lysc_node *find_child(const struct lysc_node *node,
 		return NULL;
 
 	LY_LIST_FOR(node, iter) {
-		if (!(iter->nodetype & NODETYPE_CONF))
+		if (!(iter->nodetype & SRP_NODETYPE_CONF))
 			continue;
 		if (!(iter->flags & LYS_CONFIG_W))
 			continue;
@@ -325,7 +323,7 @@ static const char *identityref_prefix(struct lysc_type_identityref *type,
 }
 
 
-static size_t num_of_keys(const struct lysc_node *node)
+size_t list_num_of_keys(const struct lysc_node *node)
 {
 	const struct lysc_node *iter = NULL;
 	size_t num = 0;
@@ -348,6 +346,25 @@ static size_t num_of_keys(const struct lysc_node *node)
 }
 
 
+bool_t list_key_with_stmt(const struct lysc_node *node, uint32_t flags)
+{
+	bool_t with_stmt = BOOL_FALSE;
+	size_t keys_num = 0;
+
+	// Parse keys's statement or not
+	keys_num = list_num_of_keys(node);
+	if (keys_num > 1) {
+		if (flags & PPARSE_MULTI_KEYS_W_STMT)
+			with_stmt = BOOL_TRUE;
+	} else {
+		if (flags & PPARSE_SINGLE_KEY_W_STMT)
+			with_stmt = BOOL_TRUE;
+	}
+
+	return with_stmt;
+}
+
+
 static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *argv,
 	pline_t *pline, uint32_t flags)
 {
@@ -440,18 +457,7 @@ static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *a
 			// Next element
 			if (!is_rollback) {
 				bool_t break_upper_loop = BOOL_FALSE;
-				bool_t with_stmt = BOOL_FALSE;
-				size_t keys_num = 0;
-
-				// Parse keys's statement or not
-				keys_num = num_of_keys(node);
-				if (keys_num > 1) {
-					if (flags & PPARSE_MULTI_KEYS_W_STMT)
-						with_stmt = BOOL_TRUE;
-				} else {
-					if (flags & PPARSE_SINGLE_KEY_W_STMT)
-						with_stmt = BOOL_TRUE;
-				}
+				bool_t with_stmt = list_key_with_stmt(node, flags);
 
 				LY_LIST_FOR(lysc_node_child(node), iter) {
 					char *tmp = NULL;

+ 7 - 0
src/pline.h

@@ -11,6 +11,7 @@
 #include <sysrepo.h>
 #include <sysrepo/xpath.h>
 
+
 // Type of positional pline argument
 // P(line) A(rg) T(ype)
 typedef enum {
@@ -116,6 +117,9 @@ typedef enum {
 } pparse_flags_e;
 
 
+#define SRP_NODETYPE_CONF (LYS_CONTAINER | LYS_LIST | LYS_LEAF | LYS_LEAFLIST)
+
+
 C_DECL_BEGIN
 
 pline_t *pline_new(sr_session_ctx_t *sess);
@@ -127,6 +131,9 @@ void pline_free(pline_t *pline);
 void pline_debug(pline_t *pline);
 void pline_print_completions(const pline_t *pline, bool_t help);
 
+size_t num_of_keys(const struct lysc_node *node);
+bool_t list_key_with_stmt(const struct lysc_node *node, uint32_t flags);
+
 C_DECL_END
 
 #endif				/* _pline_h */

+ 169 - 0
src/show.c

@@ -0,0 +1,169 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+#include <faux/faux.h>
+#include <faux/str.h>
+#include <faux/list.h>
+#include <faux/argv.h>
+
+#include <sysrepo.h>
+#include <sysrepo/xpath.h>
+#include <sysrepo/values.h>
+#include <libyang/tree_edit.h>
+
+#include "sr_copypaste.h"
+#include "pline.h"
+#include "show.h"
+
+#define LEVEL_SPACES_NUM 2
+
+
+static void show_container(const struct lyd_node *node, size_t level, uint32_t flags);
+static void show_list(const struct lyd_node *node, size_t level, uint32_t flags);
+static void show_leaf(const struct lyd_node *node, size_t level, uint32_t flags);
+static void show_leaflist(const struct lyd_node *node, size_t level, uint32_t flags);
+static void show_node(const struct lyd_node *node, size_t level, uint32_t flags);
+static void show_subtree(const struct lyd_node *nodes_list, size_t level, uint32_t flags);
+
+
+static void show_container(const struct lyd_node *node, size_t level, uint32_t flags)
+{
+	if (!node)
+		return;
+
+	printf("%*s%s\n", (int)(level * LEVEL_SPACES_NUM), "", node->schema->name);
+
+	show_subtree(lyd_child(node), level + 1, flags);
+}
+
+
+static void show_list(const struct lyd_node *node, size_t level, uint32_t flags)
+{
+	size_t keys_num = 0;
+	bool_t with_stmt = BOOL_FALSE;
+	const struct lyd_node *iter = NULL;
+
+	if (!node)
+		return;
+
+	printf("%*s%s", (int)(level * LEVEL_SPACES_NUM), "", node->schema->name);
+
+	with_stmt = list_key_with_stmt(node->schema, flags);
+
+	LY_LIST_FOR(lyd_child(node), iter) {
+		if (!(iter->schema->nodetype & LYS_LEAF))
+			continue;
+		if (!(iter->schema->flags & LYS_KEY))
+			continue;
+		if (with_stmt)
+			printf(" %s", iter->schema->name);
+		printf(" %s", lyd_get_value(iter));
+	}
+	printf("\n");
+
+	show_subtree(lyd_child(node), level + 1, flags);
+}
+
+
+static void show_leaf(const struct lyd_node *node, size_t level, uint32_t flags)
+{
+	struct lysc_node_leaf *leaf = (struct lysc_node_leaf *)node;
+
+	if (!node)
+		return;
+	if (node->schema->flags & LYS_KEY)
+		return;
+
+	printf("%*s%s", (int)(level * LEVEL_SPACES_NUM), "", node->schema->name);
+
+	leaf = (struct lysc_node_leaf *)node->schema;
+	if (leaf->type->basetype != LY_TYPE_EMPTY)
+		printf(" %s", lyd_get_value(node));
+
+	printf("\n");
+}
+
+
+static void show_leaflist(const struct lyd_node *node, size_t level, uint32_t flags)
+{
+
+}
+
+
+static void show_node(const struct lyd_node *node, size_t level, uint32_t flags)
+{
+	const struct lysc_node *schema = NULL;
+
+	if (!node)
+		return;
+
+	if (node->flags & LYD_DEFAULT)
+		return;
+	schema = node->schema;
+	if (!schema)
+		return;
+	if (!(schema->nodetype & SRP_NODETYPE_CONF))
+		return;
+	if (!(schema->flags & LYS_CONFIG_W))
+		return;
+
+	// Container
+	if (schema->nodetype & LYS_CONTAINER) {
+		show_container((const struct lyd_node *)node, level, flags);
+
+	// List
+	} else if (schema->nodetype & LYS_LIST) {
+		show_list((const struct lyd_node *)node, level, flags);
+
+	// Leaf
+	} else if (schema->nodetype & LYS_LEAF) {
+		show_leaf((const struct lyd_node *)node, level, flags);
+
+	// Leaf-list
+	} else if (schema->nodetype & LYS_LEAFLIST) {
+		show_leaflist((const struct lyd_node *)node, level, flags);
+
+	} else {
+		return;
+	}
+}
+
+
+static void show_subtree(const struct lyd_node *nodes_list, size_t level, uint32_t flags)
+{
+	const struct lyd_node *iter = NULL;
+
+	if(!nodes_list)
+		return;
+
+	LY_LIST_FOR(nodes_list, iter) {
+		show_node(iter, level, flags);
+	}
+}
+
+
+bool_t show_xpath(sr_session_ctx_t *sess, const char *xpath, uint32_t flags)
+{
+	sr_data_t *data = NULL;
+	struct lyd_node *nodes_list = NULL;
+
+	assert(sess);
+
+	if (xpath) {
+		if (sr_get_subtree(sess, xpath, 0, &data) != SR_ERR_OK)
+			return BOOL_FALSE;
+		nodes_list = lyd_child(data->tree);
+	} else {
+		if (sr_get_data(sess, "/*", 0, 0, 0, &data) != SR_ERR_OK)
+			return BOOL_FALSE;
+		nodes_list = data->tree;
+	}
+
+	show_subtree(nodes_list, 0, flags);
+	sr_release_data(data);
+
+	return BOOL_TRUE;
+}

+ 11 - 0
src/show.h

@@ -0,0 +1,11 @@
+#ifndef _show_h
+#define _show_h
+
+#include <sysrepo.h>
+#include <sysrepo/xpath.h>
+
+
+bool_t show_xpath(sr_session_ctx_t *sess, const char *xpath, uint32_t flags);
+
+
+#endif // _show_h

+ 67 - 1
src/syms.c

@@ -22,6 +22,7 @@
 #include "sr_copypaste.h"
 #include "pline.h"
 #include "syms.h"
+#include "show.h"
 
 
 static faux_argv_t *param2argv(const faux_argv_t *cur_path,
@@ -787,7 +788,7 @@ err:
 }
 
 
-int srp_show(kcontext_t *context)
+int srp_show_xml(kcontext_t *context)
 {
 	int ret = -1;
 	faux_argv_t *args = NULL;
@@ -862,6 +863,71 @@ err:
 }
 
 
+int srp_show(kcontext_t *context)
+{
+	int ret = -1;
+	faux_argv_t *args = NULL;
+	pline_t *pline = NULL;
+	sr_conn_ctx_t *conn = NULL;
+	sr_session_ctx_t *sess = NULL;
+	pexpr_t *expr = NULL;
+	faux_argv_t *cur_path = NULL;
+	kplugin_t *plugin = NULL;
+	char *xpath = NULL;
+
+	assert(context);
+
+	if (sr_connect(SR_CONN_DEFAULT, &conn))
+		return -1;
+	if (sr_session_start(conn, SRP_REPO_EDIT, &sess)) {
+		sr_disconnect(conn);
+		return -1;
+	}
+
+	plugin = kcontext_plugin(context);
+	cur_path = (faux_argv_t *)kplugin_udata(plugin);
+
+	if (kpargv_find(kcontext_pargv(context), "path") || cur_path) {
+		args = param2argv(cur_path, kcontext_pargv(context), "path");
+		pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
+		faux_argv_free(args);
+
+		if (pline->invalid) {
+			fprintf(stderr, "Invalid 'show' request\n");
+			goto err;
+		}
+
+		if (faux_list_len(pline->exprs) > 1) {
+			fprintf(stderr, "Can't process more than one object\n");
+			goto err;
+		}
+
+		if (!(expr = (pexpr_t *)faux_list_data(faux_list_head(pline->exprs)))) {
+			fprintf(stderr, "Can't get expression\n");
+			goto err;
+		}
+		if (!(expr->pat & PT_EDIT)) {
+			fprintf(stderr, "Illegal expression for 'show' operation\n");
+			goto err;
+		}
+		if (!expr->xpath) {
+			fprintf(stderr, "Empty expression for 'show' operation\n");
+			goto err;
+		}
+		xpath = expr->xpath;
+	}
+
+	show_xpath(sess, xpath, SRP_DEFAULT_PARSE_OPTS);
+
+	ret = 0;
+err:
+	pline_free(pline);
+	sr_disconnect(conn);
+
+	return ret;
+}
+
+
 int srp_deactivate(kcontext_t *context)
 {
 	int ret = -1;