/* testutils.c
   D. Swinehart, July 9, 1982  12:51 PM
   L. Stewart, October 6, 1982  3:09 PM
   L. Stewart, December 27, 1982  3:23 PM, flush nested declarations
   L. Stewart, January 1, 1983  4:20 PM, flush AllocZero
   L. Stewart, January 3, 1983  1:30 PM, flush CStringToString
   L. Stewart, March 6, 1983  4:45 PM, unflush CStringToString
 */

#include <Env.h>
#include <Alloc.h>
#include <Queue.h>
#include <Context.h>
#include <Signal.h>

extern struct ZN *GetAll();
extern int *Alloc();
extern InitQueue();
extern StartNProcess();
extern int CtxRunning;

struct ZN *zone, *myZone;
static struct Queue *ctxQ;
static int quit;
static int args[10];
static int ta[10];
static int mlerr[3];
static int leftover;
static int any;

extern/*forward*/ Loop();

main()
  {
  zone = myZone = GetAll();
  ctxQ = (struct Queue *) Alloc(zone, 2);
  InitQueue(ctxQ);
  StartNProcess("Loop", ctxQ, &Loop, 300, 75);
  quit=false;
  while (!quit) {
    CallContext(ctxQ->head);
    };
  };

static Loop() {
  char c;
  int i, result;
  for (;;) {
    wf("% ");
    while (!chav()) Block();
    c = getchar() & 0177;
    switch (c) {
        case 'q': {
          wf("\rQuit!\r");
	  quit=true;
          Block();
          };
        case '0': { getarg(0); break; };
        case '1': { getarg(1); break; };
        case '2': { getarg(2); break; };
        case '3': { getarg(3); break; };
        case '4': { getarg(4); break; };
        case '5': { getarg(5); break; };
        case '6': { getarg(6); break; };
        case '7': { getarg(7); break; };
        case '8': { getarg(8); break; };
        case '9': { getarg(9); break; };
        case 'p': { printargs(); break; };
	case 'z': {
          args[5] = (int) Alloc(zone, 10);
          printarg(5);
          break;
          };
	case 'f': { Free56(); break; };
	case 's': { CtoS(); break; };
	case 'c': { StoC(); break; };
	case 'l': { args[7] = StringSize(args[5]); printarg(7); break; };
	case 'n': { args[7] = StringSizeN(args[1]); printarg(7); break; };
	case 'v': { SV(); break; };
	case 'm': { args[7] = InstanceToMachine(args[5]);printarg(7);break;};
	case 'k': { args[6] = MakeKey(zone, args[5]); printarg(6); break; };
	case 'a': { App(); break; };
	case 'e': { Eq(); break; };
	case 'o': { Marshall1(); break; };
     case 'x': { args[6] = ShallString(0, args[5], 1); printarg(6); break; };
     case 'y': { args[5] = ShallString(0, args[6], 2); printarg(4); break; };
        default: wf("\r unknown command\r");
        }; }; };

static Marshall1() {
  Marshall((args[1]<0), &args[5], &args[1], 4);
  printargs(); };

static App() {
  struct ShortSTRING *s;
  s = CStringToString("abcdefghijklmnop");
  args[7] = AppendString(args[5], s);
  printarg(5);
  printarg(7);
  Free(zone, s); };

static Eq() {
  struct ShortSTRING *s;
  s = CStringToString("173#6#");
  args[7] = EquivalentStrings(args[5], s);
  printarg(5);
  printarg(7);
  Free(zone, s); };

static Free56() {
  if (args[5]) Free(zone, args[5]);
  if (args[6]) Free(zone, args[6]);
  args[5] = args[6] = 0; };

char *StringToCString(zone, s)
  struct ZN *zone;
  struct ShortSTRING *s;
  {
  int len, i; char b[];
  len = s->length;
  b = (char *) Allocate(zone, len/2+1);
  for (i = 0; i<len; ++i) b[i] = s->text[i];
  b[i]=0;
  return(b);
  };

static SV() {
  args[7] = GetSigVec();
  args[8] = CtxRunning;
  printarg(7); printarg(8); };

static CtoS() {
  struct ShortSTRING *s;
  args[5] = CStringToString("173#6#xxxxxxxx");
  s = (struct ShortSTRING *) args[5];
  s->length = 6;
  printarg(5); };

static StoC() {
  args[6] = StringToCString(zone, args[5]);
  printarg(6); };

static copyargs()
  {
  int i;
  for (i = 0; i < 10; i +=1 ) { ta[i] = args[i]; };
  };

static getarg(an)
  int an;
  {
  wf1("arg word %d: ", an);
  args[an] = gethex();
  wfcr();
  printarg(an);
  };

static printargs()
  {
  int i;
  wfcr();
  for (i = 0; i<10; i+=1) printarg(i);
  };

static printarg(i)
  int i;
  {
  wf3("arg %d = %xH, %d\r", i, args[i], args[i]);
  };

static printta(i)
  int i;
  {
  wf3("arg %d = %xH, %d\r", i, ta[i], ta[i]);
  };

static printtapair(i)
  int i;
  {
  printta(i);
  printta(i+1);
  };

static int gethex()
  {
  int v;
  v = 0;
  any = 0;
  for (;;) {
    egetchar();
    if (isdigit(leftover)) {
      v = (v<<4);
      v += (leftover-'0');
      any = 1;
      continue;
      };
    leftover = lc(leftover);
    if (leftover>='a' && leftover<='f') {
      v = (v<<4);
      v += (leftover-'a'+10);
      any = 1;
      continue;
      };
    break;
    };
  return(v);
  };

static int egetchar()  /* getchar with echo */
  {
  leftover = getchar() & 0177;
  putcrchar(leftover);
  return(leftover);
  };

static int generator;
int NewPSB() {
  if (++generator > maxPSB) SIGNAL(ERROR, 0);
  return generator; };