/** * Create a new mtree that is a copy of a ttree * * @param[in] t pointer to source ttree * @returns handle to mtree */ H _m_new_from_t(T *t) { H h = null_H; h = __mnft(h,t); h.a.l = 0; h.a.i = 0; return h; }
// helper function to recursively travers a ttree and build an mtree out of it // used by _m_new_from_t H __mnft(H parent,T *t) { int i, c = _t_children(t); H h = _m_new(parent,_t_symbol(t),_t_surface(t),_t_size(t)); for(i=1;i<=c;i++) { __mnft(h,_t_child(t,i)); } return h; }
// helper function to recursively traverse a ttree and build an mtree out of it // used by _m_new_from_t H __mnft(H parent,T *t) { int i, c = _t_children(t); // clear the allocated flag, because that will get recalculated in __m_new uint32_t flags = t->context.flags & ~TFLAG_ALLOCATED; // if the ttree points to a type that has an allocated c structure as its surface // it must be copied into the mtree as reference, otherwise it would get freed twice // when the mtree is freed if (flags & (TFLAG_SURFACE_IS_RECEPTOR+TFLAG_SURFACE_IS_SCAPE+TFLAG_SURFACE_IS_STREAM)) flags |= TFLAG_REFERENCE; void *surface = _t_surface(t); void *sp; H h; if (flags & TFLAG_SURFACE_IS_TREE && !(flags & TFLAG_SURFACE_IS_RECEPTOR)) { H sh = _m_new_from_t((T *)surface); h = _m_newt(parent,_t_symbol(t),sh); } else { if (flags & (TFLAG_SURFACE_IS_RECEPTOR+TFLAG_SURFACE_IS_SCAPE+TFLAG_SURFACE_IS_STREAM)) { sp = surface; surface = &sp; } h = __m_new(parent,_t_symbol(t),surface,_t_size(t),flags); } if (flags&TFLAG_RUN_NODE) { // @todo, make this more efficient, ie we shouldn't have to // do an _m_get, instead there should be a way for mtrees to create run_nodes N *n = __m_get(h); n->cur_child = ((rT *)t)->cur_child; } for(i=1;i<=c;i++) { __mnft(h,_t_child(t,i)); } return h; }