#include <stdio.h>
#include <stdlib.h>
#include <tmpl.h>
#include "ip_types.h"
#include "ip_global.h"

#include "ip_alloc.gbl"
#include "ip_alloc.lcl"

#include "ip_error.gbl"

GLOBAL_FUNCTION ip_keyword_tree_t *
ip_alloc_keyword_tree()
{
  ip_keyword_tree_t *result;

  result = (ip_keyword_tree_t *) malloc(sizeof(ip_keyword_tree_t));
  if (!result) {
    perror("ip_alloc_keyword_tree: malloc failed");
    ip_error(NULL);
    }

  result->up = NULL;
  result->down = NULL;
  result->across = NULL;
  result->keyword = NULL;
  result->value = NULL;

  return result;
  }

GLOBAL_FUNCTION VOID
ip_free_keyword_tree(tree)
ip_keyword_tree_t *tree;
{
  ip_keyword_tree_t *I,*nextI;

  if (!tree) return;

  /* Free all the keyword_trees in the across list. */
  I=tree;
  do {
    /* Free the sub trees first. */
    ip_free_keyword_tree(I->down);
    free(I->keyword);
    nextI = I->across;

    /* Zero out I (so if I accidently use it again I'll get SEGV). */
    I->down = NULL;
    I->keyword = NULL;
    I->across = NULL;
    I->up = NULL;

    free(I);
    } while ((I = nextI) != tree);

  }

GLOBAL_FUNCTION ip_value_t *
ip_alloc_value()
{
  ip_value_t *result;

  result = (ip_value_t *) malloc(sizeof(ip_value_t));
  if (!result) {
    perror("ip_alloc_value: malloc failed");
    ip_error(NULL);
    }
  result->type = IP_UNDEFINED;
  result->v.scalar = NULL;
  return result;
  }

GLOBAL_FUNCTION VOID
ip_free_value(value)
ip_value_t *value;
{
  if (!value) return;

  if (value->type == IP_ARRAY) {
    ip_free_array(value->v.array);
    value->v.array = NULL;
    }
  else if (value->type == IP_SCALAR) {
    free(value->v.scalar);
    value->v.scalar = NULL;
    }

  free(value);
  }

GLOBAL_FUNCTION VOID
ip_free_array(array)
ip_array_t *array;
{
  int i;

  for (i=0; i<array->n; i++) {
    ip_free_value(array->values[i]);
    }

  free(array->values);
  free(array);
  }

