Index: trunk/src/libcschem/abstract.c =================================================================== --- trunk/src/libcschem/abstract.c (revision 10094) +++ trunk/src/libcschem/abstract.c (revision 10095) @@ -33,6 +33,8 @@ #include #include +#include "hierarchy.h" + #include "abstract.h" static const char *atype_names[] = { @@ -100,6 +102,7 @@ htsp_init(&abs->nets, strhash, strkeyeq); htsp_init(&abs->comps, strhash, strkeyeq); htip_init(&abs->aid2obj, longhash, longkeyeq); + abs->hroot = csch_hlevel_new(NULL); abs->next_aid = 1; } @@ -107,6 +110,8 @@ { htsp_entry_t *e; + csch_hlevel_free_tree(abs->hroot); + for(e = htsp_first(&abs->nets); e != NULL; e = htsp_next(&abs->nets, e)) { csch_anet_free_fields(e->value); free(e->value); e->value = NULL; @@ -120,6 +125,7 @@ htsp_uninit(&abs->nets); htsp_uninit(&abs->comps); htip_uninit(&abs->aid2obj); + memset(abs, 0, sizeof(csch_abstract_t)); } Index: trunk/src/libcschem/abstract.h =================================================================== --- trunk/src/libcschem/abstract.h (revision 10094) +++ trunk/src/libcschem/abstract.h (revision 10095) @@ -48,7 +48,7 @@ htsp_t nets; /* local netname -> csch_anet_t */ htsp_t comps; /* local name -> csch_acomp_t */ - unsigned root:1; /* set to 1 when this hlevel is the root */ + csch_hlevel_t *parent; /* NULL in root */ gdl_elem_t link; /* doubly linked list of siblings; not used in root */ gdl_list_t children; /* of (csch_hlevel_t *) */ }; @@ -123,12 +123,15 @@ vtp0_t conns; /* a list of (csch_ahdr_t *) connections, ports and bus-ports */ char *name; /* global unique name for the hash (flat model); includes hierarchic path of some sort */ char *locname;/* local name within the hierarchic level (doesn't include hierarchic path) */ - csch_ascope_t scope; + /* hierarchy */ + csch_ascope_t scope; /* coming from name prefix */ + csch_hlevel_t *hlev; /* subtree the net is in */ + + unsigned no_uname:1; /* 1 if there is no user assigned net name */ unsigned term_term:1; /* the net was created for a "hidden" terminal-terminal connection */ long hdepth; /* how deep the net is in the hierarchy; 0 means it's on a root sheet */ - csch_acomp_t *hparent;/* hierarchy: sheet ref symbol in the parent sheet that created the sheet this object is picked up from; NULL means object from root sheet */ /* cached from attributes: */ const char *chan; @@ -181,8 +184,11 @@ csch_ahdr_t hdr; char *name; /* global unique name for the hash (flat model); includes hierarchic path of some sort */ char *locname; /* local name within the hierarchic level (doesn't include hierarchic path) */ - csch_ascope_t scope; + /* hierarchy */ + csch_ascope_t scope; /* coming from name prefix */ + csch_hlevel_t *hlev; /* subtree the component is in */ + htsp_t ports; /* of csch_aport_t, key is ->name */ htsp_t busports; /* of csch_abusport_t, key is ->name */ Index: trunk/src/libcschem/compile.c =================================================================== --- trunk/src/libcschem/compile.c (revision 10094) +++ trunk/src/libcschem/compile.c (revision 10095) @@ -190,7 +190,7 @@ return -1; } - net = csch_anet_get_at(dst, hpath, scope, name_loc); + net = csch_anet_get_at(dst, hpath->hlev, scope, name_loc); if (net == NULL) { net = csch_anet_new(dst, name_glob, no_uname); if (net == NULL) @@ -197,8 +197,7 @@ return -1; } - net->hdepth = hpath->path.used; - net->hparent = csch_hier_get_hparent(hpath); + net->hdepth = hpath->hdepth; csch_compile_add_source(src, &net->hdr); return compile_attributes(&net->hdr, &src->attr, src, "net", orig_name, 0); @@ -572,8 +571,8 @@ return -1; } net->term_term = 1; - net->hdepth = hpath->path.used; - net->hparent = csch_hier_get_hparent(hpath); /* even tho it won't be referenced... */ + net->hdepth = hpath->hdepth; + net->hlev = hpath->hlev; /* even tho it won't be referenced because it's a globally unique name... */ } /* second pass: make the connections */ Index: trunk/src/libcschem/hierarchy.c =================================================================== --- trunk/src/libcschem/hierarchy.c (revision 10094) +++ trunk/src/libcschem/hierarchy.c (revision 10095) @@ -29,6 +29,7 @@ #include "config.h" #include +#include #include "concrete.h" #include "cnc_grp.h" @@ -159,13 +160,41 @@ void csch_hier_path_free(csch_hier_path_t *hpath) { - vtp0_uninit(&hpath->path); + gds_uninit(&hpath->prefix); + hpath->hlev = NULL; + hpath->hdepth = -1; } +csch_hlevel_t *csch_hlevel_new(csch_hlevel_t *parent) +{ + csch_hlevel_t *hlev = calloc(sizeof(csch_hlevel_t), 1); + if (parent != NULL) { + hlev->parent = parent; + gdl_append(&parent->children, hlev, link); + } + htsp_init(&hlev->nets, strhash, strkeyeq); + htsp_init(&hlev->comps, strhash, strkeyeq); + return hlev; +} + + +void csch_hlevel_free_tree(csch_hlevel_t *hlev) +{ + csch_hlevel_t *f; + for(f = gdl_first(&hlev->children); f != NULL; f = gdl_first(&hlev->children)) { + gdl_remove(&hlev->children, f, link); + csch_hlevel_free_tree(f); + } + htsp_uninit(&hlev->nets); + htsp_uninit(&hlev->comps); + free(f); +} + + int csch_hier_enter(csch_hier_path_t *hpath, csch_hier_temp_t *tmp, csch_cgrp_t *sym, const char *name) { - if (hpath->path.used > MAX_DEPTH) { - rnd_message(RND_MSG_ERROR, "Hierarchy recursion too deep (%ld)\n(The hierarchy graph shall not contain loops)\n", hpath->path.used); + if (hpath->hdepth > MAX_DEPTH) { + rnd_message(RND_MSG_ERROR, "Hierarchy recursion too deep (%ld)\n(The hierarchy graph shall not contain loops)\n", hpath->hdepth); return -1; } @@ -178,8 +207,10 @@ gds_append_str(&hpath->prefix, name); gds_append(&hpath->prefix, HSEP); /* rnd_trace("HIER: enter [%d '%s']\n", hpath->path.used+1, hpath->prefix.array);*/ - vtp0_append(&hpath->path, sym); + hpath->hlev = csch_hlevel_new(hpath->hlev); + hpath->hdepth++; + return 0; } @@ -186,16 +217,10 @@ void csch_hier_leave(csch_hier_path_t *hpath, csch_hier_temp_t *tmp) { /* rnd_trace("HIER: leave [%d '%s']\n", hpath->path.used, hpath->prefix.array);*/ - hpath->path.used--; + hpath->hlev = hpath->hlev->parent; + hpath->hdepth--; hpath->prefix.used = tmp->prefix_len; hpath->prefix.array[hpath->prefix.used] = '\0'; - assert(hpath->path.used >= 0); + assert(hpath->hdepth >= 0); } -csch_acomp_t *csch_hier_get_hparent(csch_hier_path_t *hpath) -{ - if (hpath->path.used == 0) - return NULL; - - return hpath->path.array[hpath->path.used-1]; -} Index: trunk/src/libcschem/hierarchy.h =================================================================== --- trunk/src/libcschem/hierarchy.h (revision 10094) +++ trunk/src/libcschem/hierarchy.h (revision 10095) @@ -35,8 +35,9 @@ /* describes the current path while descending a hierarchic design */ typedef struct csch_hier_path_s { - vtp0_t path; /* each element is a (*sch_cgrp_t) or (*sch_cgrp_ref_t) describing the path; root sheet is the first group's sheet */ - gds_t prefix; /* path prefix string */ + gds_t prefix; /* path prefix string (cache) */ + csch_hlevel_t *hlev; /* subtree we are in at the moment */ + long hdepth; } csch_hier_path_t; /* used for enter/leave to store some temporary data on the caller's stack; @@ -57,9 +58,8 @@ int csch_hier_enter(csch_hier_path_t *hpath, csch_hier_temp_t *tmp, csch_cgrp_t *sym, const char *name); void csch_hier_leave(csch_hier_path_t *hpath, csch_hier_temp_t *tmp); +csch_hlevel_t *csch_hlevel_new(csch_hlevel_t *parent); +void csch_hlevel_free_tree(csch_hlevel_t *hlev); -/* Return the component that was the sheet ref for the subsheet of hpath. - Returns NULL if hpath is root. */ -csch_acomp_t *csch_hier_get_hparent(csch_hier_path_t *hpath); #endif