#include <stddef.h>
#include <assert.h>

#include "FTreg.h"
#include "string.h"
#include "memory.h"
#include "useful.h"

static const char *true_strings[] = {
  "1",
  "true",
  "yes"
  };

static const char *false_strings[] = {
  "0",
  "false",
  "no"
  };

union boolean_union {
  Bool b;
  char ch[sizeof(Bool)];
};

/* This needs to be replaced if the lists of true and false strings
 * get longer */

static char *parser(str)
const char *str;
{
  union boolean_union u;
  const char **p;
  char *temp;

  assert(str != (const char *)NULL);

  for (p = &(true_strings[0]);
       p < &(true_strings[0])+sizeof(true_strings);
       ++p)
    if (strcasecmp(str, *p) == 0) {
      u.b = Bool_TRUE;
      temp = (char *)Memory_allocate(sizeof u);
      strncpy(temp, &(u.ch[0]), sizeof(u.ch));
      return temp;
    }

  for (p = &(false_strings[0]);
       p < &(false_strings[0])+sizeof(false_strings);
       ++p)
    if (strcasecmp(str, *p) == 0) {
      u.b = Bool_FALSE;
      temp = (char *)Memory_allocate(sizeof u);
      strncpy(temp, &(u.ch[0]), sizeof(u.ch));
      return temp;
    }
  return (char *)NULL;
}

static const char *un_parser(s)
const char *s;
{
  union boolean_union u;

  strncpy(&(u.ch[0]), s, sizeof(u.ch));
  if (u.b == Bool_FALSE)
    return (const char *)"False";
  else
    return (const char *)"True";
}

static int bool_equal(value, pattern)
const char *value, *pattern;
{
  union boolean_union u1, u2;

  strncpy(&(u1.ch[0]), value, sizeof(u1.ch));
  strncpy(&(u2.ch[0]), pattern, sizeof(u2.ch));
  return u1.b == u2.b;
}

static NORET bool_free(data)
char *data;
{
  Memory_free((VOIDP)data);
}

/*  The name of the first item in each group below will appear in the */
 /*  ruleeditor menu.  All the other items are equivalent ways to name that */
 /*  field operator. */
static FieldOpArg fieldOpList[]={
  { "=",bool_equal },
  { "equal",bool_equal },
  { "equals",bool_equal },
  { (char *)NULL, (FieldOperatorProc *)NULL }
};

static struct AlFieldTypeRegistry_str  bool_FTrec={
  "Boolean",
  parser,
  un_parser,
  fieldOpList,
  NULL,
  NULL,
  bool_free,
};

struct AlFieldTypeRegistry_str  *bool_FTrecptr = &bool_FTrec;
