Apresentacao preenche_apresentacao_faturacao_nao_comprados (Travessia t, Apresentacao a, int*filial) { Produto elemento; int fil, i, j, v; if(filial) fil=(*filial)-1; while(1){ elemento = avl_t_next(t); if (elemento==NULL) break; else { if(!filial){ if((elemento->vendas_anual)==0) a = recebe_elemento(elemento->prod,a,strlen(elemento->prod),SEM_ORDENACAO_INT,SEM_ORDENACAO_DOUBLE,SEM_ORDEM,0); } else { v=0; for(i=0;i<N_MESES;i++){ for(j=0;j<N_REGIMES;j++){ v+=elemento->vendas_mes[fil][i][j]; } } if (v==0) a = recebe_elemento(elemento->prod,a,strlen(elemento->prod),SEM_ORDENACAO_INT,SEM_ORDENACAO_DOUBLE,SEM_ORDEM,0); } } } return a; }
void write_enc(char **glyph_names, struct avl_table *tx_tree, integer fe_objnum) { int i_old, *p; struct avl_traverser t; assert(glyph_names != NULL); assert(tx_tree != NULL); assert(fe_objnum != 0); pdf_begin_dict(fe_objnum, 1); pdf_puts("/Type /Encoding\n"); pdf_printf("/Differences ["); avl_t_init(&t, tx_tree); for (i_old = -2, p = (int *) avl_t_first(&t, tx_tree); p != NULL; p = (int *) avl_t_next(&t)) { if (*p == i_old + 1) /* no gap */ pdf_printf("/%s", glyph_names[*p]); else { if (i_old == -2) pdf_printf("%i/%s", *p, glyph_names[*p]); else pdf_printf(" %i/%s", *p, glyph_names[*p]); } i_old = *p; } pdf_puts("]\n"); pdf_end_dict(); }
Apresentacao preenche_apresentacao_top_produtos (Travessia t, Apresentacao a, int N) { ProdutoGestao elemento; int j,v,offset; char s[BUFFER_GRANDE]; while(1){ elemento = avl_t_next(t); if (elemento==NULL) return a; for(j=0,v=0;j<N_FILIAIS;j++){ v += elemento->vendas[j]; } offset = sprintf(s,"Produto %s, participa em %d vendas realizadas por %d clientes diferentes num total de %d unidades\n |",elemento->prod, v, elemento->num_clientes,elemento->quantidade_anual); for(j=0;j<N_FILIAIS;j++){ if(offset>=BUFFER_GRANDE){ printf("Buffer demasiado pequeno.\n"); return NULL; } offset += sprintf(s+offset," Filial %d: Faturou %.2f e Vendeu %d;", j+1, elemento->faturacao[j], elemento->vendas[j]); } offset += sprintf(s+offset,"\n |"); recebe_elemento(s,a,offset,elemento->quantidade_anual,SEM_ORDENACAO_DOUBLE,DESCENDENTE,N); } return a; }
extern "C" void fc_solve_dbm_store_offload_pre_cache( fcs_dbm_store_t store, fcs_pre_cache_t * pre_cache ) { leveldb::DB * db; #ifdef FCS_DBM_USE_LIBAVL struct avl_traverser trav; dict_key_t item; #else dnode_t * node; #endif dict_t * kaz_tree; int num_left_in_transaction = MAX_ITEMS_IN_TRANSACTION; leveldb::WriteBatch batch; fcs_pre_cache_key_val_pair_t * kv; db = (leveldb::DB *)store; kaz_tree = pre_cache->kaz_tree; #ifdef FCS_DBM_USE_LIBAVL avl_t_init(&trav, kaz_tree); #endif #ifdef FCS_DBM_USE_LIBAVL for ( item = avl_t_first(&trav, kaz_tree) ; item ; item = avl_t_next(&trav) ) #else for (node = fc_solve_kaz_tree_first(kaz_tree); node ; node = fc_solve_kaz_tree_next(kaz_tree, node) ) #define item (node->dict_key) #endif { kv = (fcs_pre_cache_key_val_pair_t *)(item); leveldb::Slice key((const char *)(kv->key.s+1),kv->key.s[0]); /* We add 1 to the parent and move's length because it includes the * trailing one-char move. * */ leveldb::Slice parent_and_move((const char *)(kv->parent_and_move.s+1),kv->parent_and_move.s[0]+1); batch.Put(key, parent_and_move); if ((--num_left_in_transaction) <= 0) { #define WRITE() assert(db->Write(leveldb::WriteOptions(), &batch).ok()) WRITE(); batch.Clear(); num_left_in_transaction = MAX_ITEMS_IN_TRANSACTION; } } WRITE(); #undef WRITE }
/*! Checks and asserts that the segment is unique within the AVL tree. Updates above/below pointers of the input seg as well as its new neighbours*/ void logicop::SweepLine::add(plysegment* seg) { avl_traverser trav; void* retitem = avl_t_insert(&trav,_tree,seg); assert(retitem == seg); avl_traverser save_trav = trav; plysegment* nx = (plysegment*)avl_t_next(&save_trav); plysegment* np = (plysegment*)avl_t_prev(&trav); if (NULL != nx) { seg->above = nx; nx->below = seg; } if (NULL != np) { seg->below = np; np->above = seg; } }
void tedop::SweepLine::remove(plysegment* seg) { avl_traverser trav; void* retitem = avl_t_find(&trav,_tree,seg); if (NULL == retitem) return; avl_traverser save_trav = trav; plysegment* nx = (plysegment*)avl_t_next(&save_trav); if (NULL != nx) nx->below = seg->below; plysegment* np = (plysegment*)avl_t_prev(&trav); if (NULL != np) np->above = seg->above; avl_delete(_tree,seg); }
void logicop::EventQueue::swipe4bind(SweepLine& SL, BindCollection& BC) { Event* evt; avl_traverser trav; avl_t_first(&trav,_equeue); while (trav.avl_node != NULL) { evt = (Event*)trav.avl_node->avl_data; SL.set_currentP(evt->evertex()); evt->swipe4bind(SL, BC); avl_t_next(&trav); } }
int hx_idmap_debug ( hx_idmap* map ) { struct avl_traverser iter; avl_t_init( &iter, map->id2string ); hx_idmap_item* item; fprintf( stderr, "Nodemap:\n" ); while ((item = (hx_idmap_item*) avl_t_next( &iter )) != NULL) { char* string = item->string; fprintf( stderr, "\t%"PRIu64" -> %s\n", item->id, string ); } return 0; }
void write_fontencodings() { fe_entry *fe; struct avl_traverser t; if (fe_tree == NULL) return; avl_t_init(&t, fe_tree); for (fe = (fe_entry *) avl_t_first(&t, fe_tree); fe != NULL; fe = (fe_entry *) avl_t_next(&t)) if (fe->fe_objnum != 0) write_fontencoding(fe); }
/*!This method is actually executing Bentley-Ottman algorithm. It traverses the event queue and calls swipe4cross methods of every Event. It should be noted that the _equeue is dynamically updated with the crossing events by the same swipe4cross methods. \n The method is sensible to the updates in the tree in a wierd way. Program will bomb out here if a new event has not been inserted properly. Some kind of try-catch mechanism should be implemented.*/ void logicop::EventQueue::swipe4cross(SweepLine& SL) { // see the comment around find parameter in the E_compare Event* evt; avl_traverser trav; avl_t_first(&trav,_equeue); while (trav.avl_node != NULL) { evt = (Event*)trav.avl_node->avl_data; SL.set_currentP(evt->evertex()); evt->swipe4cross(SL, _equeue); avl_t_next(&trav); } }
void pour_toute_cle_valeur_table( const Table* table, void (* action)( const intptr_t cle, intptr_t valeur, void* data ), void* data ) { struct avl_traverser traverser; void * item; avl_t_init( &traverser, table->root ); while( (item = avl_t_next( &traverser )) ) { Table_association* asso = (Table_association *) item; action( asso->cle, asso->valeur, data ); } }
Apresentacao preenche_apresentacao_clientes_produto (Travessia t, Apresentacao a){ char* elemento; while(1){ elemento = avl_t_next(t); if (elemento==NULL) break; a = recebe_elemento(elemento,a,strlen(elemento),SEM_ORDENACAO_INT,SEM_ORDENACAO_DOUBLE,SEM_ORDEM,0); } return a; }
Apresentacao preenche_apresentacao_gestao_compradores_todas_filiais (Travessia t, Apresentacao a) { Cliente elemento; while(1){ elemento = avl_t_next(t); if (elemento==NULL) break; if ((elemento->comprador_todas_filiais)==1) a = recebe_elemento(elemento->cli,a,strlen(elemento->cli),SEM_ORDENACAO_INT,SEM_ORDENACAO_DOUBLE,SEM_ORDEM,0); } return a; }
void print_pagetable() { if(avl_tree == NULL) { printf("Empty table\n"); return; } avl_t_init(&trav, avl_tree); void *item; while((item = avl_t_next(&trav)) != NULL) { page_print(item); } }
PAGINA_RESULTADOS travessiaProdutosPorLetra(CATALOGO_PRODUTOS catalogo, char letra){ int n; CodigoProduto_st produto; PAGINA_RESULTADOS pagina; int i = calculaIndiceProduto(toupper(letra)); int totalResultados = getTotalProdutos(catalogo,i); TravessiaModulo trav = avl_trav_alloc(); avl_t_init(trav, getCatalogoProdutosPorLetra(catalogo,letra)); produto = (CodigoProduto_st) avl_t_next(trav); pagina = (PAGINA_RESULTADOS) paginaResultadosInit(totalResultados,1); inserirResultadoLista(pagina, produto); /* a inserir enderecos dos codigos (sem malloc) */ n = 0; while((produto = avl_t_next(trav)) && n < totalResultados){ inserirResultadoLista(pagina, produto); n++; } freeTravessiaCatalogoProdutos(trav); return pagina; }
/* Checks that the current item at |trav| is |i| and that its previous and next items are as they should be. |label| is a name for the traverser used in reporting messages. There should be |n| items in the tree numbered |0|@dots{}|n - 1|. Returns nonzero only if there is an error. */ static int check_traverser (struct avl_traverser *trav, int i, int n, const char *label) { int okay = 1; int *cur, *prev, *next; prev = avl_t_prev (trav); if ((i == 0 && prev != NULL) || (i > 0 && (prev == NULL || *prev != i - 1))) { printf (" %s traverser ahead of %d, but should be ahead of %d.\n", label, prev != NULL ? *prev : -1, i == 0 ? -1 : i - 1); okay = 0; } avl_t_next (trav); cur = avl_t_cur (trav); if (cur == NULL || *cur != i) { printf (" %s traverser at %d, but should be at %d.\n", label, cur != NULL ? *cur : -1, i); okay = 0; } next = avl_t_next (trav); if ((i == n - 1 && next != NULL) || (i != n - 1 && (next == NULL || *next != i + 1))) { printf (" %s traverser behind %d, but should be behind %d.\n", label, next != NULL ? *next : -1, i == n - 1 ? -1 : i + 1); okay = 0; } avl_t_prev (trav); return okay; }
PAGINA_RESULTADOS travessiaClientesPorLetra(CATALOGO_CLIENTES catalogo, char letra){ int n; CodigoCliente_st cliente; PAGINA_RESULTADOS pagina; int i = calculaIndiceCliente(toupper(letra)); int totalResultados = getTotalClientes(catalogo,i); TravessiaModulo trav = avl_trav_alloc(); avl_t_init(trav, getCatalogoClientesPorLetra(catalogo,letra)); cliente = (CodigoCliente_st) avl_t_next(trav); pagina = (PAGINA_RESULTADOS) paginaResultadosInit(totalResultados,1); inserirResultadoLista(pagina, cliente); /* a inserir enderecos dos codigos (sem malloc) */ n = 0; while((cliente = avl_t_next(trav)) && n < totalResultados){ inserirResultadoLista(pagina, cliente); n++; } freeTravessiaCatalogoClientes(trav); return pagina; }
Apresentacao preenche_apresentacao_top_cliente (Travessia t, Apresentacao a, int N) { Produto elemento; int offset; char s[BUFFER_PEQUENO]; while(1){ elemento = avl_t_next(t); if (elemento==NULL) return a; offset = sprintf(s,"%s faturou %.2f",elemento->prod, elemento->faturacao); a = recebe_elemento(s,a,offset,SEM_ORDENACAO_INT,elemento->faturacao,DESCENDENTE,N); } return a; }
hx_container_t* hx_idmap_strings ( hx_idmap* map ) { size_t size = avl_count( map->id2string ); hx_container_t* c = hx_new_container( 'S', size ); struct avl_traverser iter; avl_t_init( &iter, map->id2string ); hx_idmap_item* item; while ((item = (hx_idmap_item*) avl_t_next( &iter )) != NULL) { int len = strlen( item->string ) + 1; char* string = calloc( len, sizeof(char) ); strcpy(string, item->string ); hx_container_push_item( c, string ); } return c; }
void RefreshACL() { ACL_User *pACL = NULL; struct avl_traverser avl_trans; struct hostent *pTemp; pACL = (ACL_User *) avl_t_first(&avl_trans,ACL_Call_Tree); while(pACL != NULL) { if(*pACL->HostName != '-') { pTemp = GetHostByName(pACL->HostName); if(pTemp != NULL) { pACL->HisAdr.ADDR = IP_FROM_HOSTENT(pTemp,0); } } pACL = (ACL_User *) avl_t_next(&avl_trans); } }
void blman_get_all_record_keys(blman *self, bbuff *recordKeys) { if(self->blockIndex->avl_count != 0) { //prealloc bbuff_reserve(recordKeys, self->blockIndex->avl_count * sizeof(uint64)); //add to buffer RDF *pRDF; struct avl_traverser rTraverser; avl_t_init(&rTraverser, self->blockIndex); // while((pRDF = avl_t_next(&rTraverser)) != NULL) { bbuff_append(recordKeys, &pRDF->m_key, sizeof(pRDF->m_key)); } } }
// ACL format: // <"allow"|"deny>"<tab><callsign><tab><hostname/IP Adr><tab><password><tab> // <Name/Location> // // The callsign field is required and should be entered in upper case without // any suffix (-R or -L). Stations are allowed/denied based on the base // callsign. // // hostname can be a numeric IP address, actual resolvable hostname or "-" for // no hostname // // The password can be "-" for no password or the actual password. The password // may not contain spaces or tabs. // // The Name/location field is free text and extends to the end of the line. // If it is desired to display <callsign>-R or <callsign>-L on the Echolink // station list start the name/location field with "-R" or "-L". // void SaveACL() { struct avl_traverser avl_trans; ACL_User *pACL; char *cp; FILE *fp = NULL; char AclFilename[80]; snprintf(AclFilename,sizeof(AclFilename),"%s." ACL_FILENAME_EXT,AppName); if((fp = fopen(AclFilename,"w")) == NULL) { LOG_ERROR(("SaveACL(): Unable to open ACL file for write.\n")); return; } pACL = (ACL_User *) avl_t_first(&avl_trans,ACL_Call_Tree); while(pACL != NULL) { if(pACL->CallPlus == NULL) { cp = NULL; } else if((cp = strchr(pACL->CallPlus,'-')) == NULL) { cp = strchr(pACL->CallPlus,' '); if(cp != NULL) { // Skip the blank cp++; } } fprintf(fp,"%s\t%s\t%s\t%s\t%s\n", pACL->bAuthorized ? "allow" : "deny", pACL->Callsign, pACL->HostName, pACL->Password, cp == NULL ? "" : cp); pACL = (ACL_User *) avl_t_next(&avl_trans); } fclose(fp); }
Apresentacao preenche_apresentacao_descendente (Travessia t, Apresentacao a, int mes, int maxAordenar) { Produto elemento; int i, j, offset, v; char s[BUFFER_PEQUENO]; while(1){ elemento = avl_t_next(t); if (elemento==NULL) break; for(v=0, i=0;i<N_FILIAIS;i++){ for(j=0;j<N_REGIMES;j++){ v+=elemento->quantidade_mes[i][mes-1][j]; } } if (v>0){ /*Foi comprado no mes pretendido*/ offset = sprintf(s,"%s quantidade comprada %d\n |",elemento->prod, v); a = recebe_elemento(s,a,offset,v,SEM_ORDENACAO_DOUBLE,DESCENDENTE, maxAordenar); } } return a; }
void LoadACL() { char Line[80]; char *Allow; ACL_User *pACL = NULL; ACL_User *pNextACL = NULL; struct avl_traverser avl_trans; char *WhiteSpace = "\t\n "; int LineNum = 0; FILE *fp = NULL; ACL_User ACL_New; struct stat FileStats; char AclFilename[80]; snprintf(AclFilename,sizeof(AclFilename),"%s." ACL_FILENAME_EXT,AppName); if((fp = fopen(AclFilename,"r")) == NULL) { if(stat(AclFilename,&FileStats) == 0) { // The ACL file exists but we couldn't open it, complain LOG_ERROR(("LoadACL(): Unable to open ACL file.\n")); } return; } memset(&ACL_New,0,sizeof(ACL_New)); ACL_New.bRefreshed = TRUE; while(fgets(Line,sizeof(Line),fp) != NULL) { LineNum++; Allow = strtok(Line,WhiteSpace); if(Allow == NULL || *Allow == '#' || *Allow == ';') { // Empty line or comment continue; } if(STRCMP(Allow,"allow") == 0) { ACL_New.bAuthorized = TRUE; } else if(STRCMP(Allow,"deny") == 0) { ACL_New.bAuthorized = FALSE; } else { // Invalid line LOG_WARN(("LoadACL(): Ignoring line %d, invalid action \"%s\".\n", LineNum,Allow)); continue; } ACL_New.Callsign = strtok(NULL,WhiteSpace); if(ACL_New.Callsign == NULL) { // Invalid line LOG_WARN(("LoadACL(): Ignoring line %d, callsign missing.\n",LineNum)); continue; } if((ACL_New.HostName = strtok(NULL,WhiteSpace)) == NULL) { LOG_WARN(("LoadACL(): Ignoring line %d, hostname missing.\n",LineNum)); continue; } if((ACL_New.Password = strtok(NULL,WhiteSpace)) == NULL) { LOG_WARN(("LoadACL(): Ignoring line %d, password missing.\n",LineNum)); continue; } ACL_New.CallPlus = strtok(NULL,"\n"); // Skip any leading whitespace if(ACL_New.CallPlus != NULL) { while(*ACL_New.CallPlus && isspace(*ACL_New.CallPlus)) { ACL_New.CallPlus++; } } if(!ACLAddUser(&ACL_New)) { LOG_WARN(("LoadACL(): Ignoring line %d, unable to resolve " "hostname \"%s\".\n",LineNum,ACL_New.HostName)); } } fclose(fp); // Remove any old entries from tree pNextACL = (ACL_User *) avl_t_first(&avl_trans,ACL_Call_Tree); while((pACL = pNextACL) != NULL) { // NB: Get the next user now in case we deleted the current user pNextACL = (ACL_User *) avl_t_next(&avl_trans); if(!pACL->bRefreshed) { DeleteACLUser(pACL); } pACL->bRefreshed = FALSE; } }
/** for all points initiate their vis line to the one directly below */ void init_vis(struct Point *points, int num_points, struct Line *lines, int num_lines) { int i; double d; struct avl_table *tree = avl_create(cmp_points, NULL, NULL); struct avl_traverser it; struct Point *p; double y1, y2; struct Point *s1, *s2; for (i = 0; i < num_points; i++) { points[i].vis = NULL; d = PORT_DOUBLE_MAX; avl_t_init(&it, tree); /* loop through the tree */ while ((p = avl_t_next(&it)) != NULL) { if (segment1(p) == NULL && segment2(p) == NULL) continue; /* test for intersection and get the intersecting point */ if (segment1(p) != NULL && segment_intersect(segment1(p), &points[i], &y1) > -1) { /* find the closest one below */ if (y1 < points[i].y && (points[i].y - y1) < d) { d = points[i].y - y1; points[i].vis = segment1(p); } } if (segment2(p) != NULL && segment_intersect(segment2(p), &points[i], &y2) > -1) { if (y2 < points[i].y && (points[i].y - y2) < d) { d = points[i].y - y2; points[i].vis = segment2(p); } } } /* end loop */ s1 = s2 = NULL; /* now if the other point is on the right, we can delete it */ if (segment1(&points[i]) != NULL && cmp_points(&points[i], other1(&points[i]), NULL) > 0) { p = other1(&points[i]); /* unless the other point of it is on the left */ if (segment1(p) != NULL && other1(p) != &points[i] && cmp_points(&points[i], other1(p), NULL) > 0) s1 = avl_delete(tree, p); else if (segment2(p) != NULL && other2(p) != &points[i] && cmp_points(&points[i], other2(p), NULL) > 0) s1 = avl_delete(tree, p); } /* now if the other point is on the right, we can delete it */ if (segment2(&points[i]) != NULL && cmp_points(&points[i], other2(&points[i]), NULL) > 0) { p = other2(&points[i]); /* unless the other point of it is on the left */ if (segment1(p) != NULL && other1(p) != &points[i] && cmp_points(&points[i], other1(p), NULL) > 0) s2 = avl_delete(tree, p); else if (segment2(p) != NULL && other2(p) != &points[i] && cmp_points(&points[i], other2(p), NULL) > 0) s2 = avl_delete(tree, p); } /* if both weren't deleted, it means there is at least one other point on the left, so add the current */ /* also there is no point adding the point if there is no segment attached to it */ if ((s1 == NULL || s2 == NULL)) { avl_insert(tree, &points[i]); } } avl_destroy(tree, NULL); }
Table_iterateur iterateur_suivant_table( Table_iterateur iterateur ) { avl_t_next( &iterateur ); return iterateur; }
void *stSortedSet_getNext(stSortedSetIterator *iterator) { return avl_t_next(&iterator->traverser); }
fm_entry *lookup_fontmap(char *ps_name) { fm_entry *fm, *fm2, tmp; char *a, *b, *c, *d, *e, *s; int i, sl, ex; struct avl_traverser t, t2; if (tfm_tree == NULL) fm_read_info(); /* only to read default map file */ assert(ps_name != NULL); s = ps_name; if (strlen(ps_name) > 7) { /* check for subsetted name tag */ for (i = 0; i < 6; i++, s++) if (*s < 'A' || *s > 'Z') break; if (i == 6 && *s == '+') s++; /* if name tag found, skip behind it */ else s = ps_name; } /* * Scan -Slant_<slant> and -Extend_<extend> font name extensions; * three valid formats: * <fontname>-Slant_<slant> * <fontname>-Slant_<slant>-Extend_<extend> * <fontname>-Extend_<extend> * Slant entry must come _before_ Extend entry */ tmp.slant = 0; tmp.extend = 0; if ((a = strstr(s, "-Slant_")) != NULL) { b = a + strlen("-Slant_"); sl = (int) strtol(b, &e, 10); if ((e != b) && (e == strend(b))) { tmp.slant = sl; *a = '\0'; /* ps_name string ends before "-Slant_" */ } else { if (e != b) { /* only if <slant> is valid number */ if ((c = strstr(e, "-Extend_")) != NULL) { d = c + strlen("-Extend_"); ex = (int) strtol(d, &e, 10); if ((e != d) && (e == strend(d))) { tmp.slant = sl; tmp.extend = ex; *a = '\0'; /* ps_name string ends before "-Slant_" */ } } } } } else { if ((a = strstr(s, "-Extend_")) != NULL) { b = a + strlen("-Extend_"); ex = (int) strtol(b, &e, 10); if ((e != b) && (e == strend(b))) { tmp.extend = ex; *a = '\0'; /* ps_name string ends before "-Extend_" */ } } } tmp.ps_name = s; fm = (fm_entry *) avl_t_find(&t, ps_tree, &tmp); if (fm == NULL) return NULL; /* no entry found */ /* at this point we know there is at least one fm_entry with given ps_name; * we test all such entries and return the first one that is valid for font * replacement */ t2 = t; fm2 = (fm_entry *) avl_t_prev(&t2); /* search forward */ do { if (fm_valid_for_font_replacement(fm)) return fm; fm = (fm_entry *) avl_t_next(&t); } while (fm != NULL && comp_fm_entry_ps(fm, &tmp, NULL) == 0); /* search backward */ while (fm2 != NULL && comp_fm_entry_ps(fm2, &tmp, NULL) == 0) { if (fm_valid_for_font_replacement(fm2)) return fm2; fm2 = (fm_entry *) avl_t_prev(&t2); } return NULL; }
/* Checks that |tree| is well-formed and verifies that the values in |array[]| are actually in |tree|. There must be |n| elements in |array[]| and |tree|. Returns nonzero only if no errors detected. */ static int verify_tree (struct avl_table *tree, int array[], size_t n) { int okay = 1; /* Check |tree|'s bst_count against that supplied. */ if (avl_count (tree) != n) { printf (" Tree count is %lu, but should be %lu.\n", (unsigned long) avl_count (tree), (unsigned long) n); okay = 0; } if (okay) { /* Recursively verify tree structure. */ size_t count; int height; recurse_verify_tree (tree->avl_root, &okay, &count, 0, INT_MAX, &height); if (count != n) { printf (" Tree has %lu nodes, but should have %lu.\n", (unsigned long) count, (unsigned long) n); okay = 0; } } if (okay) { /* Check that all the values in |array[]| are in |tree|. */ size_t i; for (i = 0; i < n; i++) if (avl_find (tree, &array[i]) == NULL) { printf (" Tree does not contain expected value %d.\n", array[i]); okay = 0; } } if (okay) { /* Check that |avl_t_first()| and |avl_t_next()| work properly. */ struct avl_traverser trav; size_t i; int prev = -1; int *item; for (i = 0, item = avl_t_first (&trav, tree); i < 2 * n && item != NULL; i++, item = avl_t_next (&trav)) { if (*item <= prev) { printf (" Tree out of order: %d follows %d in traversal\n", *item, prev); okay = 0; } prev = *item; } if (i != n) { printf (" Tree should have %lu items, but has %lu in traversal\n", (unsigned long) n, (unsigned long) i); okay = 0; } } if (okay) { /* Check that |avl_t_last()| and |avl_t_prev()| work properly. */ struct avl_traverser trav; size_t i; int next = INT_MAX; int *item; for (i = 0, item = avl_t_last (&trav, tree); i < 2 * n && item != NULL; i++, item = avl_t_prev (&trav)) { if (*item >= next) { printf (" Tree out of order: %d precedes %d in traversal\n", *item, next); okay = 0; } next = *item; } if (i != n) { printf (" Tree should have %lu items, but has %lu in reverse\n", (unsigned long) n, (unsigned long) i); okay = 0; } } if (okay) { /* Check that |avl_t_init()| works properly. */ struct avl_traverser init, first, last; int *cur, *prev, *next; avl_t_init (&init, tree); avl_t_first (&first, tree); avl_t_last (&last, tree); cur = avl_t_cur (&init); if (cur != NULL) { printf (" Inited traverser should be null, but is actually %d.\n", *cur); okay = 0; } next = avl_t_next (&init); if (next != avl_t_cur (&first)) { printf (" Next after null should be %d, but is actually %d.\n", *(int *) avl_t_cur (&first), *next); okay = 0; } avl_t_prev (&init); prev = avl_t_prev (&init); if (prev != avl_t_cur (&last)) { printf (" Previous before null should be %d, but is actually %d.\n", *(int *) avl_t_cur (&last), *prev); okay = 0; } avl_t_next (&init); } return okay; }