/*
   File:        dyvp_array.h
   Author:      Dan Pelleg
   Created:     Mon Jan 19 11:46:33 EST 2004
   Description: Header for dyvp_array

   Copyright 2004, Carnegie Mellon University
*/

#include "dyvp_array.h"

static const char *const CVSID = "$Id: dyvp_array.c,v 1.2 2004/01/20 12:28:52 dpelleg Exp $";

#define INITIAL_DYVP_ARRAY_SIZE 10

void add_to_dyvp_array(dyvp_array *pda, const dyv *dv)
/*
     Assume dyv_array is previously of size n. After this it is of size
     n+1.
*/
{
  if ( pda -> size == pda -> array_size )
  {
    int new_size = 2 + 2 * pda->array_size;
    const dyv **new_array = AM_MALLOC_ARRAY(const dyv *,new_size);
    int i;
    for ( i = 0 ; i < pda -> array_size ; i++ )
      new_array[i] = pda->array[i];
    AM_FREE_ARRAY(pda->array,dyv *,pda->array_size);
    pda -> array = new_array;
    pda -> array_size = new_size;
  }
  pda->array[pda->size] = dv;
  pda->size += 1;
}

const dyv *safe_dyvp_array_ref(const dyvp_array *pda,int idx)
/*
     Returns a pointer (not a copy) to the index'th element stored in
   the dyv_array. Error if index < 0 or index >= size
*/
{
  const dyv *result;
  if ( idx < 0 || idx >= dyvp_array_size(pda) )
  {
    result = NULL;
    my_error("dyvp_array_ref");
  }
  else
    result = pda->array[idx];
  return(result);
}

void free_dyvp_array(dyvp_array *pda)
{
  AM_FREE_ARRAY(pda->array,dyv *,pda->array_size);
  AM_FREE(pda,dyvp_array);
}

int dyvp_array_size(const dyvp_array *da)
{
  return(da->size);
}

void dyvp_array_set(dyvp_array *dva, int idx, const dyv *dv)
{
#ifndef AMFAST
  if ((idx < 0) || (dva == NULL) || (idx >= dva->size))
    my_error("dyvp_array_set: called with incompatible arguments");
#endif /* AMFAST */
  dva->array[idx] = dv;
}

dyvp_array *mk_dyvp_array( int size)
{
  int i;
  dyvp_array *da;
 
  da = AM_MALLOC( dyvp_array);
  da->size = size;
  da->array_size = size;
  da->array = AM_MALLOC_ARRAY(const dyv *, size);

  for (i=0; i<size; ++i) da->array[i] = NULL;

  return(da);
}

dyvp_array *mk_empty_dyvp_array(void)
{
  dyvp_array *pda = AM_MALLOC(dyvp_array);
  pda -> size = 0;
  pda -> array_size = INITIAL_DYVP_ARRAY_SIZE;
  pda -> array = AM_MALLOC_ARRAY(const dyv *,pda->array_size);
  return(pda);
}
