The cfgfile supports duplicate section name and entry name when parsing
config file, which may confused and hard to debug when accidentally set
duplicate name.

So add strict parse flag, it will treat as error if encounter duplicate
section name or entry name.

Cc: sta...@dpdk.org

Signed-off-by: Chengwen Feng <fengcheng...@huawei.com>
---
 lib/cfgfile/rte_cfgfile.c | 32 +++++++++++++++++++++++---------
 lib/cfgfile/rte_cfgfile.h |  7 +++++++
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/lib/cfgfile/rte_cfgfile.c b/lib/cfgfile/rte_cfgfile.c
index 3033cff4a4..5d96818728 100644
--- a/lib/cfgfile/rte_cfgfile.c
+++ b/lib/cfgfile/rte_cfgfile.c
@@ -102,8 +102,8 @@ _get_section(struct rte_cfgfile *cfg, const char 
*sectionname)
 }
 
 static int
-_add_entry(struct rte_cfgfile_section *section, const char *entryname,
-               const char *entryvalue)
+_add_entry(struct rte_cfgfile *cfg, struct rte_cfgfile_section *section,
+          const char *entryname, const char *entryvalue, bool check_dup)
 {
        int name_len, value_len;
 
@@ -115,6 +115,14 @@ _add_entry(struct rte_cfgfile_section *section, const char 
*entryname,
                return -EINVAL;
        }
 
+       if (check_dup) {
+               if (rte_cfgfile_has_entry(cfg, section->name, entryname) != 0) {
+                       CFG_LOG(ERR, "duplicate entry name %s in section %s",
+                               entryname, section->name);
+                       return -EEXIST;
+               }
+       }
+
        /* resize entry structure if we don't have room for more entries */
        if (section->num_entries == section->allocated_entries) {
                struct rte_cfgfile_entry *n_entries = realloc(
@@ -264,8 +272,9 @@ rte_cfgfile_load_with_params(const char *filename, int 
flags,
                        if (cfg->num_sections == 0)
                                goto error1;
 
-                       ret = _add_entry(&cfg->sections[cfg->num_sections - 1],
-                                        split[0], split[1]);
+                       ret = _add_entry(cfg, &cfg->sections[cfg->num_sections 
- 1],
+                                        split[0], split[1],
+                                        !!(flags & CFG_FLAG_STRICT_PARSE));
                        if (ret != 0)
                                goto error1;
                }
@@ -286,7 +295,8 @@ rte_cfgfile_create(int flags)
        struct rte_cfgfile *cfg;
 
        /* future proof flags usage */
-       if (flags & ~(CFG_FLAG_GLOBAL_SECTION | CFG_FLAG_EMPTY_VALUES))
+       if (flags & ~(CFG_FLAG_GLOBAL_SECTION | CFG_FLAG_EMPTY_VALUES |
+                     CFG_FLAG_STRICT_PARSE))
                return NULL;
 
        cfg = malloc(sizeof(*cfg));
@@ -356,6 +366,13 @@ rte_cfgfile_add_section(struct rte_cfgfile *cfg, const 
char *sectionname)
                return -EINVAL;
        }
 
+       if (cfg->flags & CFG_FLAG_STRICT_PARSE) {
+               if (rte_cfgfile_has_section(cfg, sectionname) != 0) {
+                       CFG_LOG(ERR, "duplicate section name %s", sectionname);
+                       return -EEXIST;
+               }
+       }
+
        /* resize overall struct if we don't have room for more sections */
        if (cfg->num_sections == cfg->allocated_sections) {
 
@@ -396,16 +413,13 @@ int rte_cfgfile_add_entry(struct rte_cfgfile *cfg,
                        || (entryvalue == NULL))
                return -EINVAL;
 
-       if (rte_cfgfile_has_entry(cfg, sectionname, entryname) != 0)
-               return -EEXIST;
-
        /* search for section pointer by sectionname */
        struct rte_cfgfile_section *curr_section = _get_section(cfg,
                                                                sectionname);
        if (curr_section == NULL)
                return -EINVAL;
 
-       ret = _add_entry(curr_section, entryname, entryvalue);
+       ret = _add_entry(cfg, curr_section, entryname, entryvalue, true);
 
        return ret;
 }
diff --git a/lib/cfgfile/rte_cfgfile.h b/lib/cfgfile/rte_cfgfile.h
index 232c65c77b..b3c50cdfb2 100644
--- a/lib/cfgfile/rte_cfgfile.h
+++ b/lib/cfgfile/rte_cfgfile.h
@@ -56,6 +56,13 @@ enum {
         * be zero length (e.g., "key=").
         */
        CFG_FLAG_EMPTY_VALUES = 2,
+
+       /**
+        * Indicates that the parser will not allow for any section and entry
+        * duplicates. If a duplicated section or entry is detected, the
+        * operation will return error.
+        */
+       CFG_FLAG_STRICT_PARSE = 4,
 };
 /**@} */
 
-- 
2.17.1

Reply via email to