1 /* 2 * This file is generated, please don't edit it. 3 * script: ../../../util/gen.pl 4 * args: bimap errmap.h NAME=mecherrmap LEFT=OM_uint32 RIGHT=struct mecherror LEFTPRINT=print_OM_uint32 RIGHTPRINT=mecherror_print LEFTCMP=cmp_OM_uint32 RIGHTCMP=mecherror_cmp 5 * The rest of this file is copied from a template, with 6 * substitutions. See the template for copyright info. 7 */ 8 /* start of t_bimap header template */ 9 /* 10 * bidirectional mapping table, add-only 11 * 12 * Parameters: 13 * NAME 14 * LEFT, RIGHT - types 15 * LEFTCMP, RIGHTCMP - comparison functions 16 * 17 * Methods: 18 * int init() - nonzero is error code, if any possible 19 * long size() 20 * void foreach(int (*)(LEFT, RIGHT, void*), void*) 21 * int add(LEFT, RIGHT) - 0 = success, -1 = allocation failure 22 * const struct mecherror *findleft(OM_uint32) - null iff not found 23 * const OM_uint32 *findright(struct mecherror) 24 * void destroy() - destroys container, doesn't delete elements 25 * 26 * initial implementation: flat array of (left,right) pairs 27 */ 28 29 struct mecherrmap__pair { 30 OM_uint32 l; 31 struct mecherror r; 32 }; 33 /* end of t_bimap header template */ 34 /* start of t_array template */ 35 36 /* 37 * array type, derived from template 38 * 39 * parameters: 40 * NAME: mecherrmap__pairarray 41 * TYPE: struct mecherrmap__pair 42 * 43 * methods: 44 * int init() -> nonzero if fail initial allocation 45 * unsigned long size() -> nonnegative number of values stored 46 * int grow(newsize) -> negative if fail allocation, memset(,0,) new space 47 * struct mecherrmap__pair *getaddr(idx) -> aborts if out of range 48 * void set(idx, value) -> aborts if out of range 49 * struct mecherrmap__pair get(idx) -> value, or aborts if out of range 50 */ 51 52 #include <stdlib.h> 53 #include <errno.h> 54 #include <limits.h> 55 #include <string.h> 56 #include <stdint.h> 57 58 struct mecherrmap__pairarray__header { 59 size_t allocated; 60 struct mecherrmap__pair *elts; 61 }; 62 typedef struct mecherrmap__pairarray__header mecherrmap__pairarray; 63 64 static inline int 65 mecherrmap__pairarray_init(mecherrmap__pairarray *arr) 66 { 67 arr->elts = calloc(10, sizeof(struct mecherrmap__pair)); 68 if (arr->elts == NULL) 69 return ENOMEM; 70 arr->allocated = 10; 71 return 0; 72 } 73 74 static inline long 75 mecherrmap__pairarray_size(mecherrmap__pairarray *arr) 76 { 77 return arr->allocated; 78 } 79 80 static inline unsigned long 81 mecherrmap__pairarray_max_size(mecherrmap__pairarray *arr) 82 { 83 size_t upper_bound; 84 85 upper_bound = SIZE_MAX / sizeof(*arr->elts); 86 if (upper_bound > ULONG_MAX) 87 upper_bound = ULONG_MAX; 88 return (unsigned long) upper_bound; 89 } 90 91 static inline int 92 mecherrmap__pairarray_grow(mecherrmap__pairarray *arr, unsigned long newcount) 93 { 94 size_t oldsize = sizeof(*arr->elts) * arr->allocated; 95 size_t newsize; 96 void *ptr; 97 98 if (newcount > LONG_MAX) 99 return -1; 100 if (newcount < arr->allocated) 101 return 0; 102 if (newcount > mecherrmap__pairarray_max_size(arr)) 103 return -1; 104 105 newsize = sizeof(*arr->elts) * newcount; 106 ptr = realloc(arr->elts, newsize); 107 if (ptr == NULL) 108 return -1; 109 memset((char *)ptr + oldsize, 0, newsize - oldsize); 110 arr->elts = ptr; 111 arr->allocated = newcount; 112 return 0; 113 } 114 115 static inline struct mecherrmap__pair * 116 mecherrmap__pairarray_getaddr (mecherrmap__pairarray *arr, long idx) 117 { 118 if (idx < 0 || (unsigned long) idx >= arr->allocated) 119 abort(); 120 return arr->elts + idx; 121 } 122 123 static inline void 124 mecherrmap__pairarray_set (mecherrmap__pairarray *arr, long idx, struct mecherrmap__pair value) 125 { 126 struct mecherrmap__pair *newvalp; 127 newvalp = mecherrmap__pairarray_getaddr(arr, idx); 128 *newvalp = value; 129 } 130 131 static inline struct mecherrmap__pair 132 mecherrmap__pairarray_get (mecherrmap__pairarray *arr, long idx) 133 { 134 return *mecherrmap__pairarray_getaddr(arr, idx); 135 } 136 137 static inline void 138 mecherrmap__pairarray_destroy (mecherrmap__pairarray *arr) 139 { 140 free(arr->elts); 141 arr->elts = 0; 142 } 143 /* end of t_array template */ 144 /* start of t_bimap body template */ 145 146 /* for use in cases where text substitutions may not work, like putting 147 "const" before a type that turns out to be "char *" */ 148 typedef OM_uint32 mecherrmap__left_t; 149 typedef struct mecherror mecherrmap__right_t; 150 151 typedef struct { 152 mecherrmap__pairarray a; 153 long nextidx; 154 } mecherrmap; 155 156 static inline int 157 mecherrmap_init (mecherrmap *m) 158 { 159 m->nextidx = 0; 160 return mecherrmap__pairarray_init (&m->a); 161 } 162 163 static inline long 164 mecherrmap_size (mecherrmap *m) 165 { 166 return mecherrmap__pairarray_size (&m->a); 167 } 168 169 static inline void 170 mecherrmap_foreach (mecherrmap *m, int (*fn)(OM_uint32, struct mecherror, void *), void *p) 171 { 172 long i, sz; 173 sz = m->nextidx; 174 for (i = 0; i < sz; i++) { 175 struct mecherrmap__pair *pair; 176 pair = mecherrmap__pairarray_getaddr (&m->a, i); 177 if ((*fn)(pair->l, pair->r, p) != 0) 178 break; 179 } 180 } 181 182 static inline int 183 mecherrmap_add (mecherrmap *m, OM_uint32 l, struct mecherror r) 184 { 185 long i, sz; 186 struct mecherrmap__pair newpair; 187 int err; 188 189 sz = m->nextidx; 190 /* Make sure we're not duplicating. */ 191 for (i = 0; i < sz; i++) { 192 struct mecherrmap__pair *pair; 193 pair = mecherrmap__pairarray_getaddr (&m->a, i); 194 assert ((*cmp_OM_uint32)(l, pair->l) != 0); 195 if ((*cmp_OM_uint32)(l, pair->l) == 0) 196 abort(); 197 assert ((*mecherror_cmp)(r, pair->r) != 0); 198 if ((*mecherror_cmp)(r, pair->r) == 0) 199 abort(); 200 } 201 newpair.l = l; 202 newpair.r = r; 203 if (sz >= LONG_MAX - 1) 204 return ENOMEM; 205 err = mecherrmap__pairarray_grow (&m->a, sz+1); 206 if (err) 207 return err; 208 mecherrmap__pairarray_set (&m->a, sz, newpair); 209 m->nextidx++; 210 return 0; 211 } 212 213 static inline const mecherrmap__right_t * 214 mecherrmap_findleft (mecherrmap *m, OM_uint32 l) 215 { 216 long i, sz; 217 sz = mecherrmap_size (m); 218 for (i = 0; i < sz; i++) { 219 struct mecherrmap__pair *pair; 220 pair = mecherrmap__pairarray_getaddr (&m->a, i); 221 if ((*cmp_OM_uint32)(l, pair->l) == 0) 222 return &pair->r; 223 } 224 return 0; 225 } 226 227 static inline const mecherrmap__left_t * 228 mecherrmap_findright (mecherrmap *m, struct mecherror r) 229 { 230 long i, sz; 231 sz = mecherrmap_size (m); 232 for (i = 0; i < sz; i++) { 233 struct mecherrmap__pair *pair; 234 pair = mecherrmap__pairarray_getaddr (&m->a, i); 235 if ((*mecherror_cmp)(r, pair->r) == 0) 236 return &pair->l; 237 } 238 return 0; 239 } 240 241 struct mecherrmap__printstat { 242 FILE *f; 243 int comma; 244 }; 245 static inline int 246 mecherrmap__printone (OM_uint32 l, struct mecherror r, void *p) 247 { 248 struct mecherrmap__printstat *ps = p; 249 fprintf(ps->f, ps->comma ? ", (" : "("); 250 ps->comma = 1; 251 (*print_OM_uint32)(l, ps->f); 252 fprintf(ps->f, ","); 253 (*mecherror_print)(r, ps->f); 254 fprintf(ps->f, ")"); 255 return 0; 256 } 257 258 static inline void 259 mecherrmap_printmap (mecherrmap *m, FILE *f) 260 { 261 struct mecherrmap__printstat ps; 262 ps.comma = 0; 263 ps.f = f; 264 fprintf(f, "("); 265 mecherrmap_foreach (m, mecherrmap__printone, &ps); 266 fprintf(f, ")"); 267 } 268 269 static inline void 270 mecherrmap_destroy (mecherrmap *m) 271 { 272 mecherrmap__pairarray_destroy (&m->a); 273 } 274 /* end of t_bimap body template */ 275