Serj Kalichev преди 1 година
родител
ревизия
382ae591dd
променени са 4 файла, в които са добавени 356 реда и са изтрити 32 реда
  1. 271 7
      pline.c
  2. 50 22
      pline.h
  3. 19 0
      ttt.yang
  4. 16 3
      ytree.c

+ 271 - 7
pline.c

@@ -1,4 +1,4 @@
-/** @file ipath.c
+/** @file pline.c
  */
 
 #include <stdlib.h>
@@ -7,12 +7,276 @@
 #include <string.h>
 #include <assert.h>
 
-#include "faux/faux.h"
-#include "faux/str.h"
-#include "faux/list.h"
+#include <sysrepo.h>
+#include <sysrepo/xpath.h>
+#include <libyang/tree_edit.h>
 
-#include "ipath.h"
+#include <faux/faux.h>
+#include <faux/str.h>
+#include <faux/list.h>
+#include <faux/argv.h>
 
+#include "pline.h"
 
-struct ipath_s {
-};
+#define NODETYPE_CONF (LYS_CONTAINER | LYS_LIST | LYS_LEAF | LYS_LEAFLIST)
+
+
+pexpr_t *pexpr_new(void)
+{
+	pexpr_t *pexpr = NULL;
+
+	pexpr = faux_zmalloc(sizeof(*pexpr));
+	assert(pexpr);
+	if (!pexpr)
+		return NULL;
+
+	return pexpr;
+}
+
+
+void pexpr_free(pexpr_t *pexpr)
+{
+	if (!pexpr)
+		return;
+
+	faux_str_free(pexpr->xpath);
+	faux_str_free(pexpr->value);
+
+	free(pexpr);
+}
+
+
+pcompl_t *pcompl_new(void)
+{
+	pcompl_t *pcompl = NULL;
+
+	pcompl = faux_zmalloc(sizeof(*pcompl));
+	assert(pcompl);
+	if (!pcompl)
+		return NULL;
+
+	return pcompl;
+}
+
+
+void pcompl_free(pcompl_t *pcompl)
+{
+	if (!pcompl)
+		return;
+
+	faux_str_free(pcompl->xpath);
+
+	free(pcompl);
+}
+
+
+pline_t *pline_new(void)
+{
+	pline_t *pline = NULL;
+
+	pline = faux_zmalloc(sizeof(*pline));
+	assert(pline);
+	if (!pline)
+		return NULL;
+
+	// Init
+	pline->exprs = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
+		NULL, NULL, (faux_list_free_fn)pexpr_free);
+	pline->compls = faux_list_new(FAUX_LIST_UNSORTED, FAUX_LIST_NONUNIQUE,
+		NULL, NULL, (faux_list_free_fn)pcompl_free);
+
+	return pline;
+}
+
+
+void pline_free(pline_t *pline)
+{
+	LY_ARRAY_COUNT_TYPE u = 0;
+
+	if (!pline)
+		return;
+
+	faux_list_free(pline->exprs);
+	faux_list_free(pline->compls);
+
+	faux_free(pline);
+}
+
+
+pexpr_t *pline_current_expr(pline_t *pline)
+{
+	assert(pline);
+
+	if (faux_list_len(pline->exprs) == 0)
+		faux_list_add(pline->exprs, pexpr_new());
+
+	return (pexpr_t *)faux_list_data(faux_list_tail(pline->exprs));
+}
+
+
+static int
+sr_ly_module_is_internal(const struct lys_module *ly_mod);
+
+int
+sr_module_is_internal(const struct lys_module *ly_mod);
+
+
+// Don't use standard lys_find_child() because it checks given module to be
+// equal to found node's module. So augmented nodes will not be found.
+static const struct lysc_node *find_child(const struct lysc_node *node,
+	const char *name)
+{
+	const struct lysc_node *iter = NULL;
+
+	if (!node)
+		return NULL;
+
+	LY_LIST_FOR(node, iter) {
+		if (!(iter->nodetype & NODETYPE_CONF))
+			continue;
+		if (!(iter->flags & LYS_CONFIG_W))
+			continue;
+		if (!faux_str_cmp(iter->name, name))
+			return iter;
+	}
+
+	return NULL;
+}
+
+
+
+
+
+
+bool_t parse_module(const struct lys_module *module, faux_argv_node_t **arg,
+	pline_t *pline)
+{
+	const struct lysc_node *node = NULL;
+
+	do {
+		pexpr_t *pexpr = pline_current_expr(pline);
+		const char *str = (const char *)faux_argv_current(*arg);
+
+		if (node) {
+			char *tmp = faux_str_sprintf("/%s:%s",
+				node->module->name, node->name);
+			faux_str_cat(&pexpr->xpath, tmp);
+			faux_str_free(tmp);
+			printf("%s\n", pexpr->xpath);
+		}
+
+printf("for str = %s\n", str);
+
+		if (!str)
+			break;
+
+		// Root of the module
+		if (!node) {
+printf("Module\n");
+			node = find_child(module->compiled->data, str);
+			if (!node)
+				return BOOL_FALSE;
+//			continue; // Don't get next arg
+
+		// Container
+		} else if (node->nodetype & LYS_CONTAINER) {
+printf("Container\n");
+			node = find_child(lysc_node_child(node), str);
+
+		// List
+		} else if (node->nodetype & LYS_LIST) {
+printf("List\n");
+			const struct lysc_node *iter = NULL;
+			printf("str = %s\n", str);
+			LY_LIST_FOR(lysc_node_child(node), iter) {
+				char *tmp = NULL;
+				struct lysc_node_leaf *leaf =
+					(struct lysc_node_leaf *)iter;
+				if (!(iter->nodetype & LYS_LEAF))
+					continue;
+				if (!(iter->flags & LYS_KEY))
+					continue;
+				assert (leaf->type->basetype != LY_TYPE_EMPTY);
+				tmp = faux_str_sprintf("[%s='%s']",
+					leaf->name, str);
+				faux_str_cat(&pexpr->xpath, tmp);
+				faux_str_free(tmp);
+				printf("%s\n", pexpr->xpath);
+				faux_argv_each(arg);
+				str = (const char *)faux_argv_current(*arg);
+printf("list str = %s\n", str);
+				if (!str)
+					break;
+			}
+			if (!str)
+				break;
+			node = find_child(lysc_node_child(node), str);
+printf("list next node = %s\n", node ? node->name : "NULL");
+
+		// Leaf
+		} else if (node->nodetype & LYS_LEAF) {
+printf("Leaf\n");
+			struct lysc_node_leaf *leaf =
+				(struct lysc_node_leaf *)node;
+			if (leaf->type->basetype != LY_TYPE_EMPTY) {
+				pexpr->value = faux_str_dup(str);
+printf("value=%s\n", pexpr->value);
+			}
+			// Expression was completed
+			node = node->parent; // For oneliners
+			faux_list_add(pline->exprs, pexpr_new());
+		}
+
+		faux_argv_each(arg);
+	} while (node);
+
+	return BOOL_TRUE;
+}
+
+
+/*
+bool_t parse_tree(const struct lysc_node *tree, faux_argv_node_t **arg,
+	pline_t *pline)
+{
+	const struct lysc_node *node = NULL;
+	const char *str = (const char *)faux_argv_current(*arg);
+
+	node = find_child(tree, str);
+	if (node) {
+		parse_node(node, arg, pline);
+		return BOOL_TRUE;
+	}
+
+	return BOOL_FALSE;
+}
+*/
+
+
+pline_t *pline_parse(const struct ly_ctx *ctx, faux_argv_t *argv, uint32_t flags)
+{
+	struct lys_module *module = NULL;
+	pline_t *pline = pline_new();
+	uint32_t i = 0;
+	faux_argv_node_t *arg = faux_argv_iter(argv);
+
+	assert(ctx);
+	if (!ctx)
+		return NULL;
+
+	// Iterate all modules
+	i = 0;
+	while ((module = ly_ctx_get_module_iter(ctx, &i))) {
+		if (sr_module_is_internal(module))
+			continue;
+		if (!module->compiled)
+			continue;
+		if (!module->implemented)
+			continue;
+		if (!module->compiled->data)
+			continue;
+		if (parse_module(module, &arg, pline))
+			break; // Found
+	}
+
+	return pline;
+}

+ 50 - 22
pline.h

@@ -1,36 +1,64 @@
-/** @file ipath.h
- * @brief Internal path structures.
+/** @file pline.h
+ * @brief Plain line.
  */
 
-#ifndef _ipath_h
-#define _ipath_h
+#ifndef _pline_h
+#define _pline_h
 
-#include <faux/faux.h>
-#include <faux/list.h>
+#include <sysrepo.h>
+#include <sysrepo/xpath.h>
 
-typedef struct ipath_s ipath_t;
-typedef faux_list_node_t ipath_node_t;
+// Plain EXPRession
+typedef struct {
+	char *xpath;
+	char *value;
+} pexpr_t;
+
+
+// Possible types of completion source
+typedef enum {
+	PCOMPL_NODE = 0,
+	PCOMPL_TYPE = 1,
+} pcompl_type_e;
+
+
+// Plain COMPLetion
+typedef struct {
+	struct lysc_node *node;
+	char *xpath;
+} pcompl_t;
+
+
+// Plain LINE
+typedef struct pline_s {
+	faux_list_t *exprs;
+	faux_list_t *compls;
+} pline_t;
 
 C_DECL_BEGIN
 
-ipath_t *ipath_new(void);
-void ipath_free(ipath_t *fargv);
-void ipath_set_quotes(ipath_t *fargv, const char *quotes);
 
-ssize_t ipath_len(ipath_t *fargv);
-ipath_node_t *ipath_iter(const ipath_t *fargv);
-const char *ipath_each(ipath_node_t **iter);
-const char *ipath_current(ipath_node_t *iter);
-const char *ipath_index(const ipath_t *fargv, size_t index);
+pline_t *pline_new(void);
+void pline_free(pline_t *pline);
+pline_t *pline_parse(const struct ly_ctx *ctx, faux_argv_t *argv, uint32_t flags);
+pexpr_t *pline_current_expr(pline_t *pline);
+
+//void pline_set_quotes(pline_t *fargv, const char *quotes);
+
+//ssize_t pline_len(const pline_t *fargv);
+//pline_node_t *pline_iter(const pline_t *fargv);
+//const char *pline_each(pline_node_t **iter);
+//const char *pline_current(pline_node_t *iter);
+//const char *pline_index(const pline_t *fargv, size_t index);
 
-ssize_t ipath_parse(ipath_t *fargv, const char *str);
-bool_t ipath_add(ipath_t *fargv, const char *arg);
+//ssize_t pline_parse(pline_t *fargv, const char *str);
+//bool_t pline_add(pline_t *fargv, const char *arg);
 
-bool_t ipath_is_continuable(const ipath_t *fargv);
-void ipath_set_continuable(ipath_t *fargv, bool_t continuable);
+//bool_t pline_is_continuable(const pline_t *fargv);
+//void pline_set_continuable(pline_t *fargv, bool_t continuable);
 
-bool_t ipath_is_last(ipath_node_t *iter);
+//bool_t pline_is_last(pline_node_t *iter);
 
 C_DECL_END
 
-#endif				/* _ipath_h */
+#endif				/* _pline_h */

+ 19 - 0
ttt.yang

@@ -0,0 +1,19 @@
+module ttt {
+  namespace "urn:ttt";
+  prefix t;
+
+  container test {
+    list acl {
+      key "name";
+      leaf name {
+        type string;
+      }
+      leaf comment {
+        type string;
+      }
+      leaf-list multi {
+        type string;
+      }
+    }
+  }
+}

+ 16 - 3
ytree.c

@@ -10,9 +10,18 @@
 #include <faux/faux.h>
 #include <faux/argv.h>
 
+#include "pline.h"
+
 #define NODETYPE_CONF (LYS_CONTAINER | LYS_LIST | LYS_LEAF | LYS_LEAFLIST)
 
 
+struct ipath {
+	struct ly_path *path_arr;
+	const char *value;
+};
+
+
+
 static void process_node(const struct lysc_node *node, size_t level);
 static void iterate_nodes(const struct lysc_node *node, size_t level);
 
@@ -101,8 +110,9 @@ static void process_node(const struct lysc_node *node, size_t level)
 	if (!node)
 		return;
 
-	printf("%*c %s [%s]",
+	printf("%*c %s:%s [%s]",
 		(int)(level * 2), ' ',
+		node->module->name,
 		node->name,
 		lys_nodetype2str(node->nodetype));
 
@@ -232,6 +242,7 @@ int main(void)
 	sr_conn_ctx_t *conn = NULL;
 	sr_session_ctx_t *sess = NULL;
 	const struct ly_ctx *ctx = NULL;
+	faux_argv_t *argv = faux_argv_new();
 
 	err = sr_connect(SR_CONN_DEFAULT, &conn);
 	if (err) {
@@ -249,12 +260,14 @@ int main(void)
 		goto out;
 	}
 
+	faux_argv_parse(argv, "interfaces interface eth0 type ethernet");
+	pline_parse(ctx, argv, 0);
+	faux_argv_free(argv);
 
-	ppath2path(ctx, "interfaces interface eth0 type");
+//	ppath2path(ctx, "interfaces interface eth0 type");
 
 //	show(ctx);
 
-//	printf("Ok\n");
 	ret = 0;
 out:
 	sr_release_context(conn);