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

#include "FTreg.h"
#include "memory.h"

union un1 {
  int i;
  char ch[sizeof(int)];
};

static char *parser(s)
char *s;
{
  union un1 u;
  char *temp;
  char *p;
  int accumulator = 0;

  assert(s != (char *)NULL);
  for (p=s; *p != '\0'; ++p) {
    switch (*p) {
    case '0': accumulator = accumulator*10 + 0; break;
    case '1': accumulator = accumulator*10 + 1; break;
    case '2': accumulator = accumulator*10 + 2; break;
    case '3': accumulator = accumulator*10 + 3; break;
    case '4': accumulator = accumulator*10 + 4; break;
    case '5': accumulator = accumulator*10 + 5; break;
    case '6': accumulator = accumulator*10 + 6; break;
    case '7': accumulator = accumulator*10 + 7; break;
    case '8': accumulator = accumulator*10 + 8; break;
    case '9': accumulator = accumulator*10 + 9; break;
    case ' ': break;
    case '-': accumulator = -accumulator; break;
    default: return (char *)NULL; /* illegal character */
    }
  }
  u.i = accumulator;
  temp = (char *)Memory_allocate(sizeof u);
  (NORET)memcpy(temp, &(u.ch[0]), sizeof(u.ch));
  return temp;
}

static char *un_parser(s)
char *s;
{
  char *temp1;
  union un1 u;

  (NORET)memcpy(&(u.ch[0]), s, sizeof(u.ch));
  temp1 = (char *)Memory_allocate(15); /* ??? */
  sprintf(temp1, "%d", u.i);
  return temp1;
}

static int int_equal(value, pattern)
char *value, *pattern;
{
  union un1 u1, u2;

  (NORET)memcpy(&(u1.ch[0]), value, sizeof(u1.ch));
  (NORET)memcpy(&(u2.ch[0]), pattern, sizeof(u2.ch));
  return u1.i == u2.i;
}

static int int_notequal(value, pattern)
char *value, *pattern;
{
  union un1 u1, u2;

  (NORET)memcpy(&(u1.ch[0]), value, sizeof(u1.ch));
  (NORET)memcpy(&(u2.ch[0]), pattern, sizeof(u2.ch));
  return u1.i != u2.i;
}

static int int_less(value, pattern)
char *value, *pattern;
{
  union un1 u1, u2;

  (NORET)memcpy(&(u1.ch[0]), value, sizeof(u1.ch));
  (NORET)memcpy(&(u2.ch[0]), pattern, sizeof(u2.ch));
  return u2.i > u1.i;
}

static int int_greater(value, pattern)
char *value, *pattern;
{
  union un1 u1, u2;

  (NORET)memcpy(&(u1.ch[0]), value, sizeof(u1.ch));
  (NORET)memcpy(&(u2.ch[0]), pattern, sizeof(u2.ch));
  return u2.i < u1.i;
}

static NORET int_free(data)
char *data;
{
  Memory_free(data);
}

static FieldOpArg fieldOpList[]={
  { "=",int_equal },
  { "%equal",int_equal },
  { "%equals",int_equal },
  { "<",int_less },
  { ">",int_greater },
  { "!=", int_notequal },
  { "~=", int_notequal },
  { "%not_equal", int_notequal },
  { "%not_equals", int_notequal },
  { (char *)NULL, NULL}
};

static struct AlFieldTypeRegistry_str  int_FTrec={
  "Integer",
  parser,
  un_parser,
  fieldOpList,
  NULL,
  NULL,
  int_free,
};

struct AlFieldTypeRegistry_str  *int_FTrecptr = &int_FTrec;

