/* * Create a new, empty hwset. * This routine may block, and must not be called from any * paused CPU context. */ static group_t * pghw_set_create(pghw_type_t hw) { group_t *g; int ret; /* * Create the top level PG hw group if it doesn't already exist * This is a "set" of hardware sets, that is ordered (and indexed) * by the pghw_type_t enum. */ if (pg_hw == NULL) { pg_hw = kmem_alloc(sizeof (group_t), KM_SLEEP); group_create(pg_hw); group_expand(pg_hw, (uint_t)PGHW_NUM_COMPONENTS); } /* * Create the new hwset * Add it to the top level pg_hw group. */ g = kmem_alloc(sizeof (group_t), KM_SLEEP); group_create(g); ret = group_add_at(pg_hw, g, (uint_t)hw); ASSERT(ret == 0); return (g); }
} END_TEST /** * \brief Test function invocation on not created group list. * * This test must be run without setup funtions which are used for other tests * * Its aim is to test response of function when GroupList is not allocated. */ START_TEST(test_noexistent) { ImageGroup *tmp = group_create("test", 'a'); fail_unless( FAIL == glist_group_insert(tmp), NULL); fail_unless( FAIL == glist_group_remove_by_index(0), NULL); fail_unless( FAIL == glist_get_by_index(0), NULL); fail_unless( NULL == glist_get_by_tag('Y'), NULL); fail_unless( NULL == glist_get_by_name("some name"), NULL); fail_unless( -1 == glist_get_size(), NULL); group_destroy(tmp); error_reset(); } END_TEST
} END_TEST /** * \brief Setup structures before test. * * Create test image group and store its pointer to static variable. Allocate * image structures for the test and insert them into test group. */ static void group_setup(void) { char image_number = '0'; char image_name[10] = "image 0"; int i; COLOR_SETUP_START; // create temporary image structures for (i = 0; i < 10; i++) { image_name[6] = image_number + i; pointer_list[i] = image_create(image_name); if ( error_is_error() ) ERROR_LOG(); } // create group with 10 elements for next testing image_group = group_create("general", 'G'); group_insert(image_group, 0, pointer_list, 10); if ( error_is_error() ) ERROR_LOG(); COLOR_SETUP_END; return ; }
} END_TEST /** * \brief Verify that it is not possible to insert one image twice */ START_TEST(test_insert_image_double) { Image* test_data_1[4] = { pointer_list[0], pointer_list[1], pointer_list[2], pointer_list[3] }; Image* test_data_2[4] = { pointer_list[1], pointer_list[4], pointer_list[2], pointer_list[5] }; ImageGroup* test_group = group_create("test_name", 't'); ck_assert_int_eq( 0, group_get_size(test_group) ); // initial insertion of 3 images into list ck_assert( OK == group_insert(test_group, 0, test_data_1, 4) ); ck_assert_int_eq( 4, group_get_size(test_group) ); ck_assert_str_eq( test_data_1[0]->name, group_get_image(test_group, 0)->name ); ck_assert_str_eq( test_data_1[1]->name, group_get_image(test_group, 1)->name ); ck_assert_str_eq( test_data_1[2]->name, group_get_image(test_group, 2)->name ); ck_assert_str_eq( test_data_1[3]->name, group_get_image(test_group, 3)->name ); // insert two images at the end of image list ck_assert( OK == group_insert(test_group, 4, test_data_2, 4) ); ck_assert_int_eq( 6, group_get_size(test_group) ); ck_assert_str_eq( test_data_2[1]->name, group_get_image(test_group, 4)->name ); ck_assert_str_eq( test_data_2[3]->name, group_get_image(test_group, 5)->name ); ck_assert( OK == group_destroy(test_group) ); ck_assert( ! error_is_error() ); } END_TEST
DiaObject * create_standard_group(GList *items) { DiaObject *new_obj; new_obj = group_create((GList*)items); return new_obj; }
void diagram_group_selected(Diagram *dia) { GList *list; GList *group_list; DiaObject *group; DiaObject *obj; GList *orig_list; Change *change; if (g_list_length(dia->data->selected) < 1) { message_error(_("Trying to group with no selected objects.")); return; } #if 0 /* the following is wrong as it screws up the selected list, see bug #153525 * I just don't get what was originally intented so please speak up if you know --hb */ dia->data->selected = parent_list_affected(dia->data->selected); #endif orig_list = g_list_copy(dia->data->active_layer->objects); /* We have to rebuild the selection list so that it is the same order as in the Diagram list. */ group_list = diagram_get_sorted_selected_remove(dia); list = group_list; while (list != NULL) { obj = (DiaObject *)list->data; /* Remove connections from obj to objects outside created group. */ /* strip_connections sets up its own undo info. */ /* The connections aren't reattached by ungroup. */ strip_connections(obj, dia->data->selected, dia); list = g_list_next(list); } /* Remove list of selected objects */ textedit_remove_focus_all(dia); data_remove_all_selected(dia->data); group = group_create(group_list); change = undo_group_objects(dia, group_list, group, orig_list); (change->apply)(change, dia); /* Select the created group */ diagram_select(dia, group); diagram_modified(dia); diagram_flush(dia); undo_set_transactionpoint(dia->undo); }
/*! * \brief Parse _DiaObject from the given node * Fill a GList* with objects which is to be put in a * diagram or a group by the caller. * Can be called recursively to allow groups in groups. * This is only using the render branch of the file, if the * object type is not registered with Dia. Otherwise the objects * are just created from their type and properties. * \ingroup DiaRenderScriptImport */ static GList* read_items (xmlNodePtr startnode, DiaContext *ctx) { xmlNodePtr node; GList *items = NULL; for (node = startnode; node != NULL; node = node->next) { if (xmlIsBlankNode(node)) continue; if (node->type != XML_ELEMENT_NODE) continue; if (!xmlStrcmp(node->name, (const xmlChar *)"object")) { xmlChar *sType = xmlGetProp(node, (const xmlChar *)"type"); const DiaObjectType *ot = object_get_type ((gchar *)sType); xmlNodePtr props = NULL, render = NULL; props = find_child_named (node, "properties"); render = find_child_named (node, "render"); if (ot && !ot->ops) { GList *moreitems; /* FIXME: 'render' is also the grouping element */ moreitems = read_items (render->children, ctx); if (moreitems) { DiaObject *group = group_create (moreitems); /* apply group props, e.g. transform */ object_load_props (group, props, ctx); /* group eats list */ items = g_list_append (items, group); } } else if (ot) { Point startpoint = {0.0,0.0}; Handle *handle1,*handle2; DiaObject *o; o = ot->ops->create(&startpoint, ot->default_user_data, &handle1,&handle2); if (o) { object_load_props (o, props, ctx); items = g_list_append (items, o); } } else if (render) { DiaObject *o = _render_object (render, ctx); if (o) items = g_list_append (items, o); } else { g_debug ("DRS-Import: %s?", node->name); } } else { g_debug ("DRS-Import: %s?", node->name); } } return items; }
} END_TEST /** * The setup and teardown function will be used for all test except for creation * and destruction of group list. */ static void test_setup(void) { COLOR_SETUP_START; glist_create(); // prepare image groups we will use for tests group_data[0] = group_create("test group 1", 'a'); group_data[1] = group_create("test group 2", 'b'); group_data[2] = group_create("test group 3", 'c'); group_data[3] = group_create("test group 4", 'd'); group_data[4] = group_create("test group 5", 'e'); if ( error_is_error() ) { ERROR_LOG(); } COLOR_SETUP_END; return ; }
static GList * read_objects(xmlNodePtr objects, GHashTable *objects_hash, char *filename) { GList *list; ObjectType *type; Object *obj; ObjectNode obj_node; char *typestr; char *versionstr; char *id; int version; list = NULL; obj_node = objects->childs; while ( obj_node != NULL) { if (strcmp(obj_node->name, "object")==0) { typestr = xmlGetProp(obj_node, "type"); versionstr = xmlGetProp(obj_node, "version"); id = xmlGetProp(obj_node, "id"); version = 0; if (versionstr != NULL) { version = atoi(versionstr); free(versionstr); } type = object_get_type((char *)typestr); if (typestr) free(typestr); obj = type->ops->load(obj_node, version, filename); list = g_list_append(list, obj); g_hash_table_insert(objects_hash, (char *)id, obj); } else if (strcmp(obj_node->name, "group")==0) { obj = group_create(read_objects(obj_node, objects_hash, filename)); list = g_list_append(list, obj); } else { message_error(_("Error reading diagram file\n")); } obj_node = obj_node->next; } return list; }
/* * Create a cmt_lgrp_t with the specified handle. */ static cmt_lgrp_t * pg_cmt_lgrp_create(lgrp_handle_t hand) { cmt_lgrp_t *lgrp; ASSERT(MUTEX_HELD(&cpu_lock)); lgrp = kmem_zalloc(sizeof (cmt_lgrp_t), KM_SLEEP); lgrp->cl_hand = hand; lgrp->cl_npgs = 0; lgrp->cl_next = cmt_lgrps; cmt_lgrps = lgrp; group_create(&lgrp->cl_pgs); return (lgrp); }
} END_TEST /** * \brief Verify insertion of images into empty list * * Insert images into empty list and verify its position in the image group * arrays is correct. Verify that the image reference counters are handled * correctly. * * The number of references is 2 at the start of the test (1 reference is held * by pointer_list array and another by static image_group). */ START_TEST(test_insert_image_simple) { Image* test_data[3] = { pointer_list[0], pointer_list[1], pointer_list[2] }; ImageGroup *test_group = group_create("test_name", 't'); int i; // check inserting three images into empty image file ck_assert( OK == group_insert(test_group, 0, test_data, 3) ); ck_assert_int_eq( 3, group_get_size(test_group) ); for (i = 0; i < 3; i++ ) { Image* image = group_get_image(test_group, i); ck_assert_int_eq( 3, image->ref ); ck_assert_str_eq( test_data[i]->name, image->name ); // the image is also in the 'general' group created in setup function ck_assert_int_eq( 2, taglist_get_count(image->group)); ck_assert_int_eq( TRUE, taglist_contains(image->group, 't') ); } // destroy image list ck_assert( OK == group_destroy(test_group) ); ck_assert( ! error_is_error() ); // check reference count on the images has droped and they are no longer in // group for (i = 0; i < 3; i++ ) { ck_assert_int_eq( 2, test_data[i]->ref ); ck_assert_int_eq( 1, taglist_get_count(test_data[i]->group)); ck_assert_int_eq( FALSE, taglist_contains(test_data[i]->group, 't') ); } } END_TEST
} END_TEST /** * \brief Verify range pasting works correctly * * Yank and paste some image pointers from one group and paste it to another * group. Verify the image pointer references are handled correctly. */ START_TEST(test_yank_paste) { Range rng; ImageGroup* test_group = group_create("test_name", 't'); ck_assert_int_eq( 0, group_get_size(test_group) ); // yank some data from the middle of group and do initial yank buffer // allocation rng.start = 2; rng.end = 4; ck_assert( OK == group_yank_range(image_group, rng) ); ck_assert_str_eq( pointer_list[2]->name, group_yank_buffer[0]->name ); ck_assert_str_eq( pointer_list[3]->name, group_yank_buffer[1]->name ); ck_assert_str_eq( pointer_list[4]->name, group_yank_buffer[2]->name ); ck_assert_int_eq( 3, pointer_list[2]->ref ); ck_assert_int_eq( 3, pointer_list[3]->ref ); ck_assert_int_eq( 3, pointer_list[4]->ref ); ck_assert_int_eq( 3, group_buffer_size() ); ck_assert_int_eq( 3, group_buffer_max_size() ); // paste from yank buffer ck_assert( OK == group_yank_paste(test_group, 0) ); ck_assert_str_eq( pointer_list[2]->name, group_get_image(test_group, 0)->name ); ck_assert_str_eq( pointer_list[3]->name, group_get_image(test_group, 1)->name ); ck_assert_str_eq( pointer_list[4]->name, group_get_image(test_group, 2)->name ); ck_assert_int_eq( 4, pointer_list[2]->ref ); ck_assert_int_eq( 4, pointer_list[3]->ref ); ck_assert_int_eq( 4, pointer_list[4]->ref ); ck_assert_int_eq( 3, group_get_size(test_group) ); ck_assert( OK == group_destroy(test_group) ); ck_assert( ! error_is_error() ); } END_TEST
void test_group( int *passed, int *failed ) { group *g = group_create( 2, 1, test_name ); if ( g != NULL ) { group_set_parent( g, 7 ); if ( group_parent(g)==7&&group_id(g)==2&&group_datasize(g,"utf-8")==10 ) (*passed)++; else { fprintf(stderr, "group: id=%d parent=%d datasize=%d\n", group_id(g),group_parent(g),group_datasize(g,"utf-8")); (*failed)++; } group_dispose( g ); } else { fprintf(stderr,"group: failed to allocate object\n"); (*failed)++; } }
/** * Recursive function to read objects from a specific level in the xml. * * Nowadays there are quite a few of them : * - Layers : a diagram may have different layers, but this function does *not* * add the created objects to them as it does not know on which nesting level it * is called. So the topmost caller must add the returned objects to the layer. * - Groups : groups in itself can have an arbitrary nesting level including other * groups or objects or both of them. A group not containing any objects is by * definition useless. So it is not created. This is to avoid trouble with some older * diagrams which happen to be saved with empty groups. * - Parents : if the parent relations would have been there from the beginning of * Dias file format they probably would have been added as nesting level * themselves. But to maintain forward compatibility (allow to let older versions * of Dia to see as much as possible) they were added all on the same level and * the parent child relation is reconstructed from additional attributes. */ static GList * read_objects(xmlNodePtr objects, GHashTable *objects_hash, DiaContext *ctx, DiaObject *parent, GHashTable *unknown_objects_hash) { GList *list; DiaObjectType *type; DiaObject *obj; ObjectNode obj_node; char *typestr; char *versionstr; char *id; int version; xmlNodePtr child_node; list = NULL; obj_node = objects->xmlChildrenNode; while ( obj_node != NULL) { if (xmlIsBlankNode(obj_node)) { obj_node = obj_node->next; continue; } if (!obj_node) break; if (xmlStrcmp(obj_node->name, (const xmlChar *)"object")==0) { typestr = (char *) xmlGetProp(obj_node, (const xmlChar *)"type"); versionstr = (char *) xmlGetProp(obj_node, (const xmlChar *)"version"); id = (char *) xmlGetProp(obj_node, (const xmlChar *)"id"); version = 0; if (versionstr != NULL) { version = atoi(versionstr); xmlFree(versionstr); } type = object_get_type((char *)typestr); if (!type) { if (g_utf8_validate (typestr, -1, NULL) && NULL == g_hash_table_lookup(unknown_objects_hash, typestr)) g_hash_table_insert(unknown_objects_hash, g_strdup(typestr), 0); } else { obj = type->ops->load(obj_node, version, ctx); list = g_list_append(list, obj); if (parent) { obj->parent = parent; parent->children = g_list_append(parent->children, obj); } g_hash_table_insert(objects_hash, g_strdup((char *)id), obj); child_node = obj_node->children; while(child_node) { if (xmlStrcmp(child_node->name, (const xmlChar *)"children") == 0) { GList *children_read = read_objects(child_node, objects_hash, ctx, obj, unknown_objects_hash); list = g_list_concat(list, children_read); break; } child_node = child_node->next; } } if (typestr) xmlFree(typestr); if (id) xmlFree (id); } else if (xmlStrcmp(obj_node->name, (const xmlChar *)"group")==0 && obj_node->children) { /* don't create empty groups */ GList *inner_objects = read_objects(obj_node, objects_hash, ctx, NULL, unknown_objects_hash); if (inner_objects) { obj = group_create(inner_objects); object_load_props(obj, obj_node, ctx); list = g_list_append(list, obj); } } else { /* silently ignore other nodes */ } obj_node = obj_node->next; } return list; }
/* * CMT class callback for a new CPU entering the system * * This routine operates on the CPU specific processor group data (for the CPU * being initialized). The argument "pgdata" is a reference to the CPU's PG * data to be constructed. * * cp->cpu_pg is used by the dispatcher to access the CPU's PG data * references a "bootstrap" structure. pg_cmt_cpu_init() and the routines it * calls must be careful to operate only on the "pgdata" argument, and not * cp->cpu_pg. */ static void pg_cmt_cpu_init(cpu_t *cp, cpu_pg_t *pgdata) { pg_cmt_t *pg; group_t *cmt_pgs; int levels, level; pghw_type_t hw; pg_t *pg_cache = NULL; pg_cmt_t *cpu_cmt_hier[PGHW_NUM_COMPONENTS]; lgrp_handle_t lgrp_handle; cmt_lgrp_t *lgrp; cmt_lineage_validation_t lineage_status; ASSERT(MUTEX_HELD(&cpu_lock)); ASSERT(pg_cpu_is_bootstrapped(cp)); if (cmt_sched_disabled) return; /* * A new CPU is coming into the system. * Interrogate the platform to see if the CPU * has any performance or efficiency relevant * sharing relationships */ cmt_pgs = &pgdata->cmt_pgs; pgdata->cmt_lineage = NULL; bzero(cpu_cmt_hier, sizeof (cpu_cmt_hier)); levels = 0; for (hw = PGHW_START; hw < PGHW_NUM_COMPONENTS; hw++) { pg_cmt_policy_t policy; /* * We're only interested in the hw sharing relationships * for which we know how to optimize. */ policy = pg_cmt_policy(hw); if (policy == CMT_NO_POLICY || pg_plat_hw_shared(cp, hw) == 0) continue; /* * We will still create the PGs for hardware sharing * relationships that have been blacklisted, but won't * implement CMT thread placement optimizations against them. */ if (cmt_hw_blacklisted[hw] == 1) policy = CMT_NO_POLICY; /* * Find (or create) the PG associated with * the hw sharing relationship in which cp * belongs. * * Determine if a suitable PG already * exists, or if one needs to be created. */ pg = (pg_cmt_t *)pghw_place_cpu(cp, hw); if (pg == NULL) { /* * Create a new one. * Initialize the common... */ pg = (pg_cmt_t *)pg_create(pg_cmt_class_id); /* ... physical ... */ pghw_init((pghw_t *)pg, cp, hw); /* * ... and CMT specific portions of the * structure. */ pg->cmt_policy = policy; /* CMT event callbacks */ cmt_callback_init((pg_t *)pg); bitset_init(&pg->cmt_cpus_actv_set); group_create(&pg->cmt_cpus_actv); } else { ASSERT(IS_CMT_PG(pg)); } /* Add the CPU to the PG */ pg_cpu_add((pg_t *)pg, cp, pgdata); /* * Ensure capacity of the active CPU group/bitset */ group_expand(&pg->cmt_cpus_actv, GROUP_SIZE(&((pg_t *)pg)->pg_cpus)); if (cp->cpu_seqid >= bitset_capacity(&pg->cmt_cpus_actv_set)) { bitset_resize(&pg->cmt_cpus_actv_set, cp->cpu_seqid + 1); } /* * Build a lineage of CMT PGs for load balancing / coalescence */ if (policy & (CMT_BALANCE | CMT_COALESCE)) { cpu_cmt_hier[levels++] = pg; } /* Cache this for later */ if (hw == PGHW_CACHE) pg_cache = (pg_t *)pg; } group_expand(cmt_pgs, levels); if (cmt_root == NULL) cmt_root = pg_cmt_lgrp_create(lgrp_plat_root_hand()); /* * Find the lgrp that encapsulates this CPU's CMT hierarchy */ lgrp_handle = lgrp_plat_cpu_to_hand(cp->cpu_id); if ((lgrp = pg_cmt_find_lgrp(lgrp_handle)) == NULL) lgrp = pg_cmt_lgrp_create(lgrp_handle); /* * Ascendingly sort the PGs in the lineage by number of CPUs */ pg_cmt_hier_sort(cpu_cmt_hier, levels); /* * Examine the lineage and validate it. * This routine will also try to fix the lineage along with the * rest of the PG hierarchy should it detect an issue. * * If it returns anything other than VALID or REPAIRED, an * unrecoverable error has occurred, and we cannot proceed. */ lineage_status = pg_cmt_lineage_validate(cpu_cmt_hier, &levels, pgdata); if ((lineage_status != CMT_LINEAGE_VALID) && (lineage_status != CMT_LINEAGE_REPAIRED)) { /* * In the case of an unrecoverable error where CMT scheduling * has been disabled, assert that the under construction CPU's * PG data has an empty CMT load balancing lineage. */ ASSERT((cmt_sched_disabled == 0) || (GROUP_SIZE(&(pgdata->cmt_pgs)) == 0)); return; } /* * For existing PGs in the lineage, verify that the parent is * correct, as the generation in the lineage may have changed * as a result of the sorting. Start the traversal at the top * of the lineage, moving down. */ for (level = levels - 1; level >= 0; ) { int reorg; reorg = 0; pg = cpu_cmt_hier[level]; /* * Promote PGs at an incorrect generation into place. */ while (pg->cmt_parent && pg->cmt_parent != cpu_cmt_hier[level + 1]) { cmt_hier_promote(pg, pgdata); reorg++; } if (reorg > 0) level = levels - 1; else level--; } /* * For each of the PGs in the CPU's lineage: * - Add an entry in the CPU sorted CMT PG group * which is used for top down CMT load balancing * - Tie the PG into the CMT hierarchy by connecting * it to it's parent and siblings. */ for (level = 0; level < levels; level++) { uint_t children; int err; pg = cpu_cmt_hier[level]; err = group_add_at(cmt_pgs, pg, levels - level - 1); ASSERT(err == 0); if (level == 0) pgdata->cmt_lineage = (pg_t *)pg; if (pg->cmt_siblings != NULL) { /* Already initialized */ ASSERT(pg->cmt_parent == NULL || pg->cmt_parent == cpu_cmt_hier[level + 1]); ASSERT(pg->cmt_siblings == &lgrp->cl_pgs || ((pg->cmt_parent != NULL) && pg->cmt_siblings == pg->cmt_parent->cmt_children)); continue; } if ((level + 1) == levels) { pg->cmt_parent = NULL; pg->cmt_siblings = &lgrp->cl_pgs; children = ++lgrp->cl_npgs; if (cmt_root != lgrp) cmt_root->cl_npgs++; } else { pg->cmt_parent = cpu_cmt_hier[level + 1]; /* * A good parent keeps track of their children. * The parent's children group is also the PG's * siblings. */ if (pg->cmt_parent->cmt_children == NULL) { pg->cmt_parent->cmt_children = kmem_zalloc(sizeof (group_t), KM_SLEEP); group_create(pg->cmt_parent->cmt_children); } pg->cmt_siblings = pg->cmt_parent->cmt_children; children = ++pg->cmt_parent->cmt_nchildren; } group_expand(pg->cmt_siblings, children); group_expand(&cmt_root->cl_pgs, cmt_root->cl_npgs); } /* * Cache the chip and core IDs in the cpu_t->cpu_physid structure * for fast lookups later. */ if (cp->cpu_physid) { cp->cpu_physid->cpu_chipid = pg_plat_hw_instance_id(cp, PGHW_CHIP); cp->cpu_physid->cpu_coreid = pg_plat_get_core_id(cp); /* * If this cpu has a PG representing shared cache, then set * cpu_cacheid to that PG's logical id */ if (pg_cache) cp->cpu_physid->cpu_cacheid = pg_cache->pg_id; } /* CPU0 only initialization */ if (is_cpu0) { is_cpu0 = 0; cpu0_lgrp = lgrp; } }
/** * Recursive function to read objects from a specific level in the xml. * * Nowadays there are quite a few of them : * - Layers : a diagram may have different layers, but this function does *not* * add the created objects to them as it does not know on which nesting level it * is called. So the topmost caller must add the returned objects to the layer. * - Groups : groups in itself can have an arbitrary nesting level including other * groups or objects or both of them. A group not containing any objects is by * definition useless. So it is not created. This is to avoid trouble with some older * diagrams which happen to be saved with empty groups. * - Parents : if the parent relations would have been there from the beginning of * Dias file format they probably would have been added as nesting level * themselves. But to maintain forward compatibility (allow to let older versions * of Dia to see as much as possible) they were added all on the same level and * the parent child relation is reconstructed from additional attributes. */ static GList * read_objects(xmlNodePtr objects, GHashTable *objects_hash,const char *filename, DiaObject *parent, GHashTable *unknown_objects_hash) { GList *list; DiaObjectType *type; DiaObject *obj; ObjectNode obj_node; char *typestr; char *versionstr; char *id; int version; xmlNodePtr child_node; list = NULL; obj_node = objects->xmlChildrenNode; while ( obj_node != NULL) { if (xmlIsBlankNode(obj_node)) { obj_node = obj_node->next; continue; } if (!obj_node) break; if (xmlStrcmp(obj_node->name, (const xmlChar *)"object")==0) { typestr = (char *) xmlGetProp(obj_node, (const xmlChar *)"type"); versionstr = (char *) xmlGetProp(obj_node, (const xmlChar *)"version"); id = (char *) xmlGetProp(obj_node, (const xmlChar *)"id"); version = 0; if (versionstr != NULL) { version = atoi(versionstr); xmlFree(versionstr); } type = object_get_type((char *)typestr); if (!type) { if (g_utf8_validate (typestr, -1, NULL) && NULL == g_hash_table_lookup(unknown_objects_hash, typestr)) g_hash_table_insert(unknown_objects_hash, g_strdup(typestr), 0); } else { obj = type->ops->load(obj_node, version, filename); list = g_list_append(list, obj); if (parent) { obj->parent = parent; parent->children = g_list_append(parent->children, obj); } g_hash_table_insert(objects_hash, g_strdup((char *)id), obj); child_node = obj_node->children; while(child_node) { if (xmlStrcmp(child_node->name, (const xmlChar *)"children") == 0) { GList *children_read = read_objects(child_node, objects_hash, filename, obj, unknown_objects_hash); list = g_list_concat(list, children_read); break; } child_node = child_node->next; } } if (typestr) xmlFree(typestr); if (id) xmlFree (id); } else if (xmlStrcmp(obj_node->name, (const xmlChar *)"group")==0 && obj_node->children) { /* don't create empty groups */ obj = group_create(read_objects(obj_node, objects_hash, filename, NULL, unknown_objects_hash)); #ifdef USE_NEWGROUP /* Old group objects had objects recursively inside them. Since * objects are now done with parenting, we need to extract those objects, * make a newgroup object, set parent-child relationships, and add * all of them to the diagram. */ { DiaObject *newgroup; GList *objects; Point lower_right; type = object_get_type("Misc - NewGroup"); lower_right = obj->position; newgroup = type->ops->create(&lower_right, NULL, NULL, NULL); list = g_list_append(list, newgroup); for (objects = group_objects(obj); objects != NULL; objects = g_list_next(objects)) { DiaObject *subobj = (DiaObject *) objects->data; list = g_list_append(list, subobj); subobj->parent = newgroup; newgroup->children = g_list_append(newgroup->children, subobj); if (subobj->bounding_box.right > lower_right.x) { lower_right.x = subobj->bounding_box.right; } if (subobj->bounding_box.bottom > lower_right.y) { lower_right.y = subobj->bounding_box.bottom; } } newgroup->ops->move_handle(newgroup, newgroup->handles[7], &lower_right, NULL, HANDLE_MOVE_CREATE_FINAL, 0); /* We've used the info from the old group, destroy it */ group_destroy_shallow(obj); } #else list = g_list_append(list, obj); #endif } else { /* silently ignore other nodes */ } obj_node = obj_node->next; } return list; }
/*! \brief group_create wrapper */ static void add_group(ATTRIBUTE_UNUSED void * data, uint32_t id, string * name) { group_create(id, name); }
} END_TEST /** * \brief Verify insertion of images into non-empty list * * Insert from one to three images into various positions in the image group * array and verify the insertion was done to correct place. Verify that the * image reference counters are handled correctly. */ START_TEST(test_insert_image_complex) { Image* test_data_1[1] = { pointer_list[0] }; Image* test_data_2[3] = { pointer_list[1], pointer_list[2], pointer_list[3] }; Image* test_data_3[2] = { pointer_list[4], pointer_list[5] }; Image* test_data_4[1] = { pointer_list[6] }; ImageGroup* test_group = group_create("test_name", 't'); ck_assert( NULL != test_group ); ck_assert( NULL != test_group->list ); ck_assert_int_eq( 0, group_get_size(test_group) ); // initial insertion of 3 images into list ck_assert( OK == group_insert(test_group, 0, test_data_2, 3) ); ck_assert_int_eq( 3, group_get_size(test_group) ); ck_assert_int_eq( 3, test_data_2[0]->ref ); ck_assert_int_eq( 3, test_data_2[1]->ref ); ck_assert_int_eq( 3, test_data_2[2]->ref ); ck_assert_str_eq( test_data_2[0]->name, group_get_image(test_group, 0)->name ); ck_assert_str_eq( test_data_2[1]->name, group_get_image(test_group, 1)->name ); ck_assert_str_eq( test_data_2[2]->name, group_get_image(test_group, 2)->name ); // insert one image at the beginning of image list ck_assert( OK == group_insert(test_group, 0, test_data_1, 1) ); ck_assert_int_eq( 4, group_get_size(test_group) ); ck_assert_int_eq( 3, test_data_1[0]->ref ); ck_assert_str_eq( test_data_1[0]->name, group_get_image(test_group, 0)->name ); ck_assert_str_eq( test_data_2[0]->name, group_get_image(test_group, 1)->name ); // insert one image at the end of image list ck_assert( OK == group_insert(test_group, 4, test_data_4, 1) ); ck_assert_int_eq( 5, group_get_size(test_group) ); ck_assert_int_eq( 3, test_data_4[0]->ref ); ck_assert_str_eq( test_data_4[0]->name, group_get_image(test_group, 4)->name ); ck_assert_str_eq( test_data_2[2]->name, group_get_image(test_group, 3)->name ); // insert two images in the middle of image list ck_assert( OK == group_insert(test_group,2, test_data_3, 2) ); ck_assert_int_eq( 7, group_get_size(test_group) ); ck_assert_int_eq( 3, test_data_3[0]->ref ); ck_assert_int_eq( 3, test_data_3[1]->ref ); ck_assert_str_eq( test_data_2[0]->name, group_get_image(test_group, 1)->name ); ck_assert_str_eq( test_data_3[0]->name, group_get_image(test_group, 2)->name ); ck_assert_str_eq( test_data_3[1]->name, group_get_image(test_group, 3)->name ); ck_assert_str_eq( test_data_2[1]->name, group_get_image(test_group, 4)->name ); // destroy image list ck_assert( OK == group_destroy(test_group) ); ck_assert( ! error_is_error() ); // check references of selected image pointers ck_assert_int_eq( 2, test_data_1[0]->ref ); ck_assert_int_eq( 2, test_data_2[0]->ref ); ck_assert_int_eq( 2, test_data_2[1]->ref ); ck_assert_int_eq( 2, test_data_2[2]->ref ); ck_assert_int_eq( 2, test_data_3[0]->ref ); ck_assert_int_eq( 2, test_data_3[1]->ref ); } END_TEST
/* s = service the command was sent to u = user the command was sent from */ void ns_group(IRC_User *s, IRC_User *u) { u_int32_t source_snid; u_int32_t snid; char *cmd; char *gname; char *nick; int memberc = 0; u_int32_t master_sgid; u_int32_t sgid; CHECK_IF_IDENTIFIED_NICK cmd = strtok(NULL, " "); gname = strtok(NULL, " "); /* base syntax validation */ if(IsNull(cmd)) send_lang(u, s, NS_GROUP_SYNTAX); else if(strcasecmp(cmd,"CREATE") == 0) { char *master; char *gdesc; char *umodes = NULL; master = strtok(NULL, " "); gdesc = strtok(NULL, ""); if(gname) /* first check if the name contains umodes */ { char *pumodes; char *eumodes; pumodes = strchr(gname,'['); if(pumodes && pumodes[0]) { *(pumodes++) = '\0'; eumodes = strchr(pumodes,']'); if(eumodes) { *eumodes = '\0'; umodes = pumodes; } } } /* syntax validation */ if(IsNull(gname) || IsNull(master)) send_lang(u, s, NS_GROUP_CREATE_SYNTAX); /* permissions validation */ else if(!is_sroot(source_snid)) send_lang(u, s, NICK_NOT_ROOT); /* check requirements */ else if((master_sgid = find_group(master)) == 0) send_lang(u, s, NS_GROUP_MASTER_NOT_FOUND, master); /* avoid duplicates */ else if((sgid = find_group(gname)) != 0) send_lang(u, s, NS_GROUP_ALREADY_EXISTS, gname); /* execute operation */ else if(group_create(gname, master_sgid, gdesc, umodes) > 0) /* report operation status */ send_lang(u, s, NS_GROUP_CREATE_OK, gname); else send_lang(u, s, UPDATE_FAIL); } else if(strcasecmp(cmd,"ADD") == 0) { u_int32_t duration = 0; time_t master_expire = 0; u_int32_t is_master_sgid; char *duration_str; nick = strtok(NULL, " "); duration_str = strtok(NULL, " "); if(duration_str) duration = time_str(duration_str); /* syntax validation */ if(IsNull(gname) || IsNull(nick)) send_lang(u, s, NS_GROUP_ADD_SYNTAX); /* check requirements */ else if((snid = nick2snid(nick)) == 0) send_lang(u, s, NO_SUCH_NICK_X, nick); else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); /* privileges validation */ else if(group_is_full(sgid)) send_lang(u, s, NS_GROUP_IS_FULL_X); else if(((is_master_sgid = is_master(source_snid, sgid))== 0) && !is_sroot(source_snid)) send_lang(u, s, NOT_MASTER_OF_X, gname); /* avoid duplicates */ else if(sql_singlequery("SELECT t_expire FROM ns_group_users " " WHERE sgid=%d AND snid=%d", is_master_sgid, source_snid) && (master_expire = sql_field_i(0)) && duration) send_lang(u, s, NS_GROUP_CANT_DEFINE_TIME_X, gname); else if(is_member_of(snid, sgid)) send_lang(u, s, NICK_X_ALREADY_ON_X, nick, gname); /* execute operation */ else { time_t t_expire = 0; if(master_expire) t_expire = master_expire; else if(duration) t_expire = irc_CurrentTime + duration; if(add_to_group(sgid, snid, t_expire) > 0) /* report operation status */ { char *server = strchr(gname, '@'); IRC_User *user = irc_FindUser(nick); send_lang(u, s, NICK_ADDED_X_X, nick, gname); if(server) /* we have a server rule to be validated */ ++server; if(user && (!server || (strcasecmp(server,u->server->sname) == 0))) { if(user->extra[ED_GROUPS] == NULL) { user->extra[ED_GROUPS] = malloc(sizeof(darray)); array_init(user->extra[ED_GROUPS], 1, DA_INT); } array_add_int(user->extra[ED_GROUPS], sgid); } } else send_lang(u, s, UPDATE_FAIL); } } else if(strcasecmp(cmd,"DEL") == 0) { nick = strtok(NULL, " "); /* syntax validation */ if(IsNull(gname) || IsNull(nick)) send_lang(u, s, NS_GROUP_DEL_SYNTAX); /* check requirements */ else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); else if((snid = nick2snid(nick)) == 0) send_lang(u, s, NO_SUCH_NICK_X, nick); /* privileges validation */ else if(!is_sroot(source_snid) && !is_master(source_snid, sgid)) send_lang(u, s, NOT_MASTER_OF_X, gname); else if(!is_member_of(snid, sgid)) send_lang(u, s, NICK_X_NOT_ON_GROUP_X, nick, gname); /* execute operation */ else if(del_from_group(sgid, snid) > 0) /* report operation status */ { IRC_User *user = irc_FindUser(nick); send_lang(u, s, NICK_DEL_X_X, nick, gname); if(user) array_del_int(user->extra[ED_GROUPS], sgid); } else send_lang(u, s, UPDATE_FAIL); } else if(strcasecmp(cmd,"INFO") == 0) { /* syntax validation */ if(IsNull(gname)) send_lang(u, s, NS_GROUP_INFO_SYNTAX); /* check requirements */ else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); /* check privileges */ else if(!is_master(source_snid, sgid) && !is_member_of(source_snid, sgid)) send_lang(u, s, NOT_MASTER_OR_MEMBER_X, gname); else if((sgid = find_group(gname))) /* we need to get the group description */ { /* execute operation */ MYSQL_RES* res; master_sgid = 0; sql_singlequery("SELECT gdesc, master_sgid FROM ns_group WHERE sgid=%d", sgid); send_lang(u, s, NS_GROUP_INFO_X, gname); if(sql_field(0)) send_lang(u, s, NS_GROUP_INFO_DESC_X, sql_field(0)); master_sgid = sql_field_i(1); if(master_sgid != 0) { if(sql_singlequery("SELECT name FROM ns_group WHERE sgid=%d", master_sgid) > 0) { send_lang(u, s, NS_GROUP_INFO_MASTER_X, sql_field(0)); } } res = sql_query("SELECT n.nick, gm.t_expire FROM " "nickserv n, ns_group_users gm WHERE gm.sgid=%d AND n.snid=gm.snid", sgid); if(sql_next_row(res) == NULL) send_lang(u, s, NS_GROUP_EMPTY); else { do { char buf[64]; struct tm *tm; time_t t_expire = sql_field_i(1); buf[0] = '\0'; if(t_expire) { tm = localtime(&t_expire); strftime(buf, sizeof(buf), format_str(u, DATE_FORMAT), tm); send_lang(u,s, NS_GROUP_ITEM_X_X, sql_field(0), buf); } else send_lang(u,s, NS_GROUP_ITEM_X, sql_field(0)); ++memberc; } while(sql_next_row(res)); send_lang(u, s, NS_GROUP_MEMBERS_TAIL_X, memberc); } sql_free(res); } } else if(strcasecmp(cmd,"DROP") == 0) { /* syntax validation */ if(IsNull(gname)) send_lang(u, s, NS_GROUP_DROP_SYNTAX); /* privileges validation */ else if(!is_sroot(source_snid)) send_lang(u, s, NICK_NOT_ROOT); /* check requirements */ else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); /* NOTE: The following sql_field( depends on previous find_group( */ else if(!sql_field(2) || (master_sgid = atoi(sql_field(2))) == 0) send_lang(u, s, CANT_DROP_ROOT); /* execute operation */ else if(drop_group(sgid)>0) /* report operation status */ send_lang(u, s, NS_GROUP_DROPPED_X, gname); else send_lang(u, s, UPDATE_FAIL); } else if(strcasecmp(cmd,"LIST") == 0) /* List groups */ { MYSQL_RES* res; MYSQL_ROW row; /* privileges validation */ if(!is_sroot(source_snid)) send_lang(u, s, NICK_NOT_ROOT); else { res = sql_query("SELECT name, master_sgid, gdesc FROM ns_group"); send_lang(u, s, NS_GROUP_LIST_HEADER); while((row = sql_next_row(res))) { char* mname = ""; if(row[1] && sql_singlequery("SELECT name FROM ns_group WHERE sgid=%d", atoi(row[1])) > 0) mname = sql_field(0); send_lang(u, s, NS_GROUP_LIST_X_X_X, row[0], mname, row[2] ? row[2] : ""); } send_lang(u, s, NS_GROUP_LIST_TAIL); sql_free(res); } } else if(strcasecmp(cmd,"SHOW") == 0) /* Show groups we belong to */ { /* groups count */ int gc = array_count(u->extra[ED_GROUPS]); if(gc == 0) send_lang(u, s, NO_GROUPS); else { MYSQL_RES *res; MYSQL_ROW row; char buf[64]; struct tm *tm; time_t t_expire; #if 0 int i; u_int32_t* data = array_data_int(u->extra[ED_GROUPS]); #endif send_lang(u, s, NS_GROUP_SHOW_HEADER); #if 0 for(i = 0; i < gc; ++i) { if(sql_singlequery("SELECT name,gdesc FROM ns_group WHERE sgid=%d", data[i]) > 0 ) send_lang(u, s, NS_GROUP_SHOW_X_X, sql_field(0), sql_field(1) ? sql_field(1) : ""); } #endif res = sql_query("SELECT g.name, g.gdesc, gu.t_expire FROM ns_group g, ns_group_users gu" " WHERE gu.snid=%d AND g.sgid=gu.sgid ORDER BY g.master_sgid", source_snid); while((row = sql_next_row(res))) { t_expire = sql_field_i(2); buf[0] = '\0'; if(t_expire) { tm = localtime(&t_expire); strftime(buf, sizeof(buf), format_str(u, DATE_FORMAT), tm); send_lang(u,s, NS_GROUP_SHOW_X_X_X, row[0], row[1] ? row[1] : "", buf); } else send_lang(u, s, NS_GROUP_SHOW_X_X, row[0], row[1] ? row[1] : ""); } send_lang(u, s, NS_GROUP_SHOW_TAIL); sql_free(res); } } else if(strcasecmp(cmd,"SET") == 0) { char *option; char *value ; option = strtok(NULL, " "); value = strtok(NULL, " "); /* syntax validation */ if(IsNull(gname) || IsNull(option)) send_lang(u, s, NS_GROUP_SET_SYNTAX); /* privileges validation */ else if(!is_sroot(source_snid)) send_lang(u, s, NICK_NOT_ROOT); /* check requirements */ else if((sgid = find_group(gname)) == 0) send_lang(u, s, NO_SUCH_GROUP_X, gname); else { if(strcasecmp(option,"AUTOMODES") == 0) STRING_SET("autoumodes", AUTOMODES_X_UNSET, AUTOMODES_X_CHANGED_TO_X) else if(strcasecmp(option,"DESC") == 0) STRING_SET("gdesc", DESC_X_UNSET, DESC_X_CHANGED_TO_X) else if(strcasecmp(option, "MAXUSERS") == 0) INT_SET("maxusers", NS_GROUP_SET_MAXUSERS_SET_X_X) else send_lang(u, s, SET_INVALID_OPTION_X, option); } }
/* reads the blocks section of the dxf file */ static void read_section_blocks_dxf(FILE *filedxf, DxfData *data, DiagramData *dia) { int group_items = 0, group = 0; GList *group_list = NULL; DiaObject *obj = NULL; Layer *group_layer = NULL; if (read_dxf_codes(filedxf, data) == FALSE){ return; } do { if((data->code == 0) && (strcmp(data->value, "LINE") == 0)) { obj = read_entity_line_dxf(filedxf, data, dia); } else if((data->code == 0) && (strcmp(data->value, "SOLID") == 0)) { obj = read_entity_solid_dxf(filedxf, data, dia); } else if((data->code == 0) && (strcmp(data->value, "VERTEX") == 0)) { read_entity_line_dxf(filedxf, data, dia); } else if((data->code == 0) && (strcmp(data->value, "POLYLINE") == 0)) { obj = read_entity_polyline_dxf(filedxf, data, dia); } else if((data->code == 0) && (strcmp(data->value, "CIRCLE") == 0)) { obj = read_entity_circle_dxf(filedxf, data, dia); } else if((data->code == 0) && (strcmp(data->value, "ELLIPSE") == 0)) { obj = read_entity_ellipse_dxf(filedxf, data, dia); } else if((data->code == 0) && (strcmp(data->value, "TEXT") == 0)) { obj = read_entity_text_dxf(filedxf, data, dia); } else if((data->code == 0) && (strcmp(data->value, "ARC") == 0)) { obj = read_entity_arc_dxf(filedxf,data,dia); } else if((data->code == 0) && (strcmp(data->value, "BLOCK") == 0)) { /* printf("Begin group\n" ); */ group = TRUE; group_items = 0; group_list = NULL; group_layer = NULL; do { if(read_dxf_codes(filedxf, data) == FALSE) return; if(data->code == 8) { group_layer = layer_find_by_name( data->value, dia ); data_set_active_layer (dia, group_layer); } } while(data->code != 0); } else if((data->code == 0) && (strcmp(data->value, "ENDBLK") == 0)) { /* printf( "End group %d\n", group_items ); */ if( group && group_items > 0 && group_list != NULL ) { obj = group_create( group_list ); if( NULL == group_layer ) layer_add_object( dia->active_layer, obj ); else layer_add_object( group_layer, obj ); } group = FALSE; group_items = 0; group_list = NULL; obj = NULL; if(read_dxf_codes(filedxf, data) == FALSE) return; } else { if(read_dxf_codes(filedxf, data) == FALSE) { return; } } if( group && obj != NULL ) { group_items++; group_list = g_list_prepend( group_list, obj ); obj = NULL; } } while((data->code != 0) || (strcmp(data->value, "ENDSEC") != 0)); }