view anagram/agcore/stacks.cpp @ 21:1c9dac05d040

Add lint-style FALLTHROUGH annotations to fallthrough cases. (in the parse engine and thus the output code) Document this, because the old output causes warnings with gcc10.
author David A. Holland
date Mon, 13 Jun 2022 00:04:38 -0400
parents 57b2cc9b87f7
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.
 *
 * stacks.cpp
 */

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "port.h"

#ifdef VACLGUI
#include <icritsec.hpp>
#include "resource.h"
#endif

#include "agstring.h"
#include "assert.h"
#include "dict.h"
#include "myalloc.h"
#include "stacks.h"

//#define INCLUDE_LOGGING
#include "log.h"


#define cs char_strings_base
#define ws word_strings_base
#define ls long_strings_base
#define is int_stack_base
#define ni int_stack_top

static char *cs;
static int  *ws;
static int  *is;
static unsigned lcs,lws, lis;
unsigned ni;
unsigned nc;
unsigned nw;
static unsigned lcx;
static unsigned lwx;
static unsigned llx;
char *string_base;
int *list_base;

#ifdef VACLGUI
static AgResource charStackResource;
#endif


void init_stk(void) {
  LOGSECTION("init_stk");
  lcs = 100;
  lws = 100;
  lis = 20;
  cs = (char *) myalloc(lcs);
  ws = (int *) myalloc(lws * sizeof(*ws));
  is = (int *) myalloc((lis+1) * sizeof(*is));
  nc = nw = ni = lcx = lwx = llx = 0;
}

/*
void logStringStack() {
  //LOGSECTION("Stack status");
  log.line() << nc << nw << ni;
  log.line() << lcs << lws << lis;
}
*/
/*
void delete_stack(void) {
  DEALLOCATE(cs);
  DEALLOCATE(ws);
  DEALLOCATE(is);
}
*/
/*
void slide_stack(void) {
  cs = (char *) myrealloc(cs, lcs, __FILE__, __LINE__);
  ws = (int *) myrealloc(ws, lws * sizeof(*ws), __FILE__, __LINE__);
  is = (int *) myrealloc(is, (lis+1) * sizeof(*is), __FILE__, __LINE__);
}
*/
void reset_stk(void) {
  nc = nw = ni = lcx = lwx = llx = 0;
}

/*
void slns(const char *s) {            / * extract line from string * /
  int n;
  const char *sp;

  ics();
  n = 0;
	if (s) for (sp = s; *sp && *sp != '\n'; sp++) {
		if (*sp == '\t') do acs(' '); while (++n % tab_spacing);
		else acs(*sp), n++;
	}
	cs[nc] = 0;
}
*/

char *string_space(int n) {
  if (nc + n >= lcs) {
#ifdef VACLGUI
    AgLock lock(charStackResource);
#endif
    LOGSECTION("string_space::resize");
    LOGV(lcs) LCV(nc) LCV(n);

    unsigned k = lcs + (lcs >> 1) + n + 1;
    if (k > MAX_BYTES) k = (unsigned) MAX_BYTES;
    lcs = k - 1;
    LOGV(lcs) LCV(nc) LCV(n);
    assert(lcs >= nc+n);
    cs = reallocate(cs,k,char);
    string_base = &cs[lcx];
  }
  return &cs[nc];
}

int *list_space(int n) {
  if (nw + n >= lws) {
#ifdef VACLGUI
    AgLock lock(charStackResource);
#endif
    unsigned k = lws + (lws >> 1) + n + 1;
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("list_space::resize");
    LOGV(lws) LCV(nw+n);
    assert(lws >= nw+n);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  return &ws[nw];
}

void sss(const char *s) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n;

  assert(s != NULL);
  n = strlen(s);
  if (ni + 1 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k-1;
    LOGSECTION("sss::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lcx;
  if (nc + n >= lcs) {
    unsigned k = lcs + (lcs >> 1) + n + 1;
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k - 1;
    LOGSECTION("sss::resize");
    LOGV(lcs) LCV(nc+n);
    assert(lcs >= nc + n);
    cs = reallocate(cs,k,char);
  }
  lcx = nc;
  string_base = &cs[lcx];
  memcpy(string_base,s,n);
  nc += is[ni++] = n;
  cs[nc] = 0;
}

void ass(const char *s) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n;

  assert(s !=NULL);
  assert(ni>=2);
  n = strlen(s);
  if (nc + n >= lcs) {
    unsigned k = lcs + (lcs >> 1) + n + 1;
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k-1;
    LOGSECTION("ass::resize");
    LOGV(lcs) LCV(nc+n);
    assert(lcs >= nc + n);
    cs = reallocate(cs,k,char);
    string_base = &cs[lcx];
  }
  memcpy(&cs[nc], s, n);
  nc += n;
  is[ni-1] += n;
  cs[nc] = 0;
}

/*
static void extend_string(int n) {
  LOGSECTION("extend_string");
  LOGV(nc) LCV(n);
  is[ni-1] += n;
  nc += n;
  assert(nc < lcs);
}
*/

int ssprintf(const char *fs, ...) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  va_list ap;
  int n;

  check_stack;
  if (ni + 1 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("ssprintf::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lcx;
  string_space(500);
  lcx = nc;
  string_base = &cs[lcx];
  va_start(ap,fs);
  n = is[ni++] = vsprintf(&cs[nc],fs,ap);
  nc += n;
  assert(nc < lcs);
  va_end(ap);
  return n;
}

int apprintf(const char *fs, ...) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  va_list ap;
  int n;

  assert(ni>=2);
  string_space(500);
  va_start(ap,fs);
  is[ni-1] += (n = vsprintf(&cs[nc],fs,ap));
  nc += n;
  assert(nc < lcs);
  va_end(ap);
  return n;
}

void tss(void) {
  cs[nc] = 0;
}

void ics(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni + 2 > lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("ics::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lcx;
  lcx = nc;
  string_base = &cs[lcx];
  is[ni++] = 0;
  cs[nc] = 0;
}

void scs(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni + 1 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("scs::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lcx;
  if (nc + 1 >= lcs) {
    unsigned k = lcs + 2 + (lcs >> 1);
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k - 1;
    LOGSECTION("scs::resize");
    LOGV(lcs) LCV(nc+1);
    assert(lcs >= nc+1);
    cs = reallocate(cs,k,char);
  }
  lcx = nc;
  string_base = &cs[lcx];
  cs[nc++] = (char) c;
  is[ni++] = 1;
  cs[nc] = 0;
}

#if 0 /* NOTUSED */
void ist(void) {                                /* init string table */
  check_stack;
  if (ni + 4 >= lis) {
    unsigned k = lis + 5 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    assert(lis >= ni+4);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lwx;
  is[ni++] = lcx;
  lwx = nw;
  list_base = &ws[lwx];
  is[ni++] = nc;
  lcx = nc;
  string_base = &cs[lcx];
  is[ni++] = 0;
  ws[nw++] = 0;
}
#endif /* 0 - NOTUSED */

void iws(void) {                                /* init word stack */
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni + 2 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("iws::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lwx;
  lwx = nw;
  list_base = &ws[lwx];
  is[ni++] = 0;
}

void sws(int c) {                           /* store word on stack */
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni + 1 >= lis) {
    unsigned k = lis + 3 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("sws::resize");
    LOGV(lis) LCV(ni+2);
    assert(lis >= ni+2);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = lwx;
  if (nw >= lws) {
    unsigned k = lws + 2 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("sws::resize");
    LOGV(lws) LCV(nw+2);
    assert(lws >= nw+1);
    REALLOCATE_ST(ws,k);
  }
  lwx = nw;
  list_base = &ws[lwx];
  ws[nw++] = c;
  is[ni++] = 1;
}

int rcs(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //LOGSECTION("rcs");
  int n;

  assert(ni >= 2);
  n = is[--ni];
  LOGV(nc) LCV(lcx) LCV(n);
  assert(nc == lcx + n);
  cs[nc] = 0;
  nc = lcx;
  lcx = is[--ni];
  string_base = &cs[lcx];
  return n;
}

int fps(FILE *f) {                         /* put string to file */
  int n;

  char *sb;
  sb = string_base;
  n = rcs();
  fputs(sb,f);
  return n;
}

int rps(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n;

  assert(ni >= 2);
  n = 2*is[--ni];
  assert(nw == lwx + n);
  nw = lwx;
  lwx = is[--ni];
  list_base = &ws[lwx];
  return n;
}

int rws(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n;

  assert(ni >= 2);
  n = is[--ni];
  assert(nw == lwx + n);
  nw = lwx;
  lwx = is[--ni];
  list_base = &ws[lwx];
  return n;
}


void sis(int i) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  if (ni >= lis) {
    unsigned k = lis + 2 + (lis >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lis = k - 1;
    LOGSECTION("sis::resize");
    LOGV(lis) LCV(ni+2);
    assert (lis >= ni+1);
    REALLOCATE_ST(is,k);
  }
  is[ni++] = i;
}


int tis(void) {
  assert(ni >= 1);
  return is[ni-1];
}

int fis(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  assert(ni >= 1);
  return is[--ni];
}

void concat_string(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
//  check_stack;
  assert(ni >= 4);
  ni -= 2;
  lcx = is[ni];
  string_base = &cs[lcx];
  is[ni-1] += is[ni+1];
}

void concat_list(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  //check_stack;
  assert(ni >= 2);
  ni -= 2;
  lwx = is[ni];
  list_base = &ws[lwx];
  is[ni-1] += is[ni+1];
}

/*
void its(char c,int n) {
  assert(ni>=2);
  while (n > is[ni-1]) acs(' ');
  if (n == is[ni-1]) {acs(c); return;}
  if (nc + 1 >= lcs) {
    unsigned k = lcs + 1 + (lcs >> 1);
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k - 1;
    assert(lcs > nc);
    cs = reallocate(cs,k,char);
    string_base = &cs[lcx];
  }
  memmove(&cs[lcx+n+1],&cs[lcx+n],sizeof(*cs)*(is[ni-1]-n));
  cs[lcx+n] = c;
  (is[ni-1])++;
  cs[++nc] = 0;
}
*/

void acs(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  assert(ni>=2);
  if (nc + 1 >= lcs) {
    unsigned k = lcs + 2 + (lcs >> 1);
    if (k > MAX_BYTES) {
      k = (unsigned) MAX_BYTES;
    }
    lcs = k - 1;
    LOGSECTION("acs::resize");
    LOGV(lcs) LCV(nc);
    assert(lcs > nc);
    cs = reallocate(cs,k,char);
    string_base = &cs[lcx];
  }
  cs[nc++] = (char) c;
  cs[nc] = 0;
  (is[ni-1])++;
}

int isws(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int bx, tx;
  unsigned nx;
  check_stack;
  assert(ni>=2);
  if (nw >= lws) {
    unsigned k = lws + 2 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k-1;
    LOGSECTION("isws::resize");
    LOGV(lws) LCV(nw);
    assert(lws > nw);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  if (nw == lwx) {
    ws[nw++] = c;
    is[ni-1]++;
    return 0;
  }
  bx = lwx;
  tx = nw-1;
  while (bx <= tx) {
    nx = (bx+tx)/2;
    if (ws[nx] > c) {
      tx = nx-1;
    }
    else if (ws[nx] < c) {
      bx = nx + 1;
    }
    else {
      return 1;
    }
  }
  if (nw > (unsigned) bx) {
    memmove(ws+bx+1,ws+bx, (nw-bx)*sizeof(*ws));
  }
  ws[bx] = c;
  nw++;
  (is[ni-1])++;
  return 0;
}

int xws(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int k;
  int *p;

  assert(ni>=2);
  if (nw >= lws) {
    unsigned k = lws + 2 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("xws::resize");
    LOGV(lws) LCV(nw);
    assert(lws > nw);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  k = nw - lwx;
  p = list_base;
  while (k--) {
    if (c == *p++) {
      return 1;
    }
  }
  ws[nw++] = c;
  (is[ni-1])++;
  return 0;
}

int xps(int c1,int c2) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  unsigned i;
  int *p;
  int flag;

  // some compilers fail to be able to unravel the loop below to show
  // that this isn't necessary
  flag = -1;

  assert(ni>=2);
  if (nw + 2 >= lws) {
    unsigned k = lws + 3 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("xps::resize");
    LOGV(lws) LCV(nw + 2);
    assert(lws >= nw + 2);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  for (p = list_base, i = lwx;
       i < nw && ((flag = p[0] - c1) < 0 ||
		  (flag == 0 && (flag = p[1] - c2) < 0));
       p += 2, i += 2);
  if (i < nw && flag == 0) {
    return 1;
  }
  memmove(p+2, p, (nw - i)* sizeof(*p));
  *p++ = c1; *p = c2;
  nw += 2;
  (is[ni-1])++;
  return 0;
}

void aws(int c) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  assert(ni>=2);
  if (nw >= lws) {
    unsigned k = lws + 2 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("aws::resize");
    LOGV(lws) LCV(nw);
    assert(lws > nw);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  ws[nw++] = c;
  (is[ni-1])++;
}

char *build_string(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  char *h;
  unsigned n;

  check_stack;
  assert(ni >= 2);
  n = is[--ni];
  lcx = is[--ni];
  string_base = &cs[lcx];
  assert(nc >= n);
  nc -= n;
  h = ALLOCATE(n+1, char);
  memmove(h, cs + nc, n*sizeof(*h));
  h[n] = 0;
  return h;
}

AgString buildAgString(void) {
  char *sb;
  sb = string_base;
  return AgString(sb,rcs());
}

AgArray<int> buildStaticList(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  unsigned n;

  //check_stack;
  assert(ni >= 1);
  n = is[--ni];
  lwx = is[--ni];
  list_base = &ws[lwx];
  assert(nw >= n);
  nw -= n;
  return AgArray<int>(ws+nw, n);
}

int *build_list(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int *h;
  unsigned n;

  //check_stack;
  assert(ni >= 1);
  n = is[--ni];
  lwx = is[ni-1];
  list_base = &ws[lwx];
  assert(nw >= n);
  nw -= n;
  is[ni-1] = n;
  if (n == 0) h = NULL;
  else ALLOCATE_ST(h, n);
  memmove(h,ws + nw, n*sizeof(*ws));
  return h;
}
/*
static void rtbc(void) {
  assert(ni>=2);
  if (cs[nc-1] != ' ') return;
  nc--;
  is[ni-1]--;
  cs[nc] = 0;
}
*/

int idl(list_dict *d) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int k,nsx;
  int *lb;

  check_stack;
  assert(ni>=2);
  nsx = d->nsx;
  lb = list_base;
  k = add_list_dict(lb, rws(), d);
  sis(k);
  return k == nsx;
}

int fws(void) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  assert(nw > 0);
  is[ni-1]--;
  return(ws[--nw]);
}

void fdl(list_dict *d,unsigned k) {
#ifdef VACLGUI
  AgLock lock(charStackResource);
#endif
  int n, *l;

  assert(k < d->nsx);
  iws();
  l = d->text + d->ndx[k];
  n = *l++ - 1;
  if (nw + n >= lws) {
    unsigned k = lws + n + 1 + (lws >> 1);
    if (k > MAX_INTS) {
      k = (unsigned) MAX_INTS;
    }
    lws = k - 1;
    LOGSECTION("fdl::resize");
    LOGV(lws) LCV(nw + n);
    assert(lws >= nw+n);
    REALLOCATE_ST(ws,k);
    list_base = &ws[lwx];
  }
  memmove(list_base, l, n*sizeof(*list_base));
  nw += n;
  is[ni-1] = n;
}

//int idsx(string_dict *);
/*
int ids(string_dict *d) {
  rtbc();
  return idsx(d);
}

static int idsx(string_dict *d) {
  int k,nsx;
  char *sb;

  check_stack;
  assert(ni>=2);
  cs[nc] = 0;
  sb = string_base;
  rcs();
  nsx = d->nsx;
  k = add_string_dict(sb, d);
  is[ni++] = k;
  cs[nc] = 0;
  return k == nsx;
}
*/