1*0a6a1f1dSLionel Sambuc /* Id */ 2eda6f593SDavid van Moolenbroek 3eda6f593SDavid van Moolenbroek /* 4eda6f593SDavid van Moolenbroek * Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net> 5eda6f593SDavid van Moolenbroek * 6eda6f593SDavid van Moolenbroek * Permission to use, copy, modify, and distribute this software for any 7eda6f593SDavid van Moolenbroek * purpose with or without fee is hereby granted, provided that the above 8eda6f593SDavid van Moolenbroek * copyright notice and this permission notice appear in all copies. 9eda6f593SDavid van Moolenbroek * 10eda6f593SDavid van Moolenbroek * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11eda6f593SDavid van Moolenbroek * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12eda6f593SDavid van Moolenbroek * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13eda6f593SDavid van Moolenbroek * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14eda6f593SDavid van Moolenbroek * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15eda6f593SDavid van Moolenbroek * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16eda6f593SDavid van Moolenbroek * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17eda6f593SDavid van Moolenbroek */ 18eda6f593SDavid van Moolenbroek 19eda6f593SDavid van Moolenbroek #ifndef ARRAY_H 20eda6f593SDavid van Moolenbroek #define ARRAY_H 21eda6f593SDavid van Moolenbroek 22eda6f593SDavid van Moolenbroek #define ARRAY_INITIALIZER { NULL, 0, 0 } 23eda6f593SDavid van Moolenbroek 24eda6f593SDavid van Moolenbroek #define ARRAY_DECL(n, c) \ 25eda6f593SDavid van Moolenbroek struct n { \ 26eda6f593SDavid van Moolenbroek c *list; \ 27eda6f593SDavid van Moolenbroek u_int num; \ 28eda6f593SDavid van Moolenbroek size_t space; \ 29eda6f593SDavid van Moolenbroek } 30eda6f593SDavid van Moolenbroek 31eda6f593SDavid van Moolenbroek #define ARRAY_ITEM(a, i) ((a)->list[i]) 32eda6f593SDavid van Moolenbroek #define ARRAY_ITEMSIZE(a) (sizeof *(a)->list) 33eda6f593SDavid van Moolenbroek #define ARRAY_INITIALSPACE(a) (10 * ARRAY_ITEMSIZE(a)) 34eda6f593SDavid van Moolenbroek 35eda6f593SDavid van Moolenbroek #define ARRAY_ENSURE(a, n) do { \ 36eda6f593SDavid van Moolenbroek if (UINT_MAX - (n) < (a)->num) \ 37eda6f593SDavid van Moolenbroek fatalx("number too big"); \ 38eda6f593SDavid van Moolenbroek if (SIZE_MAX / ((a)->num + (n)) < ARRAY_ITEMSIZE(a)) \ 39eda6f593SDavid van Moolenbroek fatalx("size too big"); \ 40eda6f593SDavid van Moolenbroek if ((a)->space == 0) { \ 41eda6f593SDavid van Moolenbroek (a)->space = ARRAY_INITIALSPACE(a); \ 42eda6f593SDavid van Moolenbroek (a)->list = xrealloc((a)->list, 1, (a)->space); \ 43eda6f593SDavid van Moolenbroek } \ 44eda6f593SDavid van Moolenbroek while ((a)->space <= ((a)->num + (n)) * ARRAY_ITEMSIZE(a)) { \ 45eda6f593SDavid van Moolenbroek (a)->list = xrealloc((a)->list, 2, (a)->space); \ 46eda6f593SDavid van Moolenbroek (a)->space *= 2; \ 47eda6f593SDavid van Moolenbroek } \ 48eda6f593SDavid van Moolenbroek } while (0) 49eda6f593SDavid van Moolenbroek 50eda6f593SDavid van Moolenbroek #define ARRAY_EMPTY(a) (((void *) (a)) == NULL || (a)->num == 0) 51eda6f593SDavid van Moolenbroek #define ARRAY_LENGTH(a) ((a)->num) 52eda6f593SDavid van Moolenbroek #define ARRAY_DATA(a) ((a)->list) 53eda6f593SDavid van Moolenbroek 54eda6f593SDavid van Moolenbroek #define ARRAY_FIRST(a) ARRAY_ITEM(a, 0) 55eda6f593SDavid van Moolenbroek #define ARRAY_LAST(a) ARRAY_ITEM(a, (a)->num - 1) 56eda6f593SDavid van Moolenbroek 57eda6f593SDavid van Moolenbroek #define ARRAY_INIT(a) do { \ 58eda6f593SDavid van Moolenbroek (a)->num = 0; \ 59eda6f593SDavid van Moolenbroek (a)->list = NULL; \ 60eda6f593SDavid van Moolenbroek (a)->space = 0; \ 61eda6f593SDavid van Moolenbroek } while (0) 62eda6f593SDavid van Moolenbroek #define ARRAY_CLEAR(a) do { \ 63eda6f593SDavid van Moolenbroek (a)->num = 0; \ 64eda6f593SDavid van Moolenbroek } while (0) 65eda6f593SDavid van Moolenbroek 66eda6f593SDavid van Moolenbroek #define ARRAY_SET(a, i, s) do { \ 67eda6f593SDavid van Moolenbroek (a)->list[i] = s; \ 68eda6f593SDavid van Moolenbroek } while (0) 69eda6f593SDavid van Moolenbroek 70eda6f593SDavid van Moolenbroek #define ARRAY_ADD(a, s) do { \ 71eda6f593SDavid van Moolenbroek ARRAY_ENSURE(a, 1); \ 72eda6f593SDavid van Moolenbroek (a)->list[(a)->num] = s; \ 73eda6f593SDavid van Moolenbroek (a)->num++; \ 74eda6f593SDavid van Moolenbroek } while (0) 75eda6f593SDavid van Moolenbroek #define ARRAY_INSERT(a, i, s) do { \ 76eda6f593SDavid van Moolenbroek ARRAY_ENSURE(a, 1); \ 77eda6f593SDavid van Moolenbroek if ((i) < (a)->num) { \ 78eda6f593SDavid van Moolenbroek memmove((a)->list + (i) + 1, (a)->list + (i), \ 79eda6f593SDavid van Moolenbroek ARRAY_ITEMSIZE(a) * ((a)->num - (i))); \ 80eda6f593SDavid van Moolenbroek } \ 81eda6f593SDavid van Moolenbroek (a)->list[i] = s; \ 82eda6f593SDavid van Moolenbroek (a)->num++; \ 83eda6f593SDavid van Moolenbroek } while (0) 84eda6f593SDavid van Moolenbroek #define ARRAY_REMOVE(a, i) do { \ 85eda6f593SDavid van Moolenbroek if ((i) < (a)->num - 1) { \ 86eda6f593SDavid van Moolenbroek memmove((a)->list + (i), (a)->list + (i) + 1, \ 87eda6f593SDavid van Moolenbroek ARRAY_ITEMSIZE(a) * ((a)->num - (i) - 1)); \ 88eda6f593SDavid van Moolenbroek } \ 89eda6f593SDavid van Moolenbroek (a)->num--; \ 90eda6f593SDavid van Moolenbroek if ((a)->num == 0) \ 91eda6f593SDavid van Moolenbroek ARRAY_FREE(a); \ 92eda6f593SDavid van Moolenbroek } while (0) 93eda6f593SDavid van Moolenbroek 94eda6f593SDavid van Moolenbroek #define ARRAY_EXPAND(a, n) do { \ 95eda6f593SDavid van Moolenbroek ARRAY_ENSURE(a, n); \ 96eda6f593SDavid van Moolenbroek (a)->num += n; \ 97eda6f593SDavid van Moolenbroek } while (0) 98eda6f593SDavid van Moolenbroek #define ARRAY_TRUNC(a, n) do { \ 99eda6f593SDavid van Moolenbroek if ((a)->num > n) \ 100eda6f593SDavid van Moolenbroek (a)->num -= n; \ 101eda6f593SDavid van Moolenbroek else \ 102eda6f593SDavid van Moolenbroek ARRAY_FREE(a); \ 103eda6f593SDavid van Moolenbroek } while (0) 104eda6f593SDavid van Moolenbroek 105eda6f593SDavid van Moolenbroek #define ARRAY_CONCAT(a, b) do { \ 106eda6f593SDavid van Moolenbroek ARRAY_ENSURE(a, (b)->num); \ 107eda6f593SDavid van Moolenbroek memcpy((a)->list + (a)->num, (b)->list, (b)->num * ARRAY_ITEMSIZE(a)); \ 108eda6f593SDavid van Moolenbroek (a)->num += (b)->num; \ 109eda6f593SDavid van Moolenbroek } while (0) 110eda6f593SDavid van Moolenbroek 111eda6f593SDavid van Moolenbroek #define ARRAY_FREE(a) do { \ 112*0a6a1f1dSLionel Sambuc free((a)->list); \ 113eda6f593SDavid van Moolenbroek ARRAY_INIT(a); \ 114eda6f593SDavid van Moolenbroek } while (0) 115eda6f593SDavid van Moolenbroek #define ARRAY_FREEALL(a) do { \ 116eda6f593SDavid van Moolenbroek ARRAY_FREE(a); \ 117*0a6a1f1dSLionel Sambuc free(a); \ 118eda6f593SDavid van Moolenbroek } while (0) 119eda6f593SDavid van Moolenbroek 120eda6f593SDavid van Moolenbroek #endif 121