Browse Source

Support for list with multi keys

Serj Kalichev 1 year ago
parent
commit
43f2b44c6b
5 changed files with 103 additions and 15 deletions
  1. 54 2
      src/pline.c
  2. 7 0
      src/pline.h
  3. 13 13
      src/syms.c
  4. 6 0
      src/syms.h
  5. 23 0
      ttt.yang

+ 54 - 2
src/pline.c

@@ -325,8 +325,31 @@ static const char *identityref_prefix(struct lysc_type_identityref *type,
 }
 
 
+static size_t num_of_keys(const struct lysc_node *node)
+{
+	const struct lysc_node *iter = NULL;
+	size_t num = 0;
+
+	assert(node);
+	if (!node)
+		return 0;
+	if (!(node->nodetype & LYS_LIST))
+		return 0;
+
+	LY_LIST_FOR(lysc_node_child(node), iter) {
+		if (!(iter->nodetype & LYS_LEAF))
+			continue;
+		if (!(iter->flags & LYS_KEY))
+			continue;
+		num++;
+	}
+
+	return num;
+}
+
+
 static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *argv,
-	pline_t *pline)
+	pline_t *pline, uint32_t flags)
 {
 	faux_argv_node_t *arg = faux_argv_iter(argv);
 	const struct lysc_node *node = NULL;
@@ -417,6 +440,18 @@ 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;
+				}
 
 				LY_LIST_FOR(lysc_node_child(node), iter) {
 					char *tmp = NULL;
@@ -429,6 +464,23 @@ static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *a
 						continue;
 					assert (leaf->type->basetype != LY_TYPE_EMPTY);
 
+					// Parse statement if necessary
+					if (with_stmt) {
+						// Completion
+						if (!str) {
+							pline_add_compl(pline,
+								PCOMPL_NODE, iter, NULL);
+							break_upper_loop = BOOL_TRUE;
+							break;
+						}
+
+						pexpr->args_num++;
+						faux_argv_each(&arg);
+						str = (const char *)faux_argv_current(arg);
+
+						pexpr->pat = PAT_LIST_KEY_INCOMPLETED;
+					}
+
 					// Completion
 					if (!str) {
 						char *tmp = NULL;
@@ -615,7 +667,7 @@ pline_t *pline_parse(sr_session_ctx_t *sess, faux_argv_t *argv, uint32_t flags)
 			continue;
 		if (!module->compiled->data)
 			continue;
-		if (pline_parse_module(module, argv, pline))
+		if (pline_parse_module(module, argv, pline, flags))
 			break; // Found
 	}
 

+ 7 - 0
src/pline.h

@@ -109,6 +109,13 @@ typedef struct pline_s {
 } pline_t;
 
 
+// Parse options
+typedef enum {
+	PPARSE_SINGLE_KEY_W_STMT = 0x01,
+	PPARSE_MULTI_KEYS_W_STMT = 0x02,
+} pparse_flags_e;
+
+
 C_DECL_BEGIN
 
 pline_t *pline_new(sr_session_ctx_t *sess);

+ 13 - 13
src/syms.c

@@ -78,7 +78,7 @@ static int srp_compl_or_help(kcontext_t *context, bool_t help)
 	cur_path = (faux_argv_t *)kplugin_udata(plugin);
 	entry_name = kentry_name(kcontext_candidate_entry(context));
 	args = param2argv(cur_path, kcontext_parent_pargv(context), entry_name);
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(args);
 	pline_print_completions(pline, help);
 	pline_free(pline);
@@ -152,7 +152,7 @@ static int srp_check_type(kcontext_t *context,
 	args = param2argv(cur_path, kcontext_parent_pargv(context), entry_name);
 	if (value)
 		faux_argv_add(args, value);
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(args);
 
 	if (pline->invalid)
@@ -212,7 +212,7 @@ static faux_argv_t *assemble_insert_to(sr_session_ctx_t *sess, const kpargv_t *p
 	assert(sess);
 
 	args = param2argv(cur_path, pargv, "from_path");
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	expr = pline_current_expr(pline);
 	for (i = 0; i < (expr->args_num - expr->list_pos); i++) {
 		faux_argv_node_t *iter = faux_argv_iterr(args);
@@ -256,7 +256,7 @@ int srp_PLINE_INSERT_TO(kcontext_t *context)
 	value = kcontext_candidate_value(context);
 	args = assemble_insert_to(sess, kcontext_parent_pargv(context),
 		cur_path, value);
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(args);
 
 	if (pline->invalid)
@@ -299,7 +299,7 @@ static int srp_compl_or_help_insert_to(kcontext_t *context, bool_t help)
 	cur_path = (faux_argv_t *)kplugin_udata(plugin);
 	args = assemble_insert_to(sess, kcontext_parent_pargv(context),
 		cur_path, NULL);
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(args);
 	pline_print_completions(pline, help);
 	pline_free(pline);
@@ -347,7 +347,7 @@ int srp_set(kcontext_t *context)
 	plugin = kcontext_plugin(context);
 	cur_path = (faux_argv_t *)kplugin_udata(plugin);
 	args = param2argv(cur_path, kcontext_pargv(context), "path");
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(args);
 
 	if (pline->invalid) {
@@ -413,7 +413,7 @@ int srp_del(kcontext_t *context)
 	plugin = kcontext_plugin(context);
 	cur_path = (faux_argv_t *)kplugin_udata(plugin);
 	args = param2argv(cur_path, kcontext_pargv(context), "path");
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(args);
 
 	if (pline->invalid) {
@@ -473,7 +473,7 @@ int srp_edit(kcontext_t *context)
 	plugin = kcontext_plugin(context);
 	cur_path = (faux_argv_t *)kplugin_udata(plugin);
 	args = param2argv(cur_path, kcontext_pargv(context), "path");
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 
 	if (pline->invalid) {
 		fprintf(stderr, "Invalid 'edit' request\n");
@@ -559,7 +559,7 @@ int srp_up(kcontext_t *context)
 
 		iter = faux_argv_iterr(cur_path);
 		faux_argv_del(cur_path, iter);
-		pline = pline_parse(sess, cur_path, 0);
+		pline = pline_parse(sess, cur_path, SRP_DEFAULT_PARSE_OPTS);
 		if (pline->invalid) {
 			pline_free(pline);
 			continue;
@@ -625,7 +625,7 @@ int srp_insert(kcontext_t *context)
 
 	// 'from' argument
 	insert_from = param2argv(cur_path, pargv, "from_path");
-	pline = pline_parse(sess, insert_from, 0);
+	pline = pline_parse(sess, insert_from, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(insert_from);
 
 	if (pline->invalid) {
@@ -662,7 +662,7 @@ int srp_insert(kcontext_t *context)
 	// 'to' argument
 	if ((SR_MOVE_BEFORE == position) || (SR_MOVE_AFTER == position)) {
 		insert_to = assemble_insert_to(sess, pargv, cur_path, NULL);
-		pline_to = pline_parse(sess, insert_to, 0);
+		pline_to = pline_parse(sess, insert_to, SRP_DEFAULT_PARSE_OPTS);
 		faux_argv_free(insert_to);
 
 		if (pline_to->invalid) {
@@ -813,7 +813,7 @@ int srp_show(kcontext_t *context)
 	plugin = kcontext_plugin(context);
 	cur_path = (faux_argv_t *)kplugin_udata(plugin);
 	args = param2argv(cur_path, kcontext_pargv(context), "path");
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(args);
 
 	if (pline->invalid) {
@@ -887,7 +887,7 @@ int srp_deactivate(kcontext_t *context)
 	plugin = kcontext_plugin(context);
 	cur_path = (faux_argv_t *)kplugin_udata(plugin);
 	args = param2argv(cur_path, kcontext_pargv(context), "path");
-	pline = pline_parse(sess, args, 0);
+	pline = pline_parse(sess, args, SRP_DEFAULT_PARSE_OPTS);
 	faux_argv_free(args);
 
 	if (pline->invalid) {

+ 6 - 0
src/syms.h

@@ -8,9 +8,15 @@
 #include <faux/faux.h>
 #include <klish/kcontext_base.h>
 
+#include "pline.h"
+
 // Repository to edit with srp commands
 #define SRP_REPO_EDIT SR_DS_CANDIDATE
 
+// Defaut parse options
+#define SRP_DEFAULT_PARSE_OPTS (PPARSE_MULTI_KEYS_W_STMT)
+
+
 C_DECL_BEGIN
 
 // Types

+ 23 - 0
ttt.yang

@@ -65,4 +65,27 @@ module ttt {
 
   }
 
+
+  list rule {
+    key "from to";
+
+    leaf from {
+      type string;
+    }
+    leaf to {
+      type string;
+    }
+
+    leaf comment {
+      type string;
+    }
+
+    leaf-list multi {
+      ordered-by user;
+      type string;
+    }
+
+  }
+
+
 }