Browse Source

Fix completion for union and leafref

Serj Kalichev 1 year ago
parent
commit
811f3bbbd2
3 changed files with 66 additions and 45 deletions
  1. 5 8
      src/kly.c
  2. 59 36
      src/pline.c
  3. 2 1
      src/private.h

+ 5 - 8
src/kly.c

@@ -340,28 +340,25 @@ static char *cut_trailing_components(const char *orig_xpath, size_t up_num)
 }
 
 
-char *klysc_leafref_xpath(const struct lysc_node *node, const char *node_path)
+char *klysc_leafref_xpath(const struct lysc_node *node,
+	const struct lysc_type *type, const char *node_path)
 {
 	char *compl_xpath = NULL;
-	const struct lysc_type *type = NULL;
 	const struct lysc_type_leafref *leafref = NULL;
 	const char *orig_xpath = NULL;
 	char *remaped_xpath = NULL;
 	const char *tmp = NULL;
 	size_t up_num = 0;
 
+	if (!type)
+		return NULL;
 	if (!node)
 		return NULL;
 	if (!(node->nodetype & (LYS_LEAF | LYS_LEAFLIST)))
 		return NULL;
-
-	if (node->nodetype & LYS_LEAF)
-		type = ((const struct lysc_node_leaf *)node)->type;
-	else
-		type = ((const struct lysc_node_leaflist *)node)->type;
-
 	if (type->basetype != LY_TYPE_LEAFREF)
 		return NULL;
+
 	leafref = (const struct lysc_type_leafref *)type;
 
 	orig_xpath = lyxp_get_expr(leafref->path);

+ 59 - 36
src/pline.c

@@ -330,6 +330,41 @@ static bool_t pexpr_xpath_add_leaflist_key(pexpr_t *pexpr,
 }
 
 
+static void pline_add_compl_leafref(pline_t *pline, const struct lysc_node *node,
+	const struct lysc_type *type, const char *xpath)
+{
+	if (!type)
+		return;
+	if (!node)
+		return;
+	if (!(node->nodetype & (LYS_LEAF | LYS_LEAFLIST)))
+		return;
+
+	switch (type->basetype) {
+
+	case LY_TYPE_UNION: {
+		struct lysc_type_union *t =
+			(struct lysc_type_union *)type;
+		LY_ARRAY_COUNT_TYPE u = 0;
+		LY_ARRAY_FOR(t->types, u) {
+			pline_add_compl_leafref(pline, node, t->types[u], xpath);
+		}
+		break;
+	}
+
+	case LY_TYPE_LEAFREF: {
+		char *compl_xpath = klysc_leafref_xpath(node, type, xpath);
+		pline_add_compl(pline, PCOMPL_TYPE, NULL, compl_xpath);
+		faux_str_free(compl_xpath);
+		break;
+	}
+
+	default:
+		break;
+	}
+}
+
+
 static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *argv,
 	pline_t *pline, pline_opts_t *opts)
 {
@@ -430,19 +465,12 @@ static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *a
 
 						// Completion
 						if (!str) {
-							char *tmp = NULL;
-							char *compl_xpath = NULL;
-
-							tmp = faux_str_sprintf("%s/%s",
+							char *tmp = faux_str_sprintf("%s/%s",
 								pexpr->xpath, leaf->name);
 							pline_add_compl(pline,
 								PCOMPL_TYPE, iter, tmp);
-							compl_xpath = klysc_leafref_xpath(iter, tmp);
-							if (compl_xpath) {
-								pline_add_compl(pline, PCOMPL_TYPE,
-									NULL, compl_xpath);
-								faux_str_free(compl_xpath);
-							}
+							pline_add_compl_leafref(pline, iter,
+								leaf->type, tmp);
 							faux_str_free(tmp);
 							break_upper_loop = BOOL_TRUE;
 							break;
@@ -514,19 +542,14 @@ static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *a
 
 						// Completion
 						if (!str) {
-							char *tmp = NULL;
-							char *compl_xpath = NULL;
-
-							tmp = faux_str_sprintf("%s/%s",
-								pexpr->xpath, cur_key->node->name);
-							pline_add_compl(pline,
-								PCOMPL_TYPE, cur_key->node, tmp);
-							compl_xpath = klysc_leafref_xpath(iter, tmp);
-							if (compl_xpath) {
-								pline_add_compl(pline, PCOMPL_TYPE,
-									NULL, compl_xpath);
-								faux_str_free(compl_xpath);
-							}
+							char *tmp = faux_str_sprintf("%s/%s",
+								pexpr->xpath,
+								cur_key->node->name);
+							pline_add_compl(pline, PCOMPL_TYPE,
+								cur_key->node, tmp);
+							pline_add_compl_leafref(pline, cur_key->node,
+								((const struct lysc_node_leaf *)cur_key->node)->type,
+								tmp);
 							faux_str_free(tmp);
 							break_upper_loop = BOOL_TRUE;
 							break;
@@ -606,10 +629,9 @@ static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *a
 
 				// Completion
 				if (!str) {
-					char *compl_xpath = klysc_leafref_xpath(node, pexpr->xpath);
-					pline_add_compl(pline,
-						PCOMPL_TYPE, node, compl_xpath);
-					faux_str_free(compl_xpath);
+					pline_add_compl(pline, PCOMPL_TYPE, node, NULL);
+					pline_add_compl_leafref(pline, node,
+						leaf->type, pexpr->xpath);
 					break;
 				}
 
@@ -647,15 +669,9 @@ static bool_t pline_parse_module(const struct lys_module *module, faux_argv_t *a
 
 			// Completion
 			if (!str) {
-				char *compl_xpath = klysc_leafref_xpath(node, pexpr->xpath);
-
-				if (compl_xpath) {
-					pline_add_compl(pline,
-						PCOMPL_TYPE, NULL, compl_xpath);
-					faux_str_free(compl_xpath);
-				}
-				pline_add_compl(pline,
-					PCOMPL_TYPE, node, pexpr->xpath);
+				pline_add_compl(pline, PCOMPL_TYPE, node, pexpr->xpath);
+				pline_add_compl_leafref(pline, node,
+					leaflist->type, pexpr->xpath);
 				break;
 			}
 
@@ -849,6 +865,13 @@ static void pline_print_type_completions(const struct lysc_type *type)
 		break;
 	}
 
+	case LY_TYPE_LEAFREF: {
+		struct lysc_type_leafref *t =
+			(struct lysc_type_leafref *)type;
+		pline_print_type_completions(t->realtype);
+		break;
+	}
+
 	default:
 		break;
 	}

+ 2 - 1
src/private.h

@@ -96,7 +96,8 @@ const char *klysc_node_ext_default(const struct lysc_node *node);
 char *klyd_node_value(const struct lyd_node *node);
 const struct lysc_node *klysc_find_child(const struct lysc_node *node,
 	const char *name);
-char *klysc_leafref_xpath(const struct lysc_node *node, const char *node_path);
+char *klysc_leafref_xpath(const struct lysc_node *node,
+	const struct lysc_type *type, const char *node_path);
 const char *klysc_identityref_prefix(struct lysc_type_identityref *type,
 	const char *name);