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