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