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