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 #ifdef HAVE_STDINT_H 57 # include <stdint.h> 58 #endif 59 60 struct mecherrmap__pairarray__header { 61 size_t allocated; 62 struct mecherrmap__pair *elts; 63 }; 64 typedef struct mecherrmap__pairarray__header mecherrmap__pairarray; 65 66 static inline int 67 mecherrmap__pairarray_init(mecherrmap__pairarray *arr) 68 { 69 arr->elts = calloc(10, sizeof(struct mecherrmap__pair)); 70 if (arr->elts == NULL) 71 return ENOMEM; 72 arr->allocated = 10; 73 return 0; 74 } 75 76 static inline long 77 mecherrmap__pairarray_size(mecherrmap__pairarray *arr) 78 { 79 return arr->allocated; 80 } 81 82 static inline long 83 mecherrmap__pairarray_max_size(mecherrmap__pairarray *arr) 84 { 85 size_t upper_bound; 86 87 upper_bound = SIZE_MAX / sizeof(*arr->elts); 88 if (upper_bound > LONG_MAX) 89 upper_bound = LONG_MAX; 90 return (long) upper_bound; 91 } 92 93 static inline int 94 mecherrmap__pairarray_grow(mecherrmap__pairarray *arr, unsigned long newcount) 95 { 96 size_t oldsize = sizeof(*arr->elts) * arr->allocated; 97 size_t newsize; 98 void *ptr; 99 100 if (newcount > LONG_MAX) 101 return -1; 102 if (newcount < arr->allocated) 103 return 0; 104 if (newcount > mecherrmap__pairarray_max_size(arr)) 105 return -1; 106 107 newsize = sizeof(*arr->elts) * newcount; 108 ptr = realloc(arr->elts, newsize); 109 if (ptr == NULL) 110 return -1; 111 memset((char *)ptr + oldsize, 0, newsize - oldsize); 112 arr->elts = ptr; 113 arr->allocated = newcount; 114 return 0; 115 } 116 117 static inline struct mecherrmap__pair * 118 mecherrmap__pairarray_getaddr (mecherrmap__pairarray *arr, long idx) 119 { 120 if (idx < 0 || idx >= arr->allocated) 121 abort(); 122 return arr->elts + idx; 123 } 124 125 static inline void 126 mecherrmap__pairarray_set (mecherrmap__pairarray *arr, long idx, struct mecherrmap__pair value) 127 { 128 struct mecherrmap__pair *newvalp; 129 newvalp = mecherrmap__pairarray_getaddr(arr, idx); 130 *newvalp = value; 131 } 132 133 static inline struct mecherrmap__pair 134 mecherrmap__pairarray_get (mecherrmap__pairarray *arr, long idx) 135 { 136 return *mecherrmap__pairarray_getaddr(arr, idx); 137 } 138 139 static inline void 140 mecherrmap__pairarray_destroy (mecherrmap__pairarray *arr) 141 { 142 free(arr->elts); 143 arr->elts = 0; 144 } 145 /* end of t_array template */ 146 /* start of t_bimap body template */ 147 148 /* for use in cases where text substitutions may not work, like putting 149 "const" before a type that turns out to be "char *" */ 150 typedef OM_uint32 mecherrmap__left_t; 151 typedef struct mecherror mecherrmap__right_t; 152 153 typedef struct { 154 mecherrmap__pairarray a; 155 long nextidx; 156 } mecherrmap; 157 158 static inline int 159 mecherrmap_init (mecherrmap *m) 160 { 161 m->nextidx = 0; 162 return mecherrmap__pairarray_init (&m->a); 163 } 164 165 static inline long 166 mecherrmap_size (mecherrmap *m) 167 { 168 return mecherrmap__pairarray_size (&m->a); 169 } 170 171 static inline void 172 mecherrmap_foreach (mecherrmap *m, int (*fn)(OM_uint32, struct mecherror, void *), void *p) 173 { 174 long i, sz; 175 sz = m->nextidx; 176 for (i = 0; i < sz; i++) { 177 struct mecherrmap__pair *pair; 178 pair = mecherrmap__pairarray_getaddr (&m->a, i); 179 if ((*fn)(pair->l, pair->r, p) != 0) 180 break; 181 } 182 } 183 184 static inline int 185 mecherrmap_add (mecherrmap *m, OM_uint32 l, struct mecherror r) 186 { 187 long i, sz; 188 struct mecherrmap__pair newpair; 189 int err; 190 191 sz = m->nextidx; 192 /* Make sure we're not duplicating. */ 193 for (i = 0; i < sz; i++) { 194 struct mecherrmap__pair *pair; 195 pair = mecherrmap__pairarray_getaddr (&m->a, i); 196 assert ((*cmp_OM_uint32)(l, pair->l) != 0); 197 if ((*cmp_OM_uint32)(l, pair->l) == 0) 198 abort(); 199 assert ((*mecherror_cmp)(r, pair->r) != 0); 200 if ((*mecherror_cmp)(r, pair->r) == 0) 201 abort(); 202 } 203 newpair.l = l; 204 newpair.r = r; 205 if (sz >= LONG_MAX - 1) 206 return ENOMEM; 207 err = mecherrmap__pairarray_grow (&m->a, sz+1); 208 if (err) 209 return err; 210 mecherrmap__pairarray_set (&m->a, sz, newpair); 211 m->nextidx++; 212 return 0; 213 } 214 215 static inline const mecherrmap__right_t * 216 mecherrmap_findleft (mecherrmap *m, OM_uint32 l) 217 { 218 long i, sz; 219 sz = mecherrmap_size (m); 220 for (i = 0; i < sz; i++) { 221 struct mecherrmap__pair *pair; 222 pair = mecherrmap__pairarray_getaddr (&m->a, i); 223 if ((*cmp_OM_uint32)(l, pair->l) == 0) 224 return &pair->r; 225 } 226 return 0; 227 } 228 229 static inline const mecherrmap__left_t * 230 mecherrmap_findright (mecherrmap *m, struct mecherror r) 231 { 232 long i, sz; 233 sz = mecherrmap_size (m); 234 for (i = 0; i < sz; i++) { 235 struct mecherrmap__pair *pair; 236 pair = mecherrmap__pairarray_getaddr (&m->a, i); 237 if ((*mecherror_cmp)(r, pair->r) == 0) 238 return &pair->l; 239 } 240 return 0; 241 } 242 243 struct mecherrmap__printstat { 244 FILE *f; 245 int comma; 246 }; 247 static inline int 248 mecherrmap__printone (OM_uint32 l, struct mecherror r, void *p) 249 { 250 struct mecherrmap__printstat *ps = p; 251 fprintf(ps->f, ps->comma ? ", (" : "("); 252 ps->comma = 1; 253 (*print_OM_uint32)(l, ps->f); 254 fprintf(ps->f, ","); 255 (*mecherror_print)(r, ps->f); 256 fprintf(ps->f, ")"); 257 return 0; 258 } 259 260 static inline void 261 mecherrmap_printmap (mecherrmap *m, FILE *f) 262 { 263 struct mecherrmap__printstat ps; 264 ps.comma = 0; 265 ps.f = f; 266 fprintf(f, "("); 267 mecherrmap_foreach (m, mecherrmap__printone, &ps); 268 fprintf(f, ")"); 269 } 270 271 static inline void 272 mecherrmap_destroy (mecherrmap *m) 273 { 274 mecherrmap__pairarray_destroy (&m->a); 275 } 276 /* end of t_bimap body template */ 277