/* * Asserts that a tree is valid, and returns the size of the tree. */ static int checktree(treenode_t *n, cmpfunc_t cmp) { if (n == nullNode) { return 0; } else { checknode(n, cmp); return 1 + checktree(n->left, cmp) + checktree(n->right, cmp); } }
static void addtree(int ind) { int loc, ptemp; int indp, indc; char ch; count++; *(r+count)=ind; *(p+ind)=count; if( count > 1 ) { loc=count; indc=*(r+loc); indp=*(r+loc/2); ch=( (*(t0+indc)) < (*(t0+indp)) ) ? 'y' : 'n'; while( ch == 'y' ) { ptemp=*(p+indc); *(p+indc)=*(p+indp); *(r+loc/2)=indc; *(p+indp)=ptemp; *(r+loc)=indp; loc=loc/2; if( loc > 1 ) { indc=*(r+loc); indp=*(r+loc/2); ch=( (*(t0+indc)) < (*(t0+indp)) ) ? 'y' : 'n'; } else ch='n'; } } checktree(ind,"Error is detected in addtree "); }
int setname (lua_State *L) { TreeNode *node = checktree(L, 1); const char *name = luaL_checkstring(L, 2); luaL_argcheck(L, name != NULL, 2, "'treenode' name shouldn't be empty"); node->name = assignNewString(node->name, name); return 0; }
int getnodes (lua_State *L) { TreeNode *node = checktree(L, 1); node->children_iter = 0; /* creates and returns the iterator function (its sole upvalue, the directory userdatum, is already on the stack top */ lua_pushcclosure(L, node_iter, 1); return 1; }
int addnode (lua_State *L) { TreeNode *node = checktree(L, 1); TreeNode *new_node = checktree(L, 2); luaL_argcheck(L, new_node->parent == NULL, 2, "new 'treenode' should not have parent"); lua_pushvalue(L, 2); /* put new_node userdata on the stack top */ if (node->children_count == 0) { node->udreflist = (int *)malloc(sizeof(int)); node->children = (TreeNode **)malloc(sizeof(TreeNode*)); node->children[0] = new_node; node->children_count = 1; new_node->parent = node; //register lua reference to TreeNode userdata node->udreflist[0] = luaL_ref(L, LUA_REGISTRYINDEX); } else { int i; bool tamped = false; for (i = 0; i < node->children_count; ++i) { if (node->children[i] == NULL) { node->children[i] = new_node; //register lua reference to TreeNode userdata node->udreflist[i] = luaL_ref(L, LUA_REGISTRYINDEX); tamped = true; break; } } if (!tamped) { // there is no place to put another node. Create new space then node->children_count++; node->children = (TreeNode **)realloc(node->children, node->children_count*sizeof(TreeNode*)); node->children[node->children_count-1] = new_node; node->udreflist = (int *)realloc(node->udreflist, node->children_count*sizeof(int)); //register lua reference to TreeNode userdata node->udreflist[node->children_count-1] = luaL_ref(L, LUA_REGISTRYINDEX); } new_node->parent = node; } return 0; }
int rmnode (lua_State *L) { TreeNode *node = checktree(L, 1); TreeNode *parent = node->parent; int i; char uuid_str[40]; uuid_to_string(&node->uuid, uuid_str); printd("Removing node with uuid %s\n", uuid_str); if (parent != NULL) { uuid_to_string(&parent->uuid, uuid_str); printd("Node has parent with uuid %s. Remove reference from parent's children list.\n", uuid_str); for (i = 0; i < parent->children_count; ++i) { if (parent->children != NULL && parent->children[i] != NULL && 0 == custom_uuid_compare(node->uuid, parent->children[i]->uuid)) { parent->children[i] = NULL; /* free (unref) userdata in parent node */ luaL_unref(L, LUA_REGISTRYINDEX, parent->udreflist[i]); parent->udreflist[i] = LUA_REFNIL; } } } // free node strucrure /* free (unref) userdata in current node */ for (i = 0; i < node->children_count; ++i) { if (node->udreflist != NULL && node->udreflist[i] != LUA_REFNIL) { luaL_unref(L, LUA_REGISTRYINDEX, node->udreflist[i]); node->udreflist[i] = LUA_REFNIL; node->children[i]->parent = NULL; } } if (node->dataType == LUA_TSTRING) free(node->data.charVal); if (node->name) free(node->name); if (node->children) free(node->children); if (node->udreflist) free(node->udreflist); node->udreflist = NULL; node->children = NULL; node->parent = NULL; node->name = NULL; return 0; }
int getvalue (lua_State *L) { TreeNode *node = checktree(L, 1); switch (node->dataType) { case LUA_TNIL: lua_pushnil(L); break; case LUA_TNUMBER: lua_pushnumber(L, node->data.numberVal); break; case LUA_TBOOLEAN: lua_pushboolean(L, node->data.boolVal); break; case LUA_TSTRING: lua_pushstring(L, node->data.charVal); break; } return 1; }
int treenode2string (lua_State *L) { TreeNode *node = checktree(L, 1); switch (node->dataType) { case LUA_TNIL: lua_pushfstring(L, "treenode: name = '%s'; value = 'NIL'", node->name); break; case LUA_TNUMBER: lua_pushfstring(L, "treenode: name = '%s'; value = '%f'", node->name, node->data.numberVal); break; case LUA_TBOOLEAN: lua_pushfstring(L, "treenode: name = '%s'; value = '%d'", node->name, node->data.boolVal); break; case LUA_TSTRING: lua_pushfstring(L, "treenode: name = '%s'; value = '%s'", node->name, node->data.charVal); break; } return 1; }
int setvalue (lua_State *L) { TreeNode *node = checktree(L, 1); int valueType = lua_type(L, 2); if (valueType != LUA_TNIL && valueType != LUA_TNUMBER && valueType != LUA_TBOOLEAN && valueType != LUA_TSTRING) { lua_pushstring(L, "incorrect value. supported types are int, float, boolean, string"); lua_error(L); } if (valueType != LUA_TSTRING && node->dataType == LUA_TSTRING) free(node->data.charVal); switch (valueType) { case LUA_TNIL: node->dataType = LUA_TNIL; break; case LUA_TNUMBER: node->data.numberVal = lua_tonumber(L,2); node->dataType = LUA_TNUMBER; break; case LUA_TBOOLEAN: node->data.boolVal = lua_toboolean(L,2); node->dataType = LUA_TBOOLEAN; break; case LUA_TSTRING: if (node->dataType == LUA_TSTRING) node->data.charVal = assignNewString(node->data.charVal, lua_tostring(L,2)); else node->data.charVal = strdup(lua_tostring(L,2)); node->dataType = LUA_TSTRING; break; } return 0; }
/* deletes root of the binary tree */ static void deltree(void) { int loc, ptemp, ind, lcc, ic=0, ic1=0, ic2=0, mind; char chd, ch='n';; mind=*(r+1); /* if( mind==53619 ) { printf("Deleting root with index %i\n",mind); ch='y'; } */ *(p+(*(r+1)))=0; *(r+1)=*(r+count); *(p+(*(r+1)))=1; count--; loc=1; ind=*(r+1); lcc=2*loc; if(ch=='y') printf("parent: loc(%i)=%i, t=%.16e\n",ind,loc,*(t0+ind)); if( lcc < count ) { ic1=*(r+lcc); ic2=*(r+lcc+1); if(ch=='y') printf("children: loc(%i)=%i, loc(%i)=%i,t1=%.16e, t2=%.16e\n", ic1,lcc,ic2,lcc+1,*(t0+ic1),*(t0+ic2)); if( (*(t0+ind)) > (*(t0+ic1)) || (*(t0+ind)) > (*(t0+ic2)) ) { if( (*(t0+ic1)) <= (*(t0+ic2)) ) { chd='l'; ic=ic1; if(ch=='y') printf("left\n"); } else { chd='r'; ic=ic2; lcc++; if(ch=='y') printf("right\n"); } } else chd='n'; } else if( lcc == count ) { ic=*(r+lcc); if( (*(t0+ind)) > (*(t0+ic)) ) {chd='l';} else chd='n'; } else chd='n'; while( chd != 'n' ) { ptemp=*(p+ind); *(p+ind)=*(p+ic); *(r+loc)=ic; *(p+ic)=ptemp; *(r+lcc)=ind; loc=lcc; lcc=2*loc; if(ch=='y') printf("parent: loc(%i)=%i, t=%.16e\n",ind,loc,*(t0+ind)); if( lcc < count ) { ic1=*(r+lcc); ic2=*(r+lcc+1); if(ch=='y') printf("children: loc(%i)=%i, loc(%i)=%i,t1=%.16e, t2=%.16e\n", ic1,lcc,ic2,lcc+1,*(t0+ic1),*(t0+ic2)); if( (*(t0+ind)) > (*(t0+ic1)) || (*(t0+ind)) > (*(t0+ic2)) ) { if( (*(t0+ic1)) <= (*(t0+ic2)) ) { chd='l'; ic=ic1; if(ch=='y') printf("left\n"); } else { chd='r'; ic=ic2; lcc++; if(ch=='y') printf("right\n"); } } else chd='n'; } else if( lcc == count ) { ic=*(r+lcc); if( (*(t0+ind)) > (*(t0+ic)) ) { chd='l';if(ch=='y') printf("left\n");} else chd='n'; } else chd='n'; } /* end while( chd != 'n' ) */ checktree(mind,"Error is detected in deltree "); }
static void updtree(int mind) { int loc, lcc, indc, indp,ind, ic=0, ptemp, ic1=0, ic2=0; char chu,chd; loc=*(p+mind); indc=*(r+loc); indp=*(r+loc/2); chu=( (loc > 1) && ((*(t0+indc)) < (*(t0+indp))) ) ? 'y' : 'n'; ind=indc; lcc=2*loc; if( lcc < count ) { ic1=*(r+lcc); ic2=*(r+lcc+1); if( (*(t0+ind)) > (*(t0+ic1)) || (*(t0+ind)) > (*(t0+ic2)) ) { if( (*(t0+ic1)) <= (*(t0+ic2)) ) { chd='l'; ic=ic1; } else { chd='r'; ic=ic2; lcc+=1; } } else chd='n'; } else if( lcc == count ) { ic=*(r+lcc); if( (*(t0+ind)) > (*(t0+ic)) ) { chd='l';} else chd='n'; } else chd='n'; if( chu == 'y' && chd != 'n' ) { sf_warning("error detected by updtree, (%i, %i)",mind%nx,mind/nx); sf_warning("mind=%i, indc=%i, indp=%i, count=%i, loc=%i, lcc=%i", mind,indc,indp,count,loc,lcc); sf_error("t=%.4e, tp=%.4e, tcl=%.4e, tcr=%.4e, chu=%c, chd=%c", *(t0+mind),*(t0+indp),*(t0+ic1),*(t0+ic2),chu,chd); } while( chu == 'y' ) { ptemp=*(p+indc); *(p+indc)=*(p+indp); *(r+loc/2)=indc; *(p+indp)=ptemp; *(r+loc)=indp; loc=loc/2; if( loc > 1 ) { indc=*(r+loc); indp=*(r+loc/2); chu=( (*(t0+indc)) < (*(t0+indp)) ) ? 'y' : 'n'; } else chu='n'; } /*end while( chu == 'y' ) */ while( chd != 'n' ) { ptemp=*(p+ind); *(p+ind)=*(p+ic); *(r+loc)=ic; *(p+ic)=ptemp; *(r+lcc)=ind; loc=lcc; lcc=2*loc; if( lcc < count ) { ic1=*(r+lcc); ic2=*(r+lcc+1); if( (*(t0+ind)) > (*(t0+ic1)) || (*(t0+ind)) > (*(t0+ic2)) ) { if( (*(t0+ic1)) <= (*(t0+ic2)) ) { chd='l'; ic=ic1; } else { chd='r'; ic=ic2; lcc+=1; } } else chd='n'; } else if( lcc == count ) { ic=*(r+lcc); if( (*(t0+ind)) > (*(t0+ic)) ) {chd='l';} else chd='n'; } else chd='n'; } /* end while( chd != 'n' ) */ checktree(mind,"Error is detected in updtree "); }
/* * Checks that a set is valid. */ static void checkset(set_t *set) { int size = checktree(set->root, set->cmpfunc); assert(size == set->size); }
int getname (lua_State *L) { TreeNode *node = checktree(L, 1); lua_pushstring(L, node->name); return 1; }