/* BSTNodeFindPrev * find previous element satisfying criteria */ LIB_EXPORT BSTNode* CC BSTNodeFindPrev ( const BSTNode *p, bool ( CC * f ) ( const BSTNode *n ) ) { if ( p != NULL ) { BSTNode *n = BSTNodePrev ( p ); while ( n != NULL ) { if ( ( * f ) ( n ) ) return n; n = BSTNodePrev ( n ); } } return NULL; }
/* BSTreeDoUntil * executes a function on each element * until the function returns 1 */ LIB_EXPORT bool CC BSTreeDoUntil ( const BSTree *bt, bool reverse, bool ( CC * f ) ( BSTNode *n, void *data ), void *data ) { if ( bt != NULL ) { BSTNode *n, *next; if ( reverse ) { n = LastNode ( bt ); while ( n != NULL ) { next = BSTNodePrev ( n ); if ( ( * f ) ( n, data ) ) return true; n = next; } } else { n = FirstNode ( bt ); while ( n != NULL ) { next = BSTNodeNext ( n ); if ( ( * f ) ( n, data ) ) return true; n = next; } } } return false; }
/* BSTreeForEach * executes a function on each tree element */ LIB_EXPORT void CC BSTreeForEach ( const BSTree *bt, bool reverse, void ( CC * f ) ( BSTNode *n, void *data ), void *data ) { if ( bt != NULL ) { BSTNode *n, *next; if ( reverse ) { n = LastNode ( bt ); while ( n != NULL ) { next = BSTNodePrev ( n ); ( * f ) ( n, data ); n = next; } } else { n = FirstNode ( bt ); while ( n != NULL ) { next = BSTNodeNext ( n ); ( * f ) ( n, data ); n = next; } } } }
rc_t make_column_typelist ( const BSTree *columns, const char *col, uint32_t *dflt_idx, KNamelist **typedecls ) { VNamelist *list; rc_t rc = VNamelistMake ( & list, 8 ); if ( rc == 0 ) { uint32_t idx; const VColumnRef *first; String col_name; StringInitCString ( & col_name, col ); first = ( const VColumnRef* ) BSTreeFind ( columns, & col_name, VColumnRefCmpString ); if ( first != NULL ) { const VColumnRef *cref = ( const VColumnRef* ) BSTNodePrev ( & first -> n ); while ( cref != NULL && StringEqual ( & first -> name, & cref -> name ) ) { first = cref; cref = ( const VColumnRef* ) BSTNodePrev ( & cref -> n ); } for ( cref = first, idx = 0; ; ++ idx ) { rc = VNamelistAppend ( list, cref -> typedecl ); if ( rc != 0 ) break; if ( cref -> dflt ) * dflt_idx = idx; cref = ( const VColumnRef* ) BSTNodeNext ( & cref -> n ); if ( cref == NULL || ! StringEqual ( & first -> name, & cref -> name ) ) break; } } if ( rc == 0 ) rc = VNamelistToNamelist ( list, typedecls ); VNamelistRelease ( list ); } return rc; }