|
Packit |
fd8b60 |
package t_tsenum;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
use strict;
|
|
Packit |
fd8b60 |
use vars qw(@ISA);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
require t_template;
|
|
Packit |
fd8b60 |
require t_enum;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
@ISA=qw(t_template);
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
my @parms = qw(NAME TYPE COMPARE COPY PRINT);
|
|
Packit |
fd8b60 |
my %defaults = ( "COPY", "0", "PRINT", "0" );
|
|
Packit |
fd8b60 |
my @templatelines = <DATA>;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
sub new { # no args
|
|
Packit |
fd8b60 |
my $self = {};
|
|
Packit |
fd8b60 |
bless $self;
|
|
Packit |
fd8b60 |
$self->init(\@parms, \%defaults, \@templatelines);
|
|
Packit |
fd8b60 |
return $self;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
sub output {
|
|
Packit |
fd8b60 |
my ($self, $fh) = @_;
|
|
Packit |
fd8b60 |
my $a = new t_enum;
|
|
Packit |
fd8b60 |
$a->setparm("NAME", $self->{values}{"NAME"} . "__unsafe_enumerator");
|
|
Packit |
fd8b60 |
$a->setparm("TYPE", $self->{values}{"TYPE"});
|
|
Packit |
fd8b60 |
$a->setparm("COMPARE", $self->{values}{"COMPARE"});
|
|
Packit |
fd8b60 |
$a->output($fh);
|
|
Packit |
fd8b60 |
$self->SUPER::output($fh);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
1;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
__DATA__
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
/*
|
|
Packit |
fd8b60 |
*/
|
|
Packit |
fd8b60 |
#include "k5-thread.h"
|
|
Packit |
fd8b60 |
struct <NAME>__ts_enumerator {
|
|
Packit |
fd8b60 |
<NAME>__unsafe_enumerator e;
|
|
Packit |
fd8b60 |
k5_mutex_t m;
|
|
Packit |
fd8b60 |
};
|
|
Packit |
fd8b60 |
typedef struct <NAME>__ts_enumerator <NAME>;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>_init(<NAME> *en)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int err = k5_mutex_init(&en->m);
|
|
Packit |
fd8b60 |
if (err)
|
|
Packit |
fd8b60 |
return err;
|
|
Packit |
fd8b60 |
err = <NAME>__unsafe_enumerator_init(&en->e);
|
|
Packit |
fd8b60 |
if (err) {
|
|
Packit |
fd8b60 |
k5_mutex_destroy(&en->m);
|
|
Packit |
fd8b60 |
return err;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>_size(<NAME> *en, long *size)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int err = k5_mutex_lock(&en->m);
|
|
Packit |
fd8b60 |
if (err) {
|
|
Packit |
fd8b60 |
*size = -48;
|
|
Packit |
fd8b60 |
return err;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
*size = <NAME>__unsafe_enumerator_size(&en->e);
|
|
Packit |
fd8b60 |
k5_mutex_unlock(&en->m);
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>__do_copy (<TYPE> *dest, <TYPE> src)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int (*copyfn)(<TYPE>*, <TYPE>) = <COPY>;
|
|
Packit |
fd8b60 |
if (copyfn)
|
|
Packit |
fd8b60 |
return copyfn(dest, src);
|
|
Packit |
fd8b60 |
*dest = src;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>_find_or_append(<NAME> *en, <TYPE> value, long *idxp, int *added)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int err;
|
|
Packit |
fd8b60 |
long idx;
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
err = k5_mutex_lock(&en->m);
|
|
Packit |
fd8b60 |
if (err)
|
|
Packit |
fd8b60 |
return err;
|
|
Packit |
fd8b60 |
idx = <NAME>__unsafe_enumerator_find(&en->e, value);
|
|
Packit |
fd8b60 |
if (idx < 0) {
|
|
Packit |
fd8b60 |
<TYPE> newvalue;
|
|
Packit |
fd8b60 |
err = <NAME>__do_copy(&newvalue, value);
|
|
Packit |
fd8b60 |
if (err == 0)
|
|
Packit |
fd8b60 |
idx = <NAME>__unsafe_enumerator_append(&en->e, newvalue);
|
|
Packit |
fd8b60 |
k5_mutex_unlock(&en->m);
|
|
Packit |
fd8b60 |
if (err != 0)
|
|
Packit |
fd8b60 |
return err;
|
|
Packit |
fd8b60 |
if (idx < 0)
|
|
Packit |
fd8b60 |
return ENOMEM;
|
|
Packit |
fd8b60 |
*idxp = idx;
|
|
Packit |
fd8b60 |
*added = 1;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
k5_mutex_unlock(&en->m);
|
|
Packit |
fd8b60 |
*idxp = idx;
|
|
Packit |
fd8b60 |
*added = 0;
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>_get(<NAME> *en, size_t idx, <TYPE> *value)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int err;
|
|
Packit |
fd8b60 |
err = k5_mutex_lock(&en->m);
|
|
Packit |
fd8b60 |
if (err)
|
|
Packit |
fd8b60 |
return err;
|
|
Packit |
fd8b60 |
*value = <NAME>__unsafe_enumerator_get(&en->e, idx);
|
|
Packit |
fd8b60 |
k5_mutex_unlock(&en->m);
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline void
|
|
Packit |
fd8b60 |
<NAME>_destroy(<NAME> *en)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
k5_mutex_destroy(&en->m);
|
|
Packit |
fd8b60 |
<NAME>__unsafe_enumerator_destroy(&en->e);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>_foreach(<NAME> *en, int (*fn)(size_t i, <TYPE> t, void *p), void *p)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
int err = k5_mutex_lock(&en->m);
|
|
Packit |
fd8b60 |
if (err)
|
|
Packit |
fd8b60 |
return err;
|
|
Packit |
fd8b60 |
<NAME>__unsafe_enumerator_foreach(&en->e, fn, p);
|
|
Packit |
fd8b60 |
k5_mutex_unlock(&en->m);
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline int
|
|
Packit |
fd8b60 |
<NAME>__print_map_elt(size_t idx, <TYPE> val, void *p)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
void (*printfn)(<TYPE>, FILE *) = <PRINT>;
|
|
Packit |
fd8b60 |
FILE *f = (FILE *) p;
|
|
Packit |
fd8b60 |
if (printfn) {
|
|
Packit |
fd8b60 |
fprintf(f, " %lu=", (unsigned long) idx);
|
|
Packit |
fd8b60 |
printfn(val, f);
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
return 0;
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
|
|
Packit |
fd8b60 |
static inline void
|
|
Packit |
fd8b60 |
<NAME>_print(<NAME> *en, FILE *f)
|
|
Packit |
fd8b60 |
{
|
|
Packit |
fd8b60 |
void (*printfn)(<TYPE>, FILE *) = <PRINT>;
|
|
Packit |
fd8b60 |
if (printfn) {
|
|
Packit |
fd8b60 |
fprintf(f, "{");
|
|
Packit |
fd8b60 |
<NAME>_foreach (en, <NAME>__print_map_elt, f);
|
|
Packit |
fd8b60 |
fprintf(f, " }");
|
|
Packit |
fd8b60 |
}
|
|
Packit |
fd8b60 |
}
|