#include <stdlib.h>
#include <string.h>

#ifdef USE_NLLIBC
#include <nllibc.h>
#endif

#include "val.h"

struct val_entry {
  struct val_entry *next;
  char *name;
  char *val;
};

val_entry_t vals = NULL;

val_entry_t val_start(void)
{
  return vals;
}

val_entry_t val_next(val_entry_t v)
{
  return v->next;
}

char *val_name(val_entry_t v)
{
  return v->name;
}

char *val_val(val_entry_t v)
{
  return v->val;
}

static val_entry_t val_search(char *name)
{
  val_entry_t v;
  for (v = vals; v; v = v->next) {
    if (!strcmp(v->name, name))
      break;
  }
  return v;
}

static val_entry_t val_make(char *name)
{
  val_entry_t v;
  v = malloc(sizeof(*v));
  if (v != NULL) {
    memset(v, 0, sizeof(*v));
    v->name = strdup(name);
    if (v->name == NULL) {
      free(v);
      v = NULL;
    }
  }
  return v;
}

char *val_get(char *name)
{
  val_entry_t v;

  v = val_search(name);
  if (v == NULL)
    return NULL;

  return v->val;
}

int val_add(char *name, char *val)
{
  val_entry_t v;

  if (val != NULL) {
    val = strdup(val);
    if (val == NULL)
      return -1;
  }

  v = val_search(name);
  if (v == NULL) {
    v = val_make(name);
    if (v == NULL)
      return -1;
    v->next = vals;
    vals = v;
  }

  if (v->val)
    free(v->val);

  v->val = val;

  return 0;
}

int val_del(char *name)
{
  val_entry_t v, *vp;

  for (vp = &vals; *vp; vp = &((*vp)->next)) {
    v = *vp;
    if (!strcmp(v->name, name)) {
      *vp = v->next;
      free(v->name);
      if (v->val) free(v->val);
      free(v);
      return 0;
    }
  }

  return -1;
}

int val_add_from_string(char *str)
{
  char *s, *p;

  s = strdup(str);
  if (s == NULL)
    return -1;
  p = strchr(s, '=');
  if (p != NULL)
    *(p++) = '\0';
  val_add(s, p);
  free(s);

  return 0;
}
