1package t_tsenum; 2 3use strict; 4use vars qw(@ISA); 5 6require t_template; 7require t_enum; 8 9@ISA=qw(t_template); 10 11my @parms = qw(NAME TYPE COMPARE COPY PRINT); 12my %defaults = ( "COPY", "0", "PRINT", "0" ); 13my @templatelines = <DATA>; 14 15sub new { # no args 16 my $self = {}; 17 bless $self; 18 $self->init(\@parms, \%defaults, \@templatelines); 19 return $self; 20} 21 22sub output { 23 my ($self, $fh) = @_; 24 my $a = new t_enum; 25 $a->setparm("NAME", $self->{values}{"NAME"} . "__unsafe_enumerator"); 26 $a->setparm("TYPE", $self->{values}{"TYPE"}); 27 $a->setparm("COMPARE", $self->{values}{"COMPARE"}); 28 $a->output($fh); 29 $self->SUPER::output($fh); 30} 31 321; 33 34__DATA__ 35 36/* 37 */ 38#include "k5-thread.h" 39struct <NAME>__ts_enumerator { 40 <NAME>__unsafe_enumerator e; 41 k5_mutex_t m; 42}; 43typedef struct <NAME>__ts_enumerator <NAME>; 44 45static inline int 46<NAME>_init(<NAME> *en) 47{ 48 int err = k5_mutex_init(&en->m); 49 if (err) 50 return err; 51 err = <NAME>__unsafe_enumerator_init(&en->e); 52 if (err) { 53 k5_mutex_destroy(&en->m); 54 return err; 55 } 56 return 0; 57} 58 59static inline int 60<NAME>_size(<NAME> *en, long *size) 61{ 62 int err = k5_mutex_lock(&en->m); 63 if (err) { 64 *size = -48; 65 return err; 66 } 67 *size = <NAME>__unsafe_enumerator_size(&en->e); 68 k5_mutex_unlock(&en->m); 69 return 0; 70} 71 72static inline int 73<NAME>__do_copy (<TYPE> *dest, <TYPE> src) 74{ 75 int (*copyfn)(<TYPE>*, <TYPE>) = <COPY>; 76 if (copyfn) 77 return copyfn(dest, src); 78 *dest = src; 79 return 0; 80} 81 82static inline int 83<NAME>_find_or_append(<NAME> *en, <TYPE> value, long *idxp, int *added) 84{ 85 int err; 86 long idx; 87 88 err = k5_mutex_lock(&en->m); 89 if (err) 90 return err; 91 idx = <NAME>__unsafe_enumerator_find(&en->e, value); 92 if (idx < 0) { 93 <TYPE> newvalue; 94 err = <NAME>__do_copy(&newvalue, value); 95 if (err == 0) 96 idx = <NAME>__unsafe_enumerator_append(&en->e, newvalue); 97 k5_mutex_unlock(&en->m); 98 if (err != 0) 99 return err; 100 if (idx < 0) 101 return ENOMEM; 102 *idxp = idx; 103 *added = 1; 104 return 0; 105 } 106 k5_mutex_unlock(&en->m); 107 *idxp = idx; 108 *added = 0; 109 return 0; 110} 111 112static inline int 113<NAME>_get(<NAME> *en, size_t idx, <TYPE> *value) 114{ 115 int err; 116 err = k5_mutex_lock(&en->m); 117 if (err) 118 return err; 119 *value = <NAME>__unsafe_enumerator_get(&en->e, idx); 120 k5_mutex_unlock(&en->m); 121 return 0; 122} 123 124static inline void 125<NAME>_destroy(<NAME> *en) 126{ 127 k5_mutex_destroy(&en->m); 128 <NAME>__unsafe_enumerator_destroy(&en->e); 129} 130 131static inline int 132<NAME>_foreach(<NAME> *en, int (*fn)(size_t i, <TYPE> t, void *p), void *p) 133{ 134 int err = k5_mutex_lock(&en->m); 135 if (err) 136 return err; 137 <NAME>__unsafe_enumerator_foreach(&en->e, fn, p); 138 k5_mutex_unlock(&en->m); 139 return 0; 140} 141 142static inline int 143<NAME>__print_map_elt(size_t idx, <TYPE> val, void *p) 144{ 145 void (*printfn)(<TYPE>, FILE *) = <PRINT>; 146 FILE *f = (FILE *) p; 147 if (printfn) { 148 fprintf(f, " %lu=", (unsigned long) idx); 149 printfn(val, f); 150 } 151 return 0; 152} 153 154static inline void 155<NAME>_print(<NAME> *en, FILE *f) 156{ 157 void (*printfn)(<TYPE>, FILE *) = <PRINT>; 158 if (printfn) { 159 fprintf(f, "{"); 160 <NAME>_foreach (en, <NAME>__print_map_elt, f); 161 fprintf(f, " }"); 162 } 163} 164