package t_array; use strict; use vars qw(@ISA); #require ktemplate; require t_template; @ISA=qw(t_template); my @parms = qw(NAME TYPE); my %defaults = ( ); my @templatelines = ; sub new { # no args my $self = {}; bless $self; $self->init(\@parms, \%defaults, \@templatelines); return $self; } __DATA__ /* * array type, derived from template * * parameters: * NAME: * TYPE: * * methods: * int init() -> nonzero if fail initial allocation * unsigned long size() -> nonnegative number of values stored * int grow(newsize) -> negative if fail allocation, memset(,0,) new space * *getaddr(idx) -> aborts if out of range * void set(idx, value) -> aborts if out of range * get(idx) -> value, or aborts if out of range */ #include #include #include #include #ifdef HAVE_STDINT_H # include #endif struct __header { size_t allocated; *elts; }; typedef struct __header ; static inline int _init( *arr) { arr->elts = calloc(10, sizeof()); if (arr->elts == NULL) return ENOMEM; arr->allocated = 10; return 0; } static inline long _size( *arr) { return arr->allocated; } static inline unsigned long _max_size( *arr) { size_t upper_bound; upper_bound = SIZE_MAX / sizeof(*arr->elts); if (upper_bound > ULONG_MAX) upper_bound = ULONG_MAX; return (unsigned long) upper_bound; } static inline int _grow( *arr, unsigned long newcount) { size_t oldsize = sizeof(*arr->elts) * arr->allocated; size_t newsize; void *ptr; if (newcount > LONG_MAX) return -1; if (newcount < arr->allocated) return 0; if (newcount > _max_size(arr)) return -1; newsize = sizeof(*arr->elts) * newcount; ptr = realloc(arr->elts, newsize); if (ptr == NULL) return -1; memset((char *)ptr + oldsize, 0, newsize - oldsize); arr->elts = ptr; arr->allocated = newcount; return 0; } static inline * _getaddr ( *arr, long idx) { if (idx < 0 || (unsigned long) idx >= arr->allocated) abort(); return arr->elts + idx; } static inline void _set ( *arr, long idx, value) { *newvalp; newvalp = _getaddr(arr, idx); *newvalp = value; } static inline _get ( *arr, long idx) { return *_getaddr(arr, idx); } static inline void _destroy ( *arr) { free(arr->elts); arr->elts = 0; }