%% options copyright owner = Dirk Krause copyright year = 2011-2014 license = bsd %% header #include "dk3conf.h" #include "dk3types.h" #ifdef __cplusplus extern "C" { #endif /** Open search structure, allocate memory. @param i Flag: Inverse sort order. @param app Application structure for diagnostics, may be NULL. @return Pointer to new structure on success, NULL on error. */ dk3_search_t * dk3search_open_app(int i, dk3_app_t *app); /** Close search structure, release memory. @param sp Search structure to close. */ void dk3search_close(dk3_search_t *sp); /** Add one result to result set. @param sp Search structure. @param fn File name to add. @return 1 on success, 0 on error (not enough memory). */ int dk3search_add(dk3_search_t *sp, dkChar const *fn); /** Reset result traversal to traverse results again. @param sp Search structure. */ void dk3search_reset(dk3_search_t *sp); /** Get next result entry. @param sp Search structure. @return Pointer to next file name or NULL. */ dkChar const * dk3search_next(dk3_search_t *sp); #ifdef __cplusplus } #endif %% module #include "dk3all.h" $(trace-include) /** One result node. */ typedef struct _dk3_search_node_t_ { unsigned long n; /**< Node number. */ dkChar const *fn; /**< File name. */ } dk3_search_node_t; /** Compare two line nodes. @param l Left node. @param r Right node. @param cr Comparison criteria. @return Comparison result. */ static int node_compare(void const *l, void const *r, int cr) { int back = 0; dk3_search_node_t const *pl; /* Left node. */ dk3_search_node_t const *pr; /* Right node. */ if(l) { if(r) { pl = (dk3_search_node_t const *)l; pr = (dk3_search_node_t const *)r; if(pl->n > pr->n) { back = 1; } else { if(pl->n < pr->n) { back = -1; } } } else { back = 1; } } else { if(r) { back = -1; } } if(cr) { back = 0 - back; } return back; } /** Delete one node, release memory. @param n Node to delete. */ static void dk3search_node_delete(dk3_search_node_t *n) { if(n) { dk3_release(n->fn); n->n = 0UL; dk3_delete(n); } } /** Create new node, allocate memory. @param n Node number. @param fn File name. @param app Application structure for diagnostics, may be NULL. @return Pointer to new node on success, NULL on error. */ static dk3_search_node_t * dk3search_node_new_app(unsigned long n, dkChar const *fn, dk3_app_t *app) { dk3_search_node_t *back = NULL; $? "+ dk3search_node_new_app \"%s\"", fn back = dk3_new_app(dk3_search_node_t,1,app); if(back) { back->n = n; back->fn = dk3str_dup_app(fn, app); if(!(back->fn)) { $? "! failed to create string copy" dk3search_node_delete(back); back = NULL; } } $? "- dk3search_node_new_app %s", TR_PTR(back) return back; } void dk3search_close(dk3_search_t *sp) { dk3_search_node_t *n = NULL; if(sp) { if(sp->s_fn) { if(sp->i_fn) { dk3sto_it_reset(sp->i_fn); while((n = (dk3_search_node_t *)dk3sto_it_next(sp->i_fn)) != NULL) { dk3search_node_delete(n); } dk3sto_it_close(sp->i_fn); } dk3sto_close(sp->s_fn); } sp->s_fn = NULL; sp->i_fn = NULL; sp->app = NULL; dk3_delete(sp); } } dk3_search_t * dk3search_open_app(int i, dk3_app_t *app) { dk3_search_t *back = NULL; back = dk3_new_app(dk3_search_t,1,app); if(back) { back->s_fn = NULL; back->i_fn = NULL; back->inverted = (i ? 1 : 0); back->nf = 0UL; back->app = app; back->s_fn = dk3sto_open_app(app); if(back->s_fn) { back->i_fn = dk3sto_it_open(back->s_fn); dk3sto_set_comp(back->s_fn, node_compare, 0); } if(!((back->s_fn) && (back->i_fn))) { dk3search_close(back); back = NULL; } } return back; } int dk3search_add(dk3_search_t *sp, dkChar const *fn) { int back = 0; dk3_search_node_t *n = NULL; /* New node. */ $? "+ dk3search_add \"%s\"", TR_STR(fn) if((sp) && (fn)) { n = dk3search_node_new_app(sp->nf, fn, sp->app); if(n) { if(dk3sto_add(sp->s_fn, n)) { back = 1; sp->nf += 1UL; } else { dk3search_node_delete(n); } } } $? "- dk3search_add %d", back return back; } void dk3search_reset(dk3_search_t *sp) { if(sp) { dk3sto_it_reset(sp->i_fn); } } dkChar const * dk3search_next(dk3_search_t *sp) { dkChar const *back = NULL; dk3_search_node_t *node = NULL; /* Next node. */ if(sp) { node = (dk3_search_node_t *)dk3sto_it_next(sp->i_fn); if(node) { back = node->fn; } } $? "= dk3search_next \"%s\"", TR_STR(back) return back; } /* vim: set ai sw=2 : */