void ast_replace(ast_t** prev, ast_t* next) { if(*prev == next) return; if(hasparent(next)) next = ast_dup(next); if(hasparent(*prev)) ast_swap(*prev, next); ast_free(*prev); *prev = next; }
void ast_consolidate_branches(ast_t* ast, size_t count) { assert(hasparent(ast)); size_t i = HASHMAP_BEGIN; symbol_t* sym; while((sym = symtab_next(ast->symtab, &i)) != NULL) { sym_status_t status; ast_get(ast->parent, sym->name, &status); if(sym->status == SYM_UNDEFINED) { assert(sym->branch_count <= count); if((status == SYM_DEFINED) || (sym->branch_count == count)) { // If we see it as defined from a parent scope, always end up defined. // If we it's defined in all the branched, it's also defined. sym->status = SYM_DEFINED; } else { // It wasn't defined in all branches. Stay undefined. sym->branch_count = 0; } } } }
void ast_swap(ast_t* prev, ast_t* next) { assert(prev != NULL); assert(prev != next); ast_t* parent = ast_parent(prev); assert(parent != NULL); if(hasparent(next)) next = ast_dup(next); set_scope_and_parent(next, parent); if(parent->type == prev) { parent->type = next; } else { ast_t* last = ast_previous(prev); if(last != NULL) last->sibling = next; else parent->child = next; next->sibling = prev->sibling; } prev->sibling = NULL; make_orphan_leave_scope(prev); }
ast_t* ast_append(ast_t* parent, ast_t* child) { assert(parent != NULL); assert(child != NULL); assert(parent != child); if(hasparent(child)) child = ast_dup(child); set_scope_and_parent(child, parent); if(parent->child == NULL) { parent->child = child; return child; } ast_t* ast = parent->child; while(ast->sibling != NULL) ast = ast->sibling; ast->sibling = child; return child; }
/* * Cross-check the configuration: make sure that each target device * or attribute (`at foo[0*?]') names at least one real device. Also * see that the root, swap, and dump devices for all configurations * are there. */ int crosscheck(void) { struct devi *i; struct config *cf; int errs; errs = 0; for (i = alldevi; i != NULL; i = i->i_next) { if (i->i_at == NULL || hasparent(i)) continue; xerror(conffile, i->i_lineno, "%s at %s is orphaned", i->i_name, i->i_at); (void)fprintf(stderr, " (%s %s declared)\n", i->i_atunit == WILD ? "nothing matching" : "no", i->i_at); errs++; } if (allcf == NULL) { (void)fprintf(stderr, "%s has no configurations!\n", conffile); errs++; } for (cf = allcf; cf != NULL; cf = cf->cf_next) { if (cf->cf_root != NULL) { /* i.e., not swap generic */ errs += cfcrosscheck(cf, "root", cf->cf_root); errs += cfcrosscheck(cf, "swap", cf->cf_swap); errs += cfcrosscheck(cf, "dumps", cf->cf_dump); } } return (errs); }
ast_t* ast_add_sibling(ast_t* older_sibling, ast_t* new_sibling) { assert(older_sibling != NULL); assert(new_sibling != NULL); assert(older_sibling != new_sibling); assert(hasparent(older_sibling)); if(hasparent(new_sibling)) new_sibling = ast_dup(new_sibling); assert(new_sibling->sibling == NULL); set_scope_and_parent(new_sibling, older_sibling->parent); new_sibling->sibling = older_sibling->sibling; older_sibling->sibling = new_sibling; return new_sibling; }
ast_t* ast_add(ast_t* parent, ast_t* child) { assert(parent != NULL); assert(parent != child); assert(parent->child != child); if(hasparent(child)) child = ast_dup(child); set_scope_and_parent(child, parent); child->sibling = parent->child; parent->child = child; return child; }
size_t ast_index(ast_t* ast) { assert(ast != NULL); assert(hasparent(ast)); ast_t* child = ast->parent->child; size_t idx = 0; while(child != ast) { child = child->sibling; idx++; } return idx; }
ast_t* ast_previous(ast_t* ast) { assert(ast != NULL); assert(hasparent(ast)); ast_t* last = NULL; ast_t* cur = ast->parent->child; while(cur != ast) { last = cur; cur = cur->sibling; } return last; }
void ast_remove(ast_t* ast) { assert(ast != NULL); assert(hasparent(ast)); ast_t* last = ast_previous(ast); if(last != NULL) last->sibling = ast->sibling; else ast->parent->child = ast->sibling; ast->parent = NULL; ast->sibling = NULL; ast_free(ast); }
void ast_settype(ast_t* ast, ast_t* type) { assert(ast != NULL); if(ast->type == type) return; ast_free(ast->type); if(type != NULL) { if(hasparent(type)) type = duplicate(ast, type); set_scope_and_parent(type, ast); } ast->type = type; }
void ast_free_unattached(ast_t* ast) { if((ast != NULL) && !hasparent(ast)) ast_free(ast); }