Quellcode durchsuchen

ncd: NCDModuleIndex: detect duplicate base_type's

ambrop7 vor 14 Jahren
Ursprung
Commit
a719a6ce17
2 geänderte Dateien mit 73 neuen und 3 gelöschten Zeilen
  1. 66 3
      ncd/NCDModuleIndex.c
  2. 7 0
      ncd/NCDModuleIndex.h

+ 66 - 3
ncd/NCDModuleIndex.c

@@ -42,6 +42,18 @@ static int string_comparator (void *user, const char *s1, const char *s2)
     return 0;
 }
 
+static int string_pointer_comparator (void *user, const char **s1, const char **s2)
+{
+    int cmp = strcmp(*s1, *s2);
+    if (cmp < 0) {
+        return -1;
+    }
+    if (cmp > 0) {
+        return 1;
+    }
+    return 0;
+}
+
 static struct NCDModuleIndex_module * find_module (NCDModuleIndex *o, const char *type)
 {
     BAVLNode *node = BAVL_LookupExact(&o->modules_tree, (void *)type);
@@ -55,11 +67,27 @@ static struct NCDModuleIndex_module * find_module (NCDModuleIndex *o, const char
     return m;
 }
 
+static struct NCDModuleIndex_base_type * find_base_type (NCDModuleIndex *o, const char *base_type)
+{
+    BAVLNode *node = BAVL_LookupExact(&o->base_types_tree, &base_type);
+    if (!node) {
+        return NULL;
+    }
+    
+    struct NCDModuleIndex_base_type *bt = UPPER_OBJECT(node, struct NCDModuleIndex_base_type, base_types_tree_node);
+    ASSERT(!strcmp(bt->base_type, base_type))
+    
+    return bt;
+}
+
 void NCDModuleIndex_Init (NCDModuleIndex *o)
 {
     // init modules tree
     BAVL_Init(&o->modules_tree, OFFSET_DIFF(struct NCDModuleIndex_module, type, modules_tree_node), (BAVL_comparator)string_comparator, NULL);
     
+    // init base types tree
+    BAVL_Init(&o->base_types_tree, OFFSET_DIFF(struct NCDModuleIndex_base_type, base_type, base_types_tree_node), (BAVL_comparator)string_pointer_comparator, NULL);
+    
     DebugObject_Init(&o->d_obj);
 }
 
@@ -67,6 +95,14 @@ void NCDModuleIndex_Free (NCDModuleIndex *o)
 {
     DebugObject_Free(&o->d_obj);
     
+    // free base types
+    while (!BAVL_IsEmpty(&o->base_types_tree)) {
+        struct NCDModuleIndex_base_type *bt = UPPER_OBJECT(BAVL_GetFirst(&o->base_types_tree), struct NCDModuleIndex_base_type, base_types_tree_node);
+        BAVL_Remove(&o->base_types_tree, &bt->base_types_tree_node);
+        free(bt);
+    }
+    
+    // free modules
     while (!BAVL_IsEmpty(&o->modules_tree)) {
         struct NCDModuleIndex_module *m = UPPER_OBJECT(BAVL_GetFirst(&o->modules_tree), struct NCDModuleIndex_module, modules_tree_node);
         BAVL_Remove(&o->modules_tree, &m->modules_tree_node);
@@ -81,23 +117,50 @@ int NCDModuleIndex_AddGroup (NCDModuleIndex *o, const struct NCDModuleGroup *gro
     for (const struct NCDModule *nm = group->modules; nm->type; nm++) {
         if (find_module(o, nm->type)) {
             BLog(BLOG_ERROR, "module type '%s' already exists", nm->type);
-            return 0;
+            goto loop_fail0;
         }
         
         if (strlen(nm->type) > NCDMODULEINDEX_MAX_TYPE_LEN) {
             BLog(BLOG_ERROR, "module type '%s' is too long", nm->type);
-            return 0;
+            goto loop_fail0;
         }
         
         struct NCDModuleIndex_module *m = malloc(sizeof(*m));
         if (!m) {
             BLog(BLOG_ERROR, "malloc failed");
-            return 0;
+            goto loop_fail0;
         }
         
         strcpy(m->type, nm->type);
         m->module = nm;
         ASSERT_EXECUTE(BAVL_Insert(&o->modules_tree, &m->modules_tree_node, NULL))
+        
+        const char *base_type = (nm->base_type ? nm->base_type : nm->type);
+        
+        struct NCDModuleIndex_base_type *bt = find_base_type(o, base_type);
+        if (bt) {
+            if (bt->group != group) {
+                BLog(BLOG_ERROR, "module base type '%s' already exists in another module group", base_type);
+                goto loop_fail1;
+            }
+        } else {
+            if (!(bt = malloc(sizeof(*bt)))) {
+                BLog(BLOG_ERROR, "malloc failed");
+                goto loop_fail1;
+            }
+            
+            bt->base_type = base_type;
+            bt->group = group;
+            ASSERT_EXECUTE(BAVL_Insert(&o->base_types_tree, &bt->base_types_tree_node, NULL))
+        }
+        
+        continue;
+        
+    loop_fail1:
+        BAVL_Remove(&o->modules_tree, &m->modules_tree_node);
+        free(m);
+    loop_fail0:
+        return 0;
     }
     
     return 1;

+ 7 - 0
ncd/NCDModuleIndex.h

@@ -32,6 +32,7 @@
 
 typedef struct {
     BAVL modules_tree;
+    BAVL base_types_tree;
     DebugObject d_obj;
 } NCDModuleIndex;
 
@@ -41,6 +42,12 @@ struct NCDModuleIndex_module {
     BAVLNode modules_tree_node;
 };
 
+struct NCDModuleIndex_base_type {
+    const char *base_type;
+    const struct NCDModuleGroup *group;
+    BAVLNode base_types_tree_node;
+};
+
 void NCDModuleIndex_Init (NCDModuleIndex *o);
 void NCDModuleIndex_Free (NCDModuleIndex *o);
 int NCDModuleIndex_AddGroup (NCDModuleIndex *o, const struct NCDModuleGroup *group) WARN_UNUSED;