Clean up a bunch of signed/unsigned comparison warnings
[krb5.git] / src / util / t_array.pm
1 package t_array;
2
3 use strict;
4 use vars qw(@ISA);
5
6 #require ktemplate;
7 require t_template;
8
9 @ISA=qw(t_template);
10
11 my @parms = qw(NAME TYPE);
12 my %defaults = ( );
13 my @templatelines = <DATA>;
14
15 sub new { # no args
16     my $self = {};
17     bless $self;
18     $self->init(\@parms, \%defaults, \@templatelines);
19     return $self;
20 }
21
22 __DATA__
23 \f
24 /*
25  * array type, derived from template
26  *
27  * parameters:
28  * NAME: <NAME>
29  * TYPE: <TYPE>
30  *
31  * methods:
32  * int init() -> nonzero if fail initial allocation
33  * unsigned long size() -> nonnegative number of values stored
34  * int grow(newsize) -> negative if fail allocation, memset(,0,) new space
35  * <TYPE> *getaddr(idx) -> aborts if out of range
36  * void set(idx, value) -> aborts if out of range
37  * <TYPE> get(idx) -> value, or aborts if out of range
38  */
39
40 #include <stdlib.h>
41 #include <errno.h>
42 #include <limits.h>
43 #include <string.h>
44 #ifdef HAVE_STDINT_H
45 # include <stdint.h>
46 #endif
47
48 struct <NAME>__header {
49     size_t allocated;
50     <TYPE> *elts;
51 };
52 typedef struct <NAME>__header <NAME>;
53
54 static inline int
55 <NAME>_init(<NAME> *arr)
56 {
57     arr->elts = calloc(10, sizeof(<TYPE>));
58     if (arr->elts == NULL)
59         return ENOMEM;
60     arr->allocated = 10;
61     return 0;
62 }
63
64 static inline long
65 <NAME>_size(<NAME> *arr)
66 {
67     return arr->allocated;
68 }
69
70 static inline unsigned long
71 <NAME>_max_size(<NAME> *arr)
72 {
73     size_t upper_bound;
74
75     upper_bound = SIZE_MAX / sizeof(*arr->elts);
76     if (upper_bound > ULONG_MAX)
77         upper_bound = ULONG_MAX;
78     return (unsigned long) upper_bound;
79 }
80 \f
81 static inline int
82 <NAME>_grow(<NAME> *arr, unsigned long newcount)
83 {
84     size_t oldsize = sizeof(*arr->elts) * arr->allocated;
85     size_t newsize;
86     void *ptr;
87
88     if (newcount > LONG_MAX)
89         return -1;
90     if (newcount < arr->allocated)
91         return 0;
92     if (newcount > <NAME>_max_size(arr))
93         return -1;
94
95     newsize = sizeof(*arr->elts) * newcount;
96     ptr = realloc(arr->elts, newsize);
97     if (ptr == NULL)
98         return -1;
99     memset((char *)ptr + oldsize, 0, newsize - oldsize);
100     arr->elts = ptr;
101     arr->allocated = newcount;
102     return 0;
103 }
104
105 static inline <TYPE> *
106 <NAME>_getaddr (<NAME> *arr, long idx)
107 {
108     if (idx < 0 || (unsigned long) idx >= arr->allocated)
109         abort();
110     return arr->elts + idx;
111 }
112
113 static inline void
114 <NAME>_set (<NAME> *arr, long idx, <TYPE> value)
115 {
116     <TYPE> *newvalp;
117     newvalp = <NAME>_getaddr(arr, idx);
118     *newvalp = value;
119 }
120
121 static inline <TYPE>
122 <NAME>_get (<NAME> *arr, long idx)
123 {
124     return *<NAME>_getaddr(arr, idx);
125 }
126
127 static inline void
128 <NAME>_destroy (<NAME> *arr)
129 {
130     free(arr->elts);
131     arr->elts = 0;
132 }