diff anagram/agcore/tsd.cpp @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/anagram/agcore/tsd.cpp	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,353 @@
+/*
+ * AnaGram, A System for Syntax Directed Programming
+ * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
+ * See the file COPYING for license and usage terms.
+ *
+ * tsd.cpp - tuple set dictionary
+ */
+
+#include <stdarg.h>
+#include <string.h>
+#include "port.h"
+
+#include "assert.h"
+#include "myalloc.h"
+#include "tsd.h"
+
+//#define INCLUDE_LOGGING
+#include "log.h"
+
+
+/*
+ invalid_tsd() checks the internal consistency of a tuple set and
+ returns true if the tuple set is invalid
+*/
+
+int invalid_tsd(tsd *t) {
+  if (!ptr_ok(t)) return 1;
+  if (t->nt > t->na) return 1;
+  if (t->sb == NULL) return 0;
+  return !ptr_ok(t->sb);
+}
+
+void purge_tsd(tsd *r, tsd *k) {
+  LOGSECTION("purge_tsd");
+  int *rp = r->sb;
+  int *wp = rp;
+  int  wn = 0;
+  int  rn = r->nt;
+  int  rw = r->tw;
+  int *kp = k->sb;
+  int  kn = k->nt;
+  int  kw = k->tw;
+
+  LOGV(r->nt) LCV(k->nt);
+  check_tsd(r);
+  check_tsd(k);
+  assert (kw == rw);
+  while (rn--) {
+    int *sp = kp;
+    int  sn = kn;
+
+#ifdef INCLUDE_LOGGING
+    LOGS("Contains   ");
+    for (int k = 0; k < kw; k++) LOGX() LS(rp[k]);
+#endif
+
+    while (sn--) {
+      int k = rw;
+      while (k--) {
+	if (rp[k] != sp[k]) break;
+      }
+      if (k < 0) break;
+      sp += kw;
+    }
+    if (sn < 0) {
+      if (wp != rp) {
+        int k = rw;
+        while (k--) {
+	  wp[k] = rp[k];
+	}
+      }
+      wp += rw;
+      wn++;
+    }
+#ifdef INCLUDE_LOGGING
+    else {
+      LOGS("Eliminating");
+      for (int k = 0; k < kw; k++) (*Log::theLog) LS(rp[k]);
+    }
+#endif
+    rp += rw;
+  }
+  r->nt = wn;
+}
+
+void p1_tsd(tsd *r, int rc, tsd *k, int kc) {
+  int *rp = r->sb;
+  int *wp = rp;
+  int  wn = 0;
+  int  rn = r->nt;
+  int  rw = r->tw;
+  int *kp = k->sb;
+  int  kn = k->nt;
+  int  kw = k->tw;
+
+  check_tsd(k);
+  while (rn--) {
+    int *sp = kp;
+    int  sn = kn;
+    int  tv = rp[rc];
+
+    while (sn--) {
+      if (tv == sp[kc]) break;
+      sp += kw;
+    }
+    if (sn < 0) {
+      if (wp != rp) {
+        int k = rw;
+        while (k--) {
+	  wp[k] = rp[k];
+	}
+      }
+      wp += rw;
+      wn++;
+    }
+    rp += rw;
+  }
+  r->nt = wn;
+}
+
+/*
+ copy_tuple_set makes a copy of a tuple set, including a copy
+ of the contents
+*/
+
+tsd *copy_tuple_set(tsd *t) {
+  tsd *c;
+  unsigned n;
+
+  check_tsd(t);
+  c = ZALLOCATE(1,tsd);
+  n = t->na * t->tw;
+  c->sb = ALLOCATE(n, int);
+  if (n) {
+    memmove(c->sb,t->sb, n*sizeof(*t->sb));
+  }
+  c->nt = t->nt;
+  c->tw = t->tw;
+  c->na = t->na;
+  return c;
+}
+
+tsd *delete_tsd(tsd *ts) {
+  if (ts == NULL) {
+    return NULL;
+  }
+  assert(ts->nt <= ts->na);
+  if (ts->sb != NULL) {
+    DEALLOCATE(ts->sb);
+  }
+  DEALLOCATE(ts);
+  return NULL;
+}
+
+void reset_tsd(tsd *ts) {
+  unsigned na,tw;
+  unsigned k;
+
+  check_tsd(ts);
+  assert(ts->nt <= ts->na);
+  if (ts->nt == 0) {
+    if (ts->sb == NULL) {
+      return;
+    }
+  }
+  tw = ts->tw;
+  na = ts->na;
+  ts->nt = 0;
+  ok_ptr(ts->sb);
+  k = tw*na*sizeof(*ts->sb);
+  size_ok(ts->sb, k, __FILE__, __LINE__);
+  memset(ts->sb, 0, k);
+}
+
+tsd *spec_tsd(unsigned size, unsigned n) {
+  tsd *ts;
+
+  ts = ZALLOCATE(1, tsd);
+  ok_ptr(ts);
+  ts->tw = n;
+  if (size == 0) {
+    return ts;
+  }
+  ts->na = size;
+  ts->sb = ZALLOCATE(size*ts->tw, int);
+  return ts;
+}
+
+tsd *resize_tsd(tsd *ts, unsigned size) {
+  LOGSECTION("resize_tsd");
+  unsigned lim;
+
+  ok_ptr(ts);
+  if (size == ts->na) {
+    return ts;
+  }
+
+  lim = (unsigned) MAX_BYTES/(ts->tw * sizeof(*ts->sb));
+  if (size > lim) {
+    size = lim;
+  }
+  LOGV(ts->nt) LCV(size);
+
+  assert(ts->nt <= size);
+  ts->sb = reallocate(ts->sb,ts->tw*size, int);
+  ts->na = size;
+  return ts;
+}
+
+tsd *init_tsd(unsigned n) {
+  tsd *ts;
+
+  ts = spec_tsd(32,n);
+  return ts;
+}
+
+int sit(tsd *t,...) {
+  va_list ap;
+  int *sp,*p;
+  unsigned i,j;
+  unsigned long size;
+  unsigned long lim;
+  unsigned nt,tw,nb;
+  int flag;
+
+  check_stack;
+  check_tsd(t);
+  if (t->nt >= t->na) {
+    if (t->na == 0) {
+      size = 32;
+    }
+    else if (t->na > ((MAX_BYTES/2)/3)) {
+      size = MAX_BYTES;
+    }
+    else {
+      size = 1 + t->na + t->na/2;
+    }
+
+    lim = MAX_BYTES/(t->tw * sizeof(*t->sb));
+    if (size > lim) size = lim;
+    LOGSECTION("sit::resize");
+    LOGV(t->nt) LCV(size);
+    assert(t->nt < size);
+
+    t->sb = reallocate(t->sb,t->tw*(unsigned)size, int);
+    t->na = (unsigned) size;
+  }
+
+  va_start(ap,t);
+  sp = t->sb + t->tw * t->nt;
+  for (i = 0; i < t->tw; i++) {
+    sp[i] = va_arg(ap, int);
+  }
+  va_end(ap);
+  p = t->sb;
+  tw = t->tw;
+  nb = sizeof(*t->sb)*tw;
+  nt = t->nt;
+  for (i = 0; i < nt; i++, p += tw) {
+    for (j = 0; j < tw; j++) {
+      if ((flag = sp[j] - p[j]) < 0) {
+	goto b;
+      }
+      if (flag > 0) {
+	goto c;
+      }
+    }
+    return 1;
+  c:
+    continue;
+  b:
+    break;
+  }
+  memmove(p+tw,p,nb*(nt - i));
+  va_start(ap, t);
+  for (i = 0; i < t->tw; i++) {
+    p[i] = va_arg(ap, int);
+  }
+  t->nt++;
+  va_end(ap);
+  return 0;
+}
+
+void at(tsd *t,...) {
+  va_list ap;
+  int *sp;
+  int i;
+  unsigned long size;
+  unsigned long lim;
+
+  check_stack;
+  check_tsd(t);
+  if (t->nt >= t->na) {
+    if (t->na == 0) {
+      size = 32;
+    }
+    else if (t->na > ((MAX_BYTES/2)/3)) {
+      size = MAX_BYTES;
+    }
+    else {
+      size = 1 + t->na + t->na/2;
+    }
+
+    lim = MAX_BYTES/(t->tw * sizeof(*t->sb));
+    if (size > lim) {
+      size = lim;
+    }
+    LOGSECTION("at::resize");
+    LOGV(t->nt) LCV(size);
+    assert(t->nt < size);
+
+    t->sb = reallocate(t->sb, t->tw*(int)size, int);
+    t->na = (unsigned) size;
+  }
+
+  va_start(ap,t);
+  sp = t->sb + t->tw * t->nt;
+  for (i = t->tw; i--; ) {
+    *sp++ = va_arg(ap, int);
+  }
+  t->nt++;
+  va_end(ap);
+}
+
+void xtx(tsd *t, unsigned x, ...) {
+  va_list ap;
+  int *sp;
+  unsigned i;
+
+  check_stack;
+  check_tsd(t);
+  assert(x < t->nt);
+  va_start(ap, x);
+  sp = t->sb + t->tw*x;
+  for (i = 0; i<t->tw; i++) {
+    *(va_arg(ap, int*)) = sp[i];
+  }
+  va_end(ap);
+}
+
+void xtxf(tsd *t, unsigned x, ...) {
+  va_list ap;
+  int *sp;
+  unsigned i;
+
+  va_start(ap, x);
+  sp = t->sb+t->tw*x;
+  for (i = t->tw; i--; ) {
+    *(va_arg(ap, int*)) = *sp++;
+  }
+  va_end(ap);
+}
+