Mercurial > ~dholland > hg > ag > index.cgi
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); +} +