Blame src/util/t_array.pm

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