yin parser work in progress
diff --git a/src/parser_yin.c b/src/parser_yin.c
index f479511..b375c71 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -307,6 +307,50 @@
return LY_SUCCESS;
}
+static LY_ERR
+yin_parse_arguments(struct lyxml_context *xml_ctx, const char **data, enum YIN_ARGUMENT arg_type, const char **arg_val, char *elem_name)
+{
+ LY_ERR ret = LY_SUCCESS;
+ const char *prefix, *name;
+ size_t prefix_len, name_len;
+
+ char *buf = NULL, *out = NULL;
+ size_t buf_len = 0, out_len = 0;
+ int dynamic;
+ enum YIN_ARGUMENT arg = YIN_ARG_NONE;
+
+ while (xml_ctx->status == LYXML_ATTRIBUTE) {
+ ret = lyxml_get_attribute(xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
+ LY_CHECK_ERR_RET(ret != LY_SUCCESS, LOGMEM(xml_ctx->ctx), LY_EMEM);
+
+ arg = match_argument_name(name, name_len);
+
+ if (arg == YIN_ARG_XMLNS) {
+ parse_xmlns(xml_ctx, data, prefix, prefix_len, elem_name);
+ break;
+ } else if (arg == arg_type) {
+ LY_CHECK_RET(ret);
+ ret = lyxml_get_string(xml_ctx, data, &buf, &buf_len, &out, &out_len, &dynamic);
+ LY_CHECK_RET(ret);
+ *arg_val = lydict_insert(xml_ctx->ctx, out, out_len);
+ LY_CHECK_ERR_RET(!(*arg_val), LOGMEM(xml_ctx->ctx), LY_EMEM);
+ break;
+ } else {
+ /* unrecognized attribute, still can be namespace definition eg. xmlns:foo=.... */
+ if (match_argument_name(prefix, prefix_len) == YIN_ARG_XMLNS) {
+ /* in this case prefix of namespace is actually name of attribute */
+ parse_xmlns(xml_ctx, data, name, name_len, elem_name);
+ } else {
+ /* unrecognized or unexpected attribute */
+ LOGERR(xml_ctx->ctx, LY_EDENIED, "Invalid argument in namespace element");
+ return LY_EVALID;
+ }
+ }
+ }
+
+ return LY_SUCCESS;
+}
+
/**
* @brief Parse prefix statement.
*
@@ -320,36 +364,24 @@
parse_prefix(struct lyxml_context *xml_ctx, const char **data, struct lysp_module **mod)
{
LY_ERR ret = LY_SUCCESS;
- const char *prefix, *name;
- size_t prefix_len, name_len;
- char *buf = NULL, *out = NULL;
- size_t buf_len = 0, out_len = 0;
- int dynamic;
-
- /* check if prefix has argument value */
- ret = lyxml_get_attribute(xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
- LY_CHECK_RET(ret);
- if (match_argument_name(name, name_len) != YIN_ARG_VALUE) {
- LOGVAL(xml_ctx->ctx, LY_VLOG_LINE, &xml_ctx->line, LYVE_SYNTAX, "Invalid argument name \"%s\", expected \"value\".", name);
- return LY_EVALID;
- }
-
- ret = lyxml_get_string(xml_ctx, data, &buf, &buf_len, &out, &out_len, &dynamic);
- LY_CHECK_RET(ret);
- (*mod_p)->mod->prefix = lydict_insert(xml_ctx->ctx, out, out_len);
- LY_CHECK_ERR_RET(!(*mod_p)->mod->prefix, LOGMEM(xml_ctx->ctx), LY_EMEM);
-
- /* prefix element can have only one argument */
- if (xml_ctx->status != LYXML_ELEMENT) {
- LOGVAL(xml_ctx->ctx, LY_VLOG_LINE, &xml_ctx->line, LYVE_SYNTAX, "Unexpected argument \"%s\".", name);
- return LY_EVALID;
- }
- return LY_SUCCESS;
+ /* parse attributes */
+ ret = yin_parse_arguments(xml_ctx, data, YIN_ARG_VALUE, &(*mod)->mod->prefix, "prefix");
+ LY_CHECK_RET(ret != LY_SUCCESS, ret);
+ /* remove local xmlns definitions */
+ ret = lyxml_ns_rm(xml_ctx, "prefix");
+ return ret;
}
+// static LY_ERR
+// yin_parse_revision_date(struct lyxml_context *xml_ctx, const char **data, struct lysp_module **mod)
+// {
+
+// return LY_SUCCESS;
+// }
+
static LY_ERR
-yin_parse_import(struct lyxml_context *xml_ctx, const char *module_prefix, const char **data, struct lysp_import **imports)
+yin_parse_import(struct lyxml_context *xml_ctx, const char *module_prefix, const char **data, struct lysp_module **mod)
{
LY_ERR ret = LY_SUCCESS;
enum yang_keyword kw;
@@ -360,9 +392,51 @@
char *buf = NULL, *out = NULL;
size_t buf_len = 0, out_len = 0;
int dynamic;
+ enum YIN_ARGUMENT arg = YIN_ARG_NONE;
+ /* TODO fix attribute parsing and yin_parse_revision_date function */
+ /* valid attributes module, xmlns */
+ /* parse import attributes */
+ while (xml_ctx->status == LYXML_ATTRIBUTE) {
+ ret = lyxml_get_attribute(xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
+ LY_CHECK_ERR_RET(ret != LY_SUCCESS, LOGMEM(xml_ctx->ctx), LY_EMEM);
+
+ arg = match_argument_name(name, name_len);
+
+ switch (arg) {
+ case YIN_ARG_XMLNS:
+ parse_xmlns(xml_ctx, data, prefix, prefix_len, "prefix");
+ break;
+ case YIN_ARG_MODULE:
+ LY_CHECK_RET(ret);
+ if (match_argument_name(name, name_len) != YIN_ARG_VALUE) {
+ LOGVAL(xml_ctx->ctx, LY_VLOG_LINE, &xml_ctx->line, LYVE_SYNTAX, "Invalid argument name \"%s\", expected \"value\".", name);
+ return LY_EVALID;
+ }
+ ret = lyxml_get_string(xml_ctx, data, &buf, &buf_len, &out, &out_len, &dynamic);
+ LY_CHECK_RET(ret);
+ (*mod)->mod->prefix = lydict_insert(xml_ctx->ctx, out, out_len);
+ LY_CHECK_ERR_RET(!(*mod)->mod->ns, LOGMEM(xml_ctx->ctx), LY_EMEM);
+ break;
+ default:
+ /* unrecognized attribute, still can be namespace definition eg. xmlns:foo=.... */
+ if (match_argument_name(prefix, prefix_len) == YIN_ARG_XMLNS) {
+ /* in this case prefix of namespace is actually name of attribute */
+ parse_xmlns(xml_ctx, data, name, name_len, "prefix");
+ } else {
+ /* unrecognized or unexpected attribute */
+ LOGERR(xml_ctx->ctx, LY_EDENIED, "Invalid argument in prefix element");
+ return LY_EVALID;
+ }
+ break;
+ }
+ }
+
+
+
+ /* valid subelements description, prefix, reference, revision-data */
/* allocate sized array for imports */
- LY_ARRAY_NEW_RET(xml_ctx->ctx, *imports, imp, LY_EVALID);
+ LY_ARRAY_NEW_RET(xml_ctx->ctx, (*mod)->imports, imp, LY_EVALID);
/* get value */
ret = lyxml_get_attribute(xml_ctx, data, &prefix, &prefix_len, &name, &name_len);
@@ -376,18 +450,20 @@
imp->name = lydict_insert(xml_ctx->ctx, out, out_len);
LY_CHECK_ERR_RET(!imp->name, LOGMEM(xml_ctx->ctx), LY_EMEM);
-
while ((ret = lyxml_get_element(xml_ctx, data, &prefix, &prefix_len, &name, &name_len) == LY_SUCCESS && name != NULL)) {
kw = match_keyword(name, name_len, prefix_len);
switch (kw) {
case YANG_PREFIX:
- /* TODO parse prefix */
+ parse_prefix(xml_ctx, data, mod);
+ break;
case YANG_DESCRIPTION:
- /* TODO parse description */
+ parse_text_element(xml_ctx, "description", data, &((*mod)->mod->dsc));
+ break;
case YANG_REFERENCE:
- /* TODO parse reference */
+ parse_text_element(xml_ctx, "reference", data, &((*mod)->imports->ref));
+ break;
case YANG_REVISION_DATE:
- /* TODO parse revision date */
+ /* this is attribute of import element */
case YANG_CUSTOM:
/* TODO parse extension */
default:
@@ -543,7 +619,7 @@
/* linkage */
case YANG_IMPORT:
- yin_parse_import(xml_ctx, (*mod)->mod->prefix, data, &(*mod)->imports);
+ yin_parse_import(xml_ctx, (*mod)->mod->prefix, data, mod);
break;
/* meta */