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, " }");
}
}