root/src/dps8/utarray.h

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. utarray_str_cpy
  2. utarray_str_dtor

   1 /*
   2  * vim: filetype=c:tabstop=4:ai:expandtab
   3  * SPDX-License-Identifier: BSD-1-Clause
   4  * scspell-id: 43cedd20-f630-11ec-8cef-80ee73e9b8e7
   5  *
   6  * ---------------------------------------------------------------------------
   7  *
   8  * Copyright (c) 2008-2021 Troy D. Hanson
   9  *     https://troydhanson.github.io/uthash/
  10  * Copyright (c) 2021-2022 The DPS8M Development Team
  11  *
  12  * All rights reserved.
  13  *
  14  * Redistribution and use in source and binary forms, with or without
  15  * modification, are permitted provided that the following conditions are met:
  16  *
  17  *    * Redistributions of source code must retain the above copyright
  18  *      notice, this list of conditions and the following disclaimer.
  19  *
  20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  21  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  23  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  24  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31  *
  32  * ---------------------------------------------------------------------------
  33  */
  34 
  35 /*
  36  * a dynamic array implementation using macros
  37  */
  38 
  39 #ifndef UTARRAY_H
  40 # define UTARRAY_H
  41 
  42 /* Derived from utarray version */
  43 # define UTARRAY_VERSION 21.9.8
  44 
  45 # ifdef __GNUC__
  46 #  define _UNUSED_ __attribute__ ((__unused__))
  47 # else
  48 #  define _UNUSED_
  49 # endif
  50 
  51 # include <stddef.h>  /* size_t       */
  52 # include <string.h>  /* memset, etc. */
  53 # include <signal.h>  /* raise        */
  54 # include <stdlib.h>  /* exit         */
  55 
  56 # include "dps8.h"
  57 
  58 # undef FREE
  59 # ifdef TESTING
  60 #  define FREE(p) free(p)
  61 #  undef realloc
  62 #  define realloc trealloc
  63 # else
  64 #  define FREE(p) do  \
  65   {                   \
  66     free((p));        \
  67     (p) = NULL;       \
  68   } while(0)
  69 # endif /* ifdef TESTING */
  70 
  71 # undef oom
  72 # define oom() do                                                          \
  73   {                                                                        \
  74     fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",  \
  75              __func__, __FILE__, __LINE__);                                \
  76 #  if defined(USE_BACKTRACE)                                               \
  77 #   ifdef SIGUSR2                                                          \
  78     (void)raise(SIGUSR2);                                                  \
  79     /*NOTREACHED*/ /* unreachable */                                       \
  80 #   endif /* ifdef SIGUSR2 */                                              \
  81 #  endif /* if defined(USE_BACKTRACE) */                                   \
  82     abort();                                                               \
  83     /*NOTREACHED*/ /* unreachable */                                       \
  84   } while(0)
  85 
  86 typedef void (ctor_f)(void *dst, const void *src);
  87 typedef void (dtor_f)(void *elt);
  88 typedef void (init_f)(void *elt);
  89 
  90 typedef struct {
  91     size_t sz;
  92     init_f *init;
  93     ctor_f *copy;
  94     dtor_f *dtor;
  95 } UT_icd;
  96 
  97 typedef struct {
  98     unsigned i, n;  /* i: index of next available slot, n: num slots */
  99     UT_icd icd;     /* initializer, copy and destructor functions    */
 100     char *d;        /* n slots of size icd->sz                       */
 101 } UT_array;
 102 
 103 # define utarray_init(a,_icd) do {                                            \
 104   memset(a,0,sizeof(UT_array));                                               \
 105   (a)->icd=*_icd;                                                             \
 106 } while(0)
 107 
 108 # define utarray_done(a) do {                                                 \
 109   if ((a)->n) {                                                               \
 110     if ((a)->icd.dtor) {                                                      \
 111       size_t _ut_i;                                                           \
 112       for(_ut_i=0; _ut_i < (a)->i; _ut_i++) {                                 \
 113         (a)->icd.dtor(utarray_eltptr(a,_ut_i));                               \
 114       }                                                                       \
 115     }                                                                         \
 116     FREE((a)->d);                                                             \
 117   }                                                                           \
 118   (a)->n=0;                                                                   \
 119 } while(0)
 120 
 121 # define utarray_new(a,_icd) do {                                             \
 122   a=(UT_array*)malloc(sizeof(UT_array));                                      \
 123   utarray_init(a,_icd);                                                       \
 124 } while(0)
 125 
 126 # define utarray_free(a) do {                                                 \
 127   utarray_done(a);                                                            \
 128   FREE(a);                                                                    \
 129 } while(0)
 130 
 131 # define utarray_reserve(a,by) do {                                           \
 132   if (((a)->i+by) > ((a)->n)) {                                               \
 133     while(((a)->i+by) > ((a)->n)) { (a)->n = ((a)->n ? (2*(a)->n) : 8); }     \
 134     if ( ((a)->d=(char*)realloc((a)->d, (a)->n*(a)->icd.sz)) == NULL) oom();  \
 135   }                                                                           \
 136 } while(0)
 137 
 138 # define utarray_push_back(a,p) do {                                          \
 139   utarray_reserve(a,1);                                                       \
 140   if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,(a)->i++), p); }      \
 141   else { memcpy(_utarray_eltptr(a,(a)->i++), p, (a)->icd.sz); };              \
 142 } while(0)
 143 
 144 # define utarray_pop_back(a) do {                                             \
 145   if ((a)->icd.dtor) { (a)->icd.dtor( _utarray_eltptr(a,--((a)->i))); }       \
 146   else { (a)->i--; }                                                          \
 147 } while(0)
 148 
 149 # define utarray_extend_back(a) do {                                          \
 150   utarray_reserve(a,1);                                                       \
 151   if ((a)->icd.init) { (a)->icd.init(_utarray_eltptr(a,(a)->i)); }            \
 152   else { memset(_utarray_eltptr(a,(a)->i),0,(a)->icd.sz); }                   \
 153   (a)->i++;                                                                   \
 154 } while(0)
 155 
 156 # define utarray_len(a) ((a)->i)
 157 
 158 # define utarray_eltptr(a,j) (((j) < (a)->i) ? _utarray_eltptr(a,j) : NULL)
 159 # define _utarray_eltptr(a,j) ((char*)((a)->d + ((a)->icd.sz*(j) )))
 160 
 161 # define utarray_insert(a,p,j) do {                                           \
 162   if (j > (a)->i) utarray_resize(a,j);                                        \
 163   utarray_reserve(a,1);                                                       \
 164   if ((j) < (a)->i) {                                                         \
 165     memmove( _utarray_eltptr(a,(j)+1), _utarray_eltptr(a,j),                  \
 166              ((a)->i - (j))*((a)->icd.sz));                                   \
 167   }                                                                           \
 168   if ((a)->icd.copy) { (a)->icd.copy( _utarray_eltptr(a,j), p); }             \
 169   else { memcpy(_utarray_eltptr(a,j), p, (a)->icd.sz); };                     \
 170   (a)->i++;                                                                   \
 171 } while(0)
 172 
 173 # define utarray_inserta(a,w,j) do {                                          \
 174   if (utarray_len(w) == 0) break;                                             \
 175   if (j > (a)->i) utarray_resize(a,j);                                        \
 176   utarray_reserve(a,utarray_len(w));                                          \
 177   if ((j) < (a)->i) {                                                         \
 178     memmove(_utarray_eltptr(a,(j)+utarray_len(w)),                            \
 179             _utarray_eltptr(a,j),                                             \
 180             ((a)->i - (j))*((a)->icd.sz));                                    \
 181   }                                                                           \
 182   if ((a)->icd.copy) {                                                        \
 183     size_t _ut_i;                                                             \
 184     for(_ut_i=0;_ut_i<(w)->i;_ut_i++) {                                       \
 185       (a)->icd.copy(_utarray_eltptr(a,j+_ut_i), _utarray_eltptr(w,_ut_i));    \
 186     }                                                                         \
 187   } else {                                                                    \
 188     memcpy(_utarray_eltptr(a,j), _utarray_eltptr(w,0),                        \
 189            utarray_len(w)*((a)->icd.sz));                                     \
 190   }                                                                           \
 191   (a)->i += utarray_len(w);                                                   \
 192 } while(0)
 193 
 194 # define utarray_resize(dst,num) do {                                         \
 195   size_t _ut_i;                                                               \
 196   if (dst->i > (size_t)(num)) {                                               \
 197     if ((dst)->icd.dtor) {                                                    \
 198       for(_ut_i=num; _ut_i < dst->i; _ut_i++) {                               \
 199         (dst)->icd.dtor(utarray_eltptr(dst,_ut_i));                           \
 200       }                                                                       \
 201     }                                                                         \
 202   } else if (dst->i < (size_t)(num)) {                                        \
 203     utarray_reserve(dst,num-dst->i);                                          \
 204     if ((dst)->icd.init) {                                                    \
 205       for(_ut_i=dst->i; _ut_i < num; _ut_i++) {                               \
 206         (dst)->icd.init(utarray_eltptr(dst,_ut_i));                           \
 207       }                                                                       \
 208     } else {                                                                  \
 209       memset(_utarray_eltptr(dst,dst->i),0,(dst)->icd.sz*(num-dst->i));       \
 210     }                                                                         \
 211   }                                                                           \
 212   dst->i = num;                                                               \
 213 } while(0)
 214 
 215 # define utarray_concat(dst,src) do {                                         \
 216   utarray_inserta((dst),(src),utarray_len(dst));                              \
 217 } while(0)
 218 
 219 # define utarray_erase(a,pos,len) do {                                        \
 220   if ((a)->icd.dtor) {                                                        \
 221     size_t _ut_i;                                                             \
 222     for(_ut_i=0; _ut_i < len; _ut_i++) {                                      \
 223       (a)->icd.dtor(utarray_eltptr((a),pos+_ut_i));                           \
 224     }                                                                         \
 225   }                                                                           \
 226   if ((a)->i > (pos+len)) {                                                   \
 227     memmove( _utarray_eltptr((a),pos), _utarray_eltptr((a),pos+len),          \
 228             (((a)->i)-(pos+len))*((a)->icd.sz));                              \
 229   }                                                                           \
 230   (a)->i -= (len);                                                            \
 231 } while(0)
 232 
 233 # define utarray_renew(a,u) do {                                              \
 234   if (a) utarray_clear(a);                                                    \
 235   else utarray_new((a),(u));                                                  \
 236 } while(0)
 237 
 238 # define utarray_clear(a) do {                                                \
 239   if ((a)->i > 0) {                                                           \
 240     if ((a)->icd.dtor) {                                                      \
 241       size_t _ut_i;                                                           \
 242       for(_ut_i=0; _ut_i < (a)->i; _ut_i++) {                                 \
 243         (a)->icd.dtor(utarray_eltptr(a,_ut_i));                               \
 244       }                                                                       \
 245     }                                                                         \
 246     (a)->i = 0;                                                               \
 247   }                                                                           \
 248 } while(0)
 249 
 250 # define utarray_sort(a,cmp) do {                                             \
 251   qsort((a)->d, (a)->i, (a)->icd.sz, cmp);                                    \
 252 } while(0)
 253 
 254 # define utarray_find(a,v,cmp) bsearch((v),(a)->d,(a)->i,(a)->icd.sz,cmp)
 255 # define utarray_front(a) (((a)->i) ? (_utarray_eltptr(a,0)) : NULL)
 256 # define utarray_next(a,e) (((e)==NULL) ? utarray_front(a) : ((((a)->i) > (utarray_eltidx(a,e)+1)) ? _utarray_eltptr(a,utarray_eltidx(a,e)+1) : NULL))
 257 # define utarray_prev(a,e) (((e)==NULL) ? utarray_back(a) : ((utarray_eltidx(a,e) > 0) ? _utarray_eltptr(a,utarray_eltidx(a,e)-1) : NULL))
 258 # define utarray_back(a) (((a)->i) ? (_utarray_eltptr(a,(a)->i-1)) : NULL)
 259 # define utarray_eltidx(a,e) (((char*)(e) >= (char*)((a)->d)) ? (((char*)(e) - (char*)((a)->d))/(ssize_t)(a)->icd.sz) : -1)
 260 
 261 /*
 262  * last we pre-define a few icd for
 263  * common utarrays of ints and strings
 264  */
 265 
 266 static void utarray_str_cpy(void *dst, const void *src) {
     /* [previous][next][first][last][top][bottom][index][help] */
 267   char *const *srcc = (char *const *)src;
 268   char **dstc = (char**)dst;
 269   *dstc = (*srcc == NULL) ? NULL : strdup(*srcc);
 270   if (!*dstc)
 271     {
 272       fprintf (stderr, "\rFATAL: Out of memory! Aborting at %s[%s:%d]\r\n",
 273                __func__, __FILE__, __LINE__);
 274 # if defined(USE_BACKTRACE)
 275 #  ifdef SIGUSR2
 276       (void)raise(SIGUSR2);
 277       /*NOTREACHED*/ /* unreachable */
 278 #  endif /* ifdef SIGUSR2 */
 279 # endif /* if defined(USE_BACKTRACE) */
 280       abort();
 281     }
 282 }
 283 
 284 static void utarray_str_dtor(void *elt) {
     /* [previous][next][first][last][top][bottom][index][help] */
 285   char **eltc = (char**)elt;
 286   if (*eltc) FREE(*eltc);
 287 }
 288 
 289 static const UT_icd ut_str_icd _UNUSED_ = {sizeof(char*),NULL,utarray_str_cpy,utarray_str_dtor};
 290 static const UT_icd ut_int_icd _UNUSED_ = {sizeof(int),NULL,NULL,NULL};
 291 static const UT_icd ut_ptr_icd _UNUSED_ = {sizeof(void*),NULL,NULL,NULL};
 292 
 293 #endif /* UTARRAY_H */

/* [previous][next][first][last][top][bottom][index][help] */