diff options
Diffstat (limited to 'src/util/t_tsenum.pm')
| -rw-r--r-- | src/util/t_tsenum.pm | 163 |
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, " }"); + } +} |
