view anagram/agcore/arrays.cpp @ 2:4b08ee1ecb99

Adjust install notes to clarify that Wine applies only to the Windows build. (Thanks to Perry Metzger for test-driving.)
author David A. Holland
date Sun, 26 Apr 2009 17:58:26 -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 */