summaryrefslogtreecommitdiff
path: root/src/util/t_tsenum.pm
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/t_tsenum.pm')
-rw-r--r--src/util/t_tsenum.pm163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/util/t_tsenum.pm b/src/util/t_tsenum.pm
new file mode 100644
index 000000000000..7d93c795a04b
--- /dev/null
+++ b/src/util/t_tsenum.pm
@@ -0,0 +1,163 @@
+package t_tsenum;
+
+use strict;
+use vars qw(@ISA);
+
+require t_template;
+require t_enum;
+
+@ISA=qw(t_template);
+
+my @parms = qw(NAME TYPE COMPARE COPY PRINT);
+my %defaults = ( "COPY", "0", "PRINT", "0" );
+my @templatelines = <DATA>;
+
+sub new { # no args
+ my $self = {};
+ bless $self;
+ $self->init(\@parms, \%defaults, \@templatelines);
+ return $self;
+}
+
+sub output {
+ my ($self, $fh) = @_;
+ my $a = new t_enum;
+ $a->setparm("NAME", $self->{values}{"NAME"} . "__unsafe_enumerator");
+ $a->setparm("TYPE", $self->{values}{"TYPE"});
+ $a->setparm("COMPARE", $self->{values}{"COMPARE"});
+ $a->output($fh);
+ $self->SUPER::output($fh);
+}
+
+1;
+
+__DATA__
+
+/*
+ */
+#include "k5-thread.h"
+struct <NAME>__ts_enumerator {
+ <NAME>__unsafe_enumerator e;
+ k5_mutex_t m;
+};
+typedef struct <NAME>__ts_enumerator <NAME>;
+
+static inline int
+<NAME>_init(<NAME> *en)
+{
+ int err = k5_mutex_init(&en->m);
+ if (err)
+ return err;
+ err = <NAME>__unsafe_enumerator_init(&en->e);
+ if (err) {
+ k5_mutex_destroy(&en->m);
+ return err;
+ }
+ return 0;
+}
+
+static inline int
+<NAME>_size(<NAME> *en, long *size)
+{
+ int err = k5_mutex_lock(&en->m);
+ if (err) {
+ *size = -48;
+ return err;
+ }
+ *size = <NAME>__unsafe_enumerator_size(&en->e);
+ k5_mutex_unlock(&en->m);
+ return 0;
+}
+
+static inline int
+<NAME>__do_copy (<TYPE> *dest, <TYPE> src)
+{
+ int (*copyfn)(<TYPE>*, <TYPE>) = <COPY>;
+ if (copyfn)
+ return copyfn(dest, src);
+ *dest = src;
+ return 0;
+}
+
+static inline int
+<NAME>_find_or_append(<NAME> *en, <TYPE> value, long *idxp, int *added)
+{
+ int err;
+ long idx;
+
+ err = k5_mutex_lock(&en->m);
+ if (err)
+ return err;
+ idx = <NAME>__unsafe_enumerator_find(&en->e, value);
+ if (idx < 0) {
+ <TYPE> newvalue;
+ err = <NAME>__do_copy(&newvalue, value);
+ if (err == 0)
+ idx = <NAME>__unsafe_enumerator_append(&en->e, newvalue);
+ k5_mutex_unlock(&en->m);
+ if (err != 0)
+ return err;
+ if (idx < 0)
+ return ENOMEM;
+ *idxp = idx;
+ *added = 1;
+ return 0;
+ }
+ k5_mutex_unlock(&en->m);
+ *idxp = idx;
+ *added = 0;
+ return 0;
+}
+
+static inline int
+<NAME>_get(<NAME> *en, size_t idx, <TYPE> *value)
+{
+ int err;
+ err = k5_mutex_lock(&en->m);
+ if (err)
+ return err;
+ *value = <NAME>__unsafe_enumerator_get(&en->e, idx);
+ k5_mutex_unlock(&en->m);
+ return 0;
+}
+
+static inline void
+<NAME>_destroy(<NAME> *en)
+{
+ k5_mutex_destroy(&en->m);
+ <NAME>__unsafe_enumerator_destroy(&en->e);
+}
+
+static inline int
+<NAME>_foreach(<NAME> *en, int (*fn)(size_t i, <TYPE> t, void *p), void *p)
+{
+ int err = k5_mutex_lock(&en->m);
+ if (err)
+ return err;
+ <NAME>__unsafe_enumerator_foreach(&en->e, fn, p);
+ k5_mutex_unlock(&en->m);
+ return 0;
+}
+
+static inline int
+<NAME>__print_map_elt(size_t idx, <TYPE> val, void *p)
+{
+ void (*printfn)(<TYPE>, FILE *) = <PRINT>;
+ FILE *f = (FILE *) p;
+ if (printfn) {
+ fprintf(f, " %lu=", (unsigned long) idx);
+ printfn(val, f);
+ }
+ return 0;
+}
+
+static inline void
+<NAME>_print(<NAME> *en, FILE *f)
+{
+ void (*printfn)(<TYPE>, FILE *) = <PRINT>;
+ if (printfn) {
+ fprintf(f, "{");
+ <NAME>_foreach (en, <NAME>__print_map_elt, f);
+ fprintf(f, " }");
+ }
+}