xref: /freebsd/crypto/krb5/src/util/t_tsenum.pm (revision 328110da2661a8841f12000b99fea27ceacdd5b2)
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