summaryrefslogtreecommitdiff
path: root/support/dktools/dk3srch.ctr
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
committerNorbert Preining <norbert@preining.info>2019-09-02 13:46:59 +0900
commite0c6872cf40896c7be36b11dcc744620f10adf1d (patch)
tree60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/dktools/dk3srch.ctr
Initial commit
Diffstat (limited to 'support/dktools/dk3srch.ctr')
-rw-r--r--support/dktools/dk3srch.ctr242
1 files changed, 242 insertions, 0 deletions
diff --git a/support/dktools/dk3srch.ctr b/support/dktools/dk3srch.ctr
new file mode 100644
index 0000000000..f80a2c5700
--- /dev/null
+++ b/support/dktools/dk3srch.ctr
@@ -0,0 +1,242 @@
+%% options
+
+copyright owner = Dirk Krause
+copyright year = 2011-xxxx
+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 \"%!ds\"", 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 %!8s", TR_8PTR(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 \"%!ds\"", 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 \"%!ds\"", TR_STR(back)
+ return back;
+}
+
+
+
+/* vim: set ai sw=2 : */
+