view anagram/agcore/arrays.cpp @ 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 13d2b8934445
children
line wrap: on
line source

/*
 * AnaGram, A System for Syntax Directed Programming
 * Copyright 1993-1999 Parsifal Software. All Rights Reserved.
 * See the file COPYING for license and usage terms.
 *
 * arrays.cpp - old array control module
 */

#include <string.h>
#include "port.h"

#include "arrays.h"
#include "assert.h"
#include "myalloc.h"
#include "stacks.h"
#include "tsd.h"

//#define INCLUDE_LOGGING
#include "log.h"


#define mkstrg(n,size) \
    (array_control_block *) \
	(ALLOCATE(n*size + sizeof(array_control_block), char))

#define remkstrg(p,n) \
    (array_control_block *) \
	(reallocate(p,n + sizeof(array_control_block), char))

typedef struct {
  unsigned elements_allocated;
  unsigned element_size;
} array_control_block;


void *init_array(unsigned n, unsigned size) {
  LOGSECTION("init_array");
  LOGV(n) LCV(size);

  array_control_block *p;
  p = mkstrg(n,size);
  p->elements_allocated = n;
  p->element_size = size;
  memset(++p,0,n*size);
  return p;
}

void *reset_array_size(void *ptr, unsigned n, unsigned size) {
  LOGSECTION("reset_array_size");
  LOGV((int) ptr) LCV(n) LCV(size);
  array_control_block *p;
  if (ptr) {
    delete_array(ptr);
  }
  p = mkstrg(n, size);
  p->elements_allocated = n;
  p->element_size = size;
  memset(++p, 0, n*size);
  LOGV((int) p) LCV(n) LCV(size);
  return p;
}

void *reset_array(void *a) {
  array_control_block *p;
  unsigned n, size;
  unsigned k;

  p = (array_control_block *) a;
  p--;
  ok_ptr(p);
  n = p->elements_allocated;
  size = p->element_size;
  k = n*size;
  size_ok(p, k+sizeof(array_control_block), __FILE__, __LINE__);
  memset(++p,0,k);
  return p;
}

void *delete_array(void *a) {
  array_control_block *p;

  p = (array_control_block *) a;
  p--;
  DEALLOCATE(p);
  return NULL;
}

static int array_ok(void *ptr) {
  array_control_block *p;

  p = (array_control_block *) ptr;
  p--;
  return ptr_ok(p);
}

#if 0 /* unused */
void *slide_array(void *ptr) {
  array_control_block *p = (array_control_block *) ptr, *q;
  unsigned size;

  p--;
  ok_ptr(p);
  size = p->elements_allocated * p->element_size + sizeof(array_control_block);
  q = (array_control_block *) reallocate(p,size, char);
  q++;
  return (void *) q;
}
#endif

int ok_index(void *ptr, unsigned x) {
  LOGSECTION("ok_index");
  array_control_block *p = (array_control_block *) ptr;
  p--;
  ok_ptr(p);
  LOGV(x) LCV(p->elements_allocated);
  return x < p->elements_allocated;
}

void *check_array_size(void *ptr, unsigned n1, unsigned n) {
  LOGSECTION("check_array_size");
  LOGV((int) ptr) LCV(n1) LCV(n);
  array_control_block *p = (array_control_block *) ptr;
  unsigned kp,kn;
//  unsigned long lim;
//  unsigned min;

  p--;
  ok_ptr(p);
  LOGV(p->elements_allocated);
  if (n1 + 1 < (kp = p->elements_allocated)) {
    return ptr;
  }
  n1 += 2;
  if (n < n1) {
    n = n1;
  }
  kn = p->element_size;
  //min = n1*kn;
  kp *= kn;

  //lim = (MAX_BYTES - sizeof(array_control_block))/kn;
  //if (lim < n1) {
  //  no_mem(kp);
  //}

  LOGV(n) LCV(n1) LCV(p->element_size);  // LCV(lim);

  //if (n > lim) {
  //  n = (unsigned) lim;
  //}

  assert(n >= n1);
  kn *= n;
/*
  p = (array_control_block *) vrealloc(p,
               min + sizeof(array_control_block),
               kn + sizeof(array_control_block), &n);
*/
  p = remkstrg(p, kn);
  LOGV(kn) LCV(p->element_size);
  //n -= sizeof(array_control_block);
  p->elements_allocated = kn/p->element_size;
  LOGV(p->elements_allocated);
  assert(p->elements_allocated >= n1);
  p++;
  if (kn > kp) {
    memset((char *)p + kp, 0, kn - kp);
  }
  LOGV(kn) LCV(kp);
  LOGV((int) ((char *)p + kp)) LCV(kn-kp);
  return p;
}

void *set_array_size(void *ptr, unsigned n) {
  array_control_block *p = (array_control_block *) ptr;
  unsigned kp,kn;

  p--;
  ok_ptr(p);
  kp = p->elements_allocated;
  if (kp == n) {
    return ptr;
  }
  kn = p->element_size;
  kp *= kn;
  kn *= n;
  p = remkstrg(p, kn);
  p->elements_allocated = n;
  p++;
  if (kn > kp) {
    memset((char *)p + kp, 0, kn - kp);
  }
  return p;
}

static unsigned *init_list(int n) {
  LOGSECTION("init_list");
  LOGV(n);
  unsigned *list = (unsigned *) init_array(n+1, sizeof(*list));
  list[0] = 1;
  return list;
}

unsigned *reset_list(unsigned *list, unsigned n) {
  LOGSECTION("reset_list");
  LOGV(list ? list[0] : 0) LCV(n);
  unsigned *new_array = init_list(n);
  new_array[0] = 1;
  if (list) {
    delete_array(list);
  }
  return new_array;
}

void *check_list_size(unsigned *list, unsigned n) {
  LOGSECTION("check_list_size");
  LOGV(list[0]) LCV(n);
  n += list[0];
  return check_array_size(list,n,n+n/2);
}

static unsigned add_data_list(unsigned *list, unsigned *data, unsigned n) {
  unsigned k = list[0];
  memmove(list+k, data, n*sizeof(*list));
  list[0] += n;
  array_ok(list);
  return k;
}

int store_list_data(unsigned *list) {
  LOGSECTION("store_list_data");
  unsigned n = tis();
  LOGV(list[0]) LCV(n);
  if (n == 0) {
    return 0;
  }
  return add_data_list(list, (unsigned *) list_base, n);
}

int store_tuple_data(tsd *t, unsigned *list) {
  unsigned n = t->nt * t->tw;
  if (n == 0) {
    return 0;
  }
  return add_data_list(list, (unsigned *)t->sb, n);
}
/*
void *shrink_fit(unsigned *list) {
  return set_array_size(list, list[0]);
}
*/

void *check_local_array(void *p) {
  assert(p != NULL);
  return p;
}

/* End ARRAYS.C */