1package t_array; 2 3use strict; 4use vars qw(@ISA); 5 6#require ktemplate; 7require t_template; 8 9@ISA=qw(t_template); 10 11my @parms = qw(NAME TYPE); 12my %defaults = ( ); 13my @templatelines = <DATA>; 14 15sub new { # no args 16 my $self = {}; 17 bless $self; 18 $self->init(\@parms, \%defaults, \@templatelines); 19 return $self; 20} 21 22__DATA__ 23 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#include <stdint.h> 45 46struct <NAME>__header { 47 size_t allocated; 48 <TYPE> *elts; 49}; 50typedef struct <NAME>__header <NAME>; 51 52static inline int 53<NAME>_init(<NAME> *arr) 54{ 55 arr->elts = calloc(10, sizeof(<TYPE>)); 56 if (arr->elts == NULL) 57 return ENOMEM; 58 arr->allocated = 10; 59 return 0; 60} 61 62static inline long 63<NAME>_size(<NAME> *arr) 64{ 65 return arr->allocated; 66} 67 68static inline unsigned long 69<NAME>_max_size(<NAME> *arr) 70{ 71 size_t upper_bound; 72 73 upper_bound = SIZE_MAX / sizeof(*arr->elts); 74 if (upper_bound > ULONG_MAX) 75 upper_bound = ULONG_MAX; 76 return (unsigned long) upper_bound; 77} 78 79static inline int 80<NAME>_grow(<NAME> *arr, unsigned long newcount) 81{ 82 size_t oldsize = sizeof(*arr->elts) * arr->allocated; 83 size_t newsize; 84 void *ptr; 85 86 if (newcount > LONG_MAX) 87 return -1; 88 if (newcount < arr->allocated) 89 return 0; 90 if (newcount > <NAME>_max_size(arr)) 91 return -1; 92 93 newsize = sizeof(*arr->elts) * newcount; 94 ptr = realloc(arr->elts, newsize); 95 if (ptr == NULL) 96 return -1; 97 memset((char *)ptr + oldsize, 0, newsize - oldsize); 98 arr->elts = ptr; 99 arr->allocated = newcount; 100 return 0; 101} 102 103static inline <TYPE> * 104<NAME>_getaddr (<NAME> *arr, long idx) 105{ 106 if (idx < 0 || (unsigned long) idx >= arr->allocated) 107 abort(); 108 return arr->elts + idx; 109} 110 111static inline void 112<NAME>_set (<NAME> *arr, long idx, <TYPE> value) 113{ 114 <TYPE> *newvalp; 115 newvalp = <NAME>_getaddr(arr, idx); 116 *newvalp = value; 117} 118 119static inline <TYPE> 120<NAME>_get (<NAME> *arr, long idx) 121{ 122 return *<NAME>_getaddr(arr, idx); 123} 124 125static inline void 126<NAME>_destroy (<NAME> *arr) 127{ 128 free(arr->elts); 129 arr->elts = 0; 130} 131