1*ebfedea0SLionel Sambuc /*- 2*ebfedea0SLionel Sambuc * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org> 3*ebfedea0SLionel Sambuc * All rights reserved. 4*ebfedea0SLionel Sambuc * 5*ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without 6*ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions 7*ebfedea0SLionel Sambuc * are met: 8*ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the above copyright 9*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer. 10*ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright 11*ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the 12*ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution. 13*ebfedea0SLionel Sambuc * 14*ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15*ebfedea0SLionel Sambuc * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16*ebfedea0SLionel Sambuc * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17*ebfedea0SLionel Sambuc * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18*ebfedea0SLionel Sambuc * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19*ebfedea0SLionel Sambuc * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20*ebfedea0SLionel Sambuc * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21*ebfedea0SLionel Sambuc * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22*ebfedea0SLionel Sambuc * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23*ebfedea0SLionel Sambuc * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24*ebfedea0SLionel Sambuc */ 25*ebfedea0SLionel Sambuc #ifndef ARRAY_H_ 26*ebfedea0SLionel Sambuc #define ARRAY_H_ 20120921 27*ebfedea0SLionel Sambuc 28*ebfedea0SLionel Sambuc #ifndef PGPV_ARRAY 29*ebfedea0SLionel Sambuc /* creates 2 unsigned vars called "name"c and "name"size in current scope */ 30*ebfedea0SLionel Sambuc /* also creates an array called "name"s in current scope */ 31*ebfedea0SLionel Sambuc #define PGPV_ARRAY(type, name) \ 32*ebfedea0SLionel Sambuc unsigned name##c; unsigned name##vsize; type *name##s 33*ebfedea0SLionel Sambuc #endif 34*ebfedea0SLionel Sambuc 35*ebfedea0SLionel Sambuc /* if this isn't part of a struct, need to specifically initialise things */ 36*ebfedea0SLionel Sambuc #define ARRAY_INIT(name) do { \ 37*ebfedea0SLionel Sambuc name##c = name##vsize = 0; \ 38*ebfedea0SLionel Sambuc name##s = NULL; \ 39*ebfedea0SLionel Sambuc } while(/*CONSTCOND*/0) 40*ebfedea0SLionel Sambuc 41*ebfedea0SLionel Sambuc /* check the array is big enough - if not, expand it by explicit amount */ 42*ebfedea0SLionel Sambuc /* this is clunky, but there are bugs a-lurking */ 43*ebfedea0SLionel Sambuc #define ARRAY_EXPAND_SIZED(name, mult, add) do { \ 44*ebfedea0SLionel Sambuc if (name##c == name##vsize) { \ 45*ebfedea0SLionel Sambuc void *_v; \ 46*ebfedea0SLionel Sambuc char *_cv = NULL; \ 47*ebfedea0SLionel Sambuc unsigned _ents; \ 48*ebfedea0SLionel Sambuc _ents = (name##vsize * (mult)) + (add); \ 49*ebfedea0SLionel Sambuc _cv = _v = realloc(name##s, _ents * sizeof(*name##s)); \ 50*ebfedea0SLionel Sambuc if (_v == NULL) { \ 51*ebfedea0SLionel Sambuc fprintf(stderr, "ARRAY_EXPAND - bad realloc\n"); \ 52*ebfedea0SLionel Sambuc } else { \ 53*ebfedea0SLionel Sambuc memset(&_cv[name##vsize * sizeof(*name##s)], \ 54*ebfedea0SLionel Sambuc 0x0, (_ents - name##vsize) * sizeof(*name##s)); \ 55*ebfedea0SLionel Sambuc name##s = _v; \ 56*ebfedea0SLionel Sambuc name##vsize = _ents; \ 57*ebfedea0SLionel Sambuc } \ 58*ebfedea0SLionel Sambuc } \ 59*ebfedea0SLionel Sambuc } while(/*CONSTCOND*/0) 60*ebfedea0SLionel Sambuc 61*ebfedea0SLionel Sambuc /* check the array is big enough - if not, expand it (size * 2) + 10 */ 62*ebfedea0SLionel Sambuc #define ARRAY_EXPAND(name) ARRAY_EXPAND_SIZED(name, 2, 10) 63*ebfedea0SLionel Sambuc 64*ebfedea0SLionel Sambuc #define ARRAY_ELEMENT(name, num) name##s[num] 65*ebfedea0SLionel Sambuc #define ARRAY_LAST(name) name##s[name##c - 1] 66*ebfedea0SLionel Sambuc #define ARRAY_COUNT(name) name##c 67*ebfedea0SLionel Sambuc #define ARRAY_SIZE(name) name##vsize 68*ebfedea0SLionel Sambuc #define ARRAY_ARRAY(name) name##s 69*ebfedea0SLionel Sambuc 70*ebfedea0SLionel Sambuc #define ARRAY_APPEND(name, newel) do { \ 71*ebfedea0SLionel Sambuc ARRAY_EXPAND(name); \ 72*ebfedea0SLionel Sambuc ARRAY_COUNT(name) += 1; \ 73*ebfedea0SLionel Sambuc ARRAY_LAST(name) = newel; \ 74*ebfedea0SLionel Sambuc } while(/*CONSTCOND*/0) 75*ebfedea0SLionel Sambuc 76*ebfedea0SLionel Sambuc #define ARRAY_DELETE(name, num) do { \ 77*ebfedea0SLionel Sambuc ARRAY_COUNT(name) -= 1; \ 78*ebfedea0SLionel Sambuc memmove(&ARRAY_ELEMENT(name, num), &ARRAY_ELEMENT(name, num + 1), \ 79*ebfedea0SLionel Sambuc (ARRAY_COUNT(name) - (num)) * sizeof(ARRAY_ELEMENT(name, 0))); \ 80*ebfedea0SLionel Sambuc } while(/*CONSTCOND*/0) 81*ebfedea0SLionel Sambuc 82*ebfedea0SLionel Sambuc #endif 83