view help2html/array.c @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -0400
parents 60b08b68c750
children
line wrap: on
line source

#include <stdlib.h>
#include "must.h"
#include "array.h"

////////////////////////////////////////////////////////////

void array_init(struct array *a) {
   a->v = NULL;
   a->num = a->max = 0;
}

struct array *array_create(void) {
   struct array *a;
   a = must_malloc(sizeof(*a));
   array_init(a);
   return a;
}

void array_cleanup(struct array *a) {
   free(a->v);
   a->v = NULL;
   a->num = a->max = 0;
}

void array_destroy(struct array *a) {
   array_cleanup(a);
   free(a);
}

////////////////////////////////////////////////////////////

/*
 * I wish there were a way to check that these were the same as the
 * inline versions, but apparently allowing such things to diverge is
 * a feature of C99. Bleh.
 *
 * Update: it all broke anyway, so I've switched to static inline as
 * an expedient. Thus, at least for the time being, we don't need the
 * extra copies.
 */

#if 0
unsigned array_num(const struct array *a) {
   return a->num;
}

void *array_get(const struct array *a, unsigned ix) {
   assert(ix < a->num);
   return a->v[ix];
}

void array_set(struct array *a, unsigned ix, void *ptr) {
   assert(ix < a->num);
   a->v[ix] = ptr;
}
#endif

////////////////////////////////////////////////////////////

unsigned array_add(struct array *a, void *ptr) {
   unsigned ix;

   ix = a->num;
   array_setsize(a, a->num+1);
   a->v[ix] = ptr;
   return ix;
}

void array_setsize(struct array *a, unsigned newnum) {
   unsigned newmax;
   void **newptr;

   if (newnum > a->max) {
      newmax = a->max;
      if (newmax == 0) {
	 newmax = 4;
      }
      while (newmax < newnum) {
	 newmax *= 2;
      }
      newptr = must_realloc(a->v, newmax*sizeof(void *));
      a->v = newptr;
      a->max = newmax;
   }

   a->num = newnum;

   /* Note: it's the user's responsibility to initialize the new space */
}

void array_nonulls(struct array *a) {
   unsigned i, j;

   for (i=j=0; i<a->num; i++) {
      if (a->v[i] != NULL) {
	 if (i != j) {
	    a->v[j] = a->v[i];
	 }
	 j++;
      }
   }

   a->num = j;
}

static int (*array_usersort)(void *a, void *b);

static int array_sortthunk(const void *av, const void *bv) {
   /* av and bv point to elements of the array */
   void *a = *(void *const *)av;
   void *b = *(void *const *)bv;
   return array_usersort(a, b);
}

void array_sort(struct array *a, int (*f)(void *a, void *b)) {
   array_usersort = f;
   qsort(a->v, a->num, sizeof(void *), array_sortthunk);
}