Index: trunk/src/libcschem/abstract.c =================================================================== --- trunk/src/libcschem/abstract.c (revision 10105) +++ trunk/src/libcschem/abstract.c (revision 10106) @@ -191,10 +191,28 @@ return CSCH_ASCOPE_AUTO; } +/* Search netname locally on hlev then search for v/netname in all hlev + parents. Return NULL if not found. */ +csch_anet_t *search_subtree_up(csch_abstract_t *abs, csch_hlevel_t *hlev, const char *netname) +{ + csch_anet_t *net; + net = htsp_get(&hlev->nets, netname); + if (net != NULL) + return net; + + for(hlev = hlev->parent; hlev != NULL; hlev = hlev->parent) { + net = htsp_get(&hlev->nets, netname); + if (net->scope == CSCH_ASCOPE_SUBTREE_LOCAL) + return net; + } + + return NULL; +} + csch_anet_t *csch_anet_get_at(csch_abstract_t *abs, csch_hlevel_t *hlev, csch_ascope_t scope, const char *netname) { - csch_anet_t *net; + csch_anet_t *net = NULL; csch_ascope_t prefix_scope; const char *orig_name = netname; @@ -211,19 +229,29 @@ switch(scope) { case CSCH_ASCOPE_AUTO: -TODO("hierarchy: implement me; at the moment we fall back to global for compatibility"); + /* first search on sheet local and parents for v/ nets */ + if (hlev != NULL) { + net = search_subtree_up(abs, hlev, netname); + if (net != NULL) + return net; + } + return htsp_get(&abs->nets, netname); /* fall back to global */ + case CSCH_ASCOPE_GLOBAL: return htsp_get(&abs->nets, netname); case CSCH_ASCOPE_SHEET_LOCAL: return htsp_get(&hlev->nets, netname); case CSCH_ASCOPE_SUBTREE_LOCAL: + /* search in sheet only so that multuple v/foo are merged together; + sub-sheets are compiled later so they can find this net searching upward */ + return htsp_get(&hlev->nets, netname); + case CSCH_ASCOPE_SUBTREE_AUTO: if (hlev == NULL) { rnd_message(RND_MSG_ERROR, "Failed to resolve net '%s': scope requires hierarchy which is not available\n", orig_name); return NULL; } + /* search on sheet local and parents for v/ nets */ + return search_subtree_up(abs, hlev, netname); - rnd_message(RND_MSG_ERROR, "TODO: scope resolver not yet implemented for '%s'\n", orig_name); - return NULL; - case CSCH_ASCOPE_unknown: rnd_message(RND_MSG_ERROR, "Failed to resolve net '%s': unknown scope\n", orig_name); return NULL; @@ -260,6 +288,7 @@ break; } } + net->scope = scope; return net; }