common CHANGE new ly_strncmp()

compare NULL-terminated reference string with a number of bytes from
other string.
diff --git a/src/common.c b/src/common.c
index 5139826..0abfcd6 100644
--- a/src/common.c
+++ b/src/common.c
@@ -171,6 +171,17 @@
     return (char *)s;
 }
 
+int
+ly_strncmp(const char *refstr, const char *str, size_t str_len)
+{
+    int rc = strncmp(refstr, str, str_len);
+    if (!rc && refstr[str_len] == '\0') {
+        return 0;
+    } else {
+        return rc ? rc : 1;
+    }
+}
+
 LY_ERR
 ly_getutf8(const char **input, unsigned int *utf8_char, size_t *bytes_read)
 {
diff --git a/src/common.h b/src/common.h
index 5c030c0..2cca2b2 100644
--- a/src/common.h
+++ b/src/common.h
@@ -319,6 +319,17 @@
 char *ly_strnchr(const char *s, int c, unsigned int len);
 
 /**
+ * @brief Compare NULL-terminated @p refstr with @str_len bytes from @p str.
+ *
+ * @param[in] refstr NULL-terminated string which must match @str_len bytes from @str followed by NULL-byte.
+ * @param[in] str String to compare
+ * @param[in] str_len Number of bytes to take into comparison from @p str.
+ * @return An integer less than, equal to, or greater than zero if @p refstr matches,
+ * respectively, to be less than, to match, or be greater than @p str.
+ */
+int ly_strncmp(const char *refstr, const char *str, size_t str_len);
+
+/**
  * @brief Get UTF8 code point of the next character in the input string.
  *
  * @param[in,out] input Input string to process, updated according to the processed/read data.
diff --git a/src/parser_xml.c b/src/parser_xml.c
index e0a0623..2b4e625 100644
--- a/src/parser_xml.c
+++ b/src/parser_xml.c
@@ -178,7 +178,7 @@
 
         LY_ARRAY_FOR(mod->compiled->exts, v) {
             if (mod->compiled->exts[v].def->plugin == lyext_plugins_internal[LYEXT_PLUGIN_INTERNAL_ANNOTATION].plugin &&
-                    !strncmp(mod->compiled->exts[v].argument, attr_data->name, attr_data->name_len) && !mod->compiled->exts[v].argument[attr_data->name_len]) {
+                    !ly_strncmp(mod->compiled->exts[v].argument, attr_data->name, attr_data->name_len)) {
                 /* we have the annotation definition */
                 ant = &mod->compiled->exts[v];
                 break;
diff --git a/src/parser_yang.c b/src/parser_yang.c
index e6830d3..314cbd7 100644
--- a/src/parser_yang.c
+++ b/src/parser_yang.c
@@ -2171,7 +2171,7 @@
         return LY_EVALID;
     }
 
-    if (strncmp(word, "unbounded", word_len)) {
+    if (ly_strncmp("unbounded", word, word_len)) {
         errno = 0;
         num = strtoul(word, &ptr, 10);
         /* we have not parsed the whole argument */
diff --git a/src/plugins_types.c b/src/plugins_types.c
index 00d7bc5..feb02f8 100644
--- a/src/plugins_types.c
+++ b/src/plugins_types.c
@@ -172,7 +172,7 @@
                 mod = NULL;
 
                 LY_ARRAY_FOR(prefixes, u) {
-                    if (!strncmp(prefixes[u].prefix, start, len) && prefixes[u].prefix[len] == '\0') {
+                    if (!ly_strncmp(prefixes[u].prefix, start, len)) {
                         mod = prefixes[u].mod;
                         break;
                     }
@@ -909,7 +909,7 @@
         item = &value[index];
         for (item_len = 0; index + item_len < value_len && !isspace(item[item_len]); item_len++);
         LY_ARRAY_FOR(type_bits->bits, u) {
-            if (!strncmp(type_bits->bits[u].name, item, item_len) && type_bits->bits[u].name[item_len] == '\0') {
+            if (!ly_strncmp(type_bits->bits[u].name, item, item_len)) {
                 /* we have the match */
                 int inserted;
 
@@ -1066,7 +1066,7 @@
 
     /* find the matching enumeration value item */
     LY_ARRAY_FOR(type_enum->enums, u) {
-        if (!strncmp(type_enum->enums[u].name, value, value_len) && type_enum->enums[u].name[value_len] == '\0') {
+        if (!ly_strncmp(type_enum->enums[u].name, value, value_len)) {
             /* we have the match */
 
             /* check that the enumeration value is not disabled */
@@ -1284,7 +1284,7 @@
     }
     LY_ARRAY_FOR(mod->compiled->identities, u) {
         ident = &mod->compiled->identities[u]; /* shortcut */
-        if (!strncmp(ident->name, id_name, id_len) && ident->name[id_len] == '\0') {
+        if (!ly_strncmp(ident->name, id_name, id_len)) {
             /* we have match */
             break;
         }
@@ -1430,7 +1430,7 @@
     } else {
         /* map prefix to schema module */
         LY_ARRAY_FOR(prefixes, u) {
-            if (!strncmp(prefixes[u].prefix, prefix, prefix_len) && prefixes[u].prefix[prefix_len] == '\0') {
+            if (!ly_strncmp(prefixes[u].prefix, prefix, prefix_len)) {
                 mod = prefixes[u].mod;
                 break;
             }
@@ -1494,7 +1494,7 @@
     unsigned int u;
 
     LY_ARRAY_FOR(prefixes, u) {
-        if (!strncmp(prefixes[u].prefix, prefix, prefix_len) && prefixes[u].prefix[prefix_len] == '\0') {
+        if (!ly_strncmp(prefixes[u].prefix, prefix, prefix_len)) {
             return prefixes[u].mod;
         }
     }
diff --git a/src/tree_data.c b/src/tree_data.c
index bc11889..d2dd786 100644
--- a/src/tree_data.c
+++ b/src/tree_data.c
@@ -103,21 +103,6 @@
     return trees;
 }
 
-static int
-cmp_str(const char *refstr, const char *str, size_t str_len)
-{
-
-    if (str_len) {
-        if (!strncmp(refstr, str, str_len) && !refstr[str_len]) {
-            return 0;
-        } else {
-            return 1;
-        }
-    } else {
-        return strcmp(refstr, str);
-    }
-}
-
 API const struct lyd_node *
 lyd_search(const struct lyd_node *first, const struct lys_module *module,
           const char *name, size_t name_len, uint16_t nodetype, const char *value, size_t value_len)
@@ -139,7 +124,7 @@
             continue;
         }
 
-        if (cmp_str(snode->name, name, name_len)) {
+        if (ly_strncmp(snode->name, name, name_len)) {
             continue;
         }
 
@@ -147,7 +132,7 @@
             if (snode->nodetype == LYS_LIST) {
                 /* TODO handle value as keys of the list instance */
             } else if (snode->nodetype & (LYS_LEAF | LYS_LEAFLIST)) {
-                if (cmp_str(((struct lyd_node_term*)node)->value.original, value, value_len)) {
+                if (ly_strncmp(((struct lyd_node_term*)node)->value.original, value, value_len)) {
                     continue;
                 }
             } else {
diff --git a/src/tree_schema.c b/src/tree_schema.c
index 240fa6d..fe0c7bc 100644
--- a/src/tree_schema.c
+++ b/src/tree_schema.c
@@ -204,7 +204,7 @@
         }
 
         if (name_len) {
-            if (!strncmp(node->name, name, name_len) && !node->name[name_len]) {
+            if (!ly_strncmp(node->name, name, name_len)) {
                 return node;
             }
         } else {
diff --git a/src/tree_schema_compile.c b/src/tree_schema_compile.c
index c241077..6bd96fa 100644
--- a/src/tree_schema_compile.c
+++ b/src/tree_schema_compile.c
@@ -416,7 +416,7 @@
     }
     LY_ARRAY_FOR(flist, i) {
         f = &flist[i];
-        if (!strncmp(f->name, name, len) && f->name[len] == '\0') {
+        if (!ly_strncmp(f->name, name, len)) {
             return f;
         }
     }
@@ -2309,7 +2309,7 @@
         if (!(context_node->flags & LYS_KEYLESS)) {
             struct lysc_node *key;
             for (key = context_node->child; key && key->nodetype == LYS_LEAF && (key->flags & LYS_KEY); key = key->next) {
-                if (!strncmp(src, key->name, src_len) && key->name[src_len] == '\0') {
+                if (!ly_strncmp(key->name, src, src_len)) {
                     src_node = key;
                     break;
                 }
@@ -4181,7 +4181,7 @@
     } else {
         name = dflt;
     }
-    if (prefix && (strncmp(prefix, node->module->prefix, prefix_len) || node->module->prefix[prefix_len] != '\0')) {
+    if (prefix && ly_strncmp(node->module->prefix, prefix, prefix_len)) {
         /* prefixed default case make sense only for the prefix of the schema itself */
         LOGVAL(ctx->ctx, LY_VLOG_STR, ctx->path, LYVE_REFERENCE,
                "Invalid default case referencing a case from different YANG module (by prefix \"%.*s\").",
@@ -6254,8 +6254,7 @@
                             for (name = d_del->uniques[x], y = 0; name; name = nodeid, ++y) {
                                 nodeid = strpbrk(name, " \t\n");
                                 if (nodeid) {
-                                    if (strncmp(name, list->uniques[z][y]->name, nodeid - name)
-                                            || list->uniques[z][y]->name[nodeid - name] != '\0') {
+                                    if (ly_strncmp(list->uniques[z][y]->name, name, nodeid - name)) {
                                         break;
                                     }
                                     while (isspace(*nodeid)) {
diff --git a/src/tree_schema_helpers.c b/src/tree_schema_helpers.c
index 9259b6f..f767bb6 100644
--- a/src/tree_schema_helpers.c
+++ b/src/tree_schema_helpers.c
@@ -96,9 +96,9 @@
         }
         if (context_node && context_node->nodetype == LYS_ACTION) {
             /* move through input/output manually */
-            if (!strncmp("input", name, name_len)) {
+            if (!ly_strncmp("input", name, name_len)) {
                 (*result_flag) |= LYSC_OPT_RPC_INPUT;
-            } else if (!strncmp("output", name, name_len)) {
+            } else if (!ly_strncmp("output", name, name_len)) {
                 (*result_flag) |= LYSC_OPT_RPC_OUTPUT;
                 getnext_extra_flag = LYS_GETNEXT_OUTPUT;
             } else {
@@ -1015,14 +1015,14 @@
 
 #define FIND_MODULE(TYPE, MOD) \
     TYPE *imp; \
-    if (!strncmp((MOD)->mod->prefix, prefix, len) && (MOD)->mod->prefix[len] == '\0') { \
+    if (!ly_strncmp((MOD)->mod->prefix, prefix, len)) { \
         /* it is the prefix of the module itself */ \
         m = ly_ctx_get_module((MOD)->mod->ctx, (MOD)->mod->name, (MOD)->mod->revision); \
     } \
     /* search in imports */ \
     if (!m) { \
         LY_ARRAY_FOR((MOD)->imports, TYPE, imp) { \
-            if (!strncmp(imp->prefix, prefix, len) && imp->prefix[len] == '\0') { \
+            if (!ly_strncmp(imp->prefix, prefix, len)) { \
                 m = imp->module; \
                 break; \
             } \
diff --git a/src/xml.c b/src/xml.c
index a08417c..1ce50c0 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -249,7 +249,7 @@
     for (u = context->ns.count - 1; u + 1 > 0; --u) {
         ns = (struct lyxml_ns *)context->ns.objs[u];
         if (prefix && prefix_len) {
-            if (ns->prefix && !strncmp(prefix, ns->prefix, prefix_len) && ns->prefix[prefix_len] == '\0') {
+            if (ns->prefix && !ly_strncmp(ns->prefix, prefix, prefix_len)) {
                 return ns;
             }
         } else if (!ns->prefix) {