view anagram/agcore/tsd.cpp @ 6:607e3be6bad8

Adjust to the moving target called the C++ standard. Apparently nowadays it's not allowed to define an explicit copy constructor but not an assignment operator. Consequently, defining the explicit copy constructor in terms of the implicit/automatic assignment operator for general convenience no longer works. Add assignment operators. Caution: not tested with the IBM compiler, but there's no particular reason it shouldn't work.
author David A. Holland
date Mon, 30 May 2022 23:46:22 -0400
parents 13d2b8934445
children
line wrap: on
line source

/*
 * 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);
}