/***** spin: pangen3.h *****/

/* Copyright (c) 1991-2000 by Lucent Technologies - Bell Laboratories     */
/* All Rights Reserved.  This software is for educational purposes only.  */
/* Permission is given to distribute this code provided that this intro-  */
/* ductory message is not removed and no monies are exchanged.            */
/* No guarantee is expressed or implied by the distribution of this code. */
/* Software written by Gerard J. Holzmann as part of the book:            */
/* `Design and Validation of Computer Protocols,' ISBN 0-13-539925-4,     */
/* Prentice Hall, Englewood Cliffs, NJ, 07632.                            */
/* Send bug-reports and/or questions to: gerard@research.bell-labs.com    */

static char *Head0[] = {
	"#ifdef VERI",
		"#define BASE	1",
	"#else",
		"#define BASE	0",
	"#endif",
	/* NEW. HSFSPIN: lextok. */
	"#ifdef HSFSPIN",
	"typedef struct HSF_Lextok{",
	"  unsigned short ntyp;  /* node type */",
	"  int (*val)(void);     /* value/excutability of condition */",
	"  void *(*var)(void);   /* adress of variable */",
	"  HSF_Lextok *lft,*rgt; /* children in condition tree */",
	"} HSF_Lextok;",
	"HSF_Lextok *Lextok_Wood;",
	"#endif /* HSFSPIN */",
	/* NEW. HSFSPIN: end. */
	"typedef struct Trans {",
	"	short atom;	/* if &2 = atomic trans; if &8 local */",
	"	short st;	/* the nextstate */",
	"#ifdef HAS_UNLESS",
	"	short escp[HAS_UNLESS];	/* lists the escape states */",
	"	short e_trans;	/* if set, this is an escp-trans */",
	"#endif",
	"	short tpe[2];	/* class of operation (for reduction) */",
	"	short qu[6];	/* for conditional selections: qid's  */",
	"	uchar ty[6];	/* ditto: type's */",
	"#ifdef NIBIS",
	"	short om;	/* completion status of preselects */",
	"#endif",
	"	char *tp;	/* src txt of statement */",
	"	int t_id;	/* transition id, unique within proc */",
	"	int forw;	/* index forward transition */",
	"	int back;	/* index return  transition */",
	/* NEW. HSFSPIN: lextok. */
	"#ifdef HSFSPIN",
	"       HSF_Lextok  *lextok_tree; /* Pointer to root of the lextok tree. */",
	"#endif /* HSFSPIN */",
	/* NEW. HSFSPIN: end. */
	"	struct Trans *nxt;",
	"} Trans;\n",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"#define qptr(x)	(((uchar *)&now)+q_offset[x])",
	"#define pptr(x)	(((uchar *)&now)+proc_offset[x])",
#endif
	"#ifndef HSFSPIN",
	"#define qptr(x)	(((uchar *)&now)+q_offset[x])",
	"#define pptr(x)	(((uchar *)&now)+proc_offset[x])",
	"#else",
	"#define qptr(x)	(((uchar *)now)+q_offset[x])",
	"#define pptr(x)	(((uchar *)now)+proc_offset[x])",
	"#define hsf_qptr(s,x)	(((uchar *)(s))+q_offset[x])", /* useful */
	"#define hsf_pptr(s,x)	(((uchar *)(s))+proc_offset[x])", /* useful */
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end.*/
/*	"#define Pptr(x)	((proc_offset[x])?pptr(x):noptr)",	*/
	"extern uchar *Pptr(int);",

	"#define q_sz(x)	(((Q0 *)qptr(x))->Qlen)\n",
	/* NEW. HSFSPIN: useful macro. */
	"#ifdef HSFSPIN",
	"#define hsf_q_sz(s,x)	(((Q0 *)hsf_qptr(s,x))->Qlen)\n", /* HSF */
	"#endif /* HSFSPIN */",
	/* NEW. HSFSPIN: end. */
	"#ifndef VECTORSZ",
	"#define VECTORSZ	1024           /* sv   size in bytes */",
	"#endif\n",
	0,
};

static char *Header[] = {
	"#ifdef VERBOSE",
		"#define CHECK",
		"#define DEBUG",
	"#endif",
	"#ifdef SAFETY",
		"#ifndef NOFAIR",
			"#define NOFAIR",
		"#endif",
	"#endif",
	"#ifdef NOREDUCE",
		"#define XUSAFE",
		"#if !defined(SAFETY) && !defined(MA)",
			"#define FULLSTACK",
		"#endif",
	"#else",
		"#ifdef BITSTATE",
			"#ifdef SAFETY",
				"#define CNTRSTACK",
			"#else",
				"#define FULLSTACK",
			"#endif",
		"#else",
			"#define FULLSTACK",
		"#endif",
	"#endif",
	"#ifdef BITSTATE",
		"#define NOCOMP",
		"#if !defined(LC) && defined(SC)",
		"#define LC",
		"#endif",
	"#endif",
	"#ifndef MEMCNT",
		"#ifdef PC",
		"#define MEMCNT	25	/* 32 Mb */",
		"#else",
		"#define MEMCNT	28",
		"#endif",
	"#endif",

	"#if defined(COLLAPSE2) || defined(COLLAPSE3) || defined(COLLAPSE4)",
		"/* accept the above for backward compatibility */",
		"#define COLLAPSE",
	"#endif",
	"#ifdef HC",
	"#define HC2",
	"#endif",
	"#ifdef HC0",	/* 32 bits */
	"#define HC	0",
	"#endif",
	"#ifdef HC1",	/* 32+8 bits */
	"#define HC	1",
	"#endif",
	"#ifdef HC2",	/* 32+16 bits */
	"#define HC	2",
	"#endif",
	"#ifdef HC3",	/* 32+24 bits */
	"#define HC	3",
	"#endif",
	"#ifdef HC4",	/* 32+32 bits - combine with -DMA=8 */
	"#define HC	4",
	"#endif",
	"#ifdef COLLAPSE",
	"unsigned long ncomps[256+2];",
	"#endif",

	"#define MAXQ   	255",
	"#define MAXPROC	255",
	"#define WS		sizeof(long)   /* word size in bytes */",
	"typedef struct Stack  {	 /* for queues and processes */",
	"#if VECTORSZ>32000",
	"	int o_delta;",
	"	int o_offset;",
	"	int o_skip;",
	"	int o_delqs;",
	"#else",
	"	short o_delta;",
	"	short o_offset;",
	"	short o_skip;",
	"	short o_delqs;",
	"#endif",
	"	short o_boq;",
	"#ifndef XUSAFE",
	"	char *o_name;",
	"#endif",
	"	char *body;",
	"	struct Stack *nxt;",
	"	struct Stack *lst;",
	"} Stack;\n",
	"typedef struct Svtack { /* for complete state vector */",
	"#if VECTORSZ>32000",
	"	int o_delta;",
	"	int m_delta;",
	"#else",
	"	short o_delta;	 /* current size of frame */",
	"	short m_delta;	 /* maximum size of frame */",
	"#endif",
	"#if SYNC",
	"	short o_boq;",
	"#endif",
	"	char *body;",
	"	struct Svtack *nxt;",
	"	struct Svtack *lst;",
	"} Svtack;\n",
	"Trans ***trans;	/* 1 ptr per state per proctype */\n",
	"#if defined(FULLSTACK)",
	"struct H_el *Lstate;",
	"#endif",
	"int depthfound = -1;	/* loop detection */",
	"int proc_offset[MAXPROC], proc_skip[MAXPROC];",
	"int q_offset[MAXQ], q_skip[MAXQ];",
	"#if VECTORSZ<65536",
	"	unsigned short vsize;",
	"#else",
	"	unsigned long  vsize;	/* vector size in bytes */",
	"#endif",
	"#ifdef SVDUMP",
	"int vprefix=0, svfd;		/* runtime option -pN */",
	"#endif",
	"char *tprefix = \"trail\";	/* runtime option -tsuffix */",
	/* AVOIDED. HSFSPIN: boq in vector. */
	"#ifndef HSFSPIN",
	"short boq = -1;		/* blocked_on_queue status */",
	"#endif",
	/* AVOIDED. HSFSPIN:end. */
	0,
};

static char *Head1[] = {
        /* CHANGED. HSFSPIN: new name for State. */
#if 0
	"typedef struct State {",
#endif
	"#ifndef HSFSPIN",
	"typedef struct State {",
	"#else",
	"typedef struct PackedState {",
	"#endif",
	/* CHANGED. HSFSPIN: end. */
	"	uchar _nr_pr;",
	"	uchar _nr_qs;",
	/* NEW. HSFSPIN: boq must be in vector. */
	"	short boq;",
	/* NEW. HSFSPIN: end. */
	"	uchar   _a_t;	/* cycle detection */",
#if 0
	in _a_t: bits 0,4, and 5 =(1|16|32) are set during a 2nd dfs
	bit 1 is used as the A-bit for fairness
	bit 7 (128) is the proviso bit, for reduced 2nd dfs (acceptance)
#endif
	"#ifndef NOFAIR",
	"	uchar   _cnt[NFAIR];	/* counters, weak fairness */",
	"#endif",

	"#ifndef NOVSZ",
#ifdef SOLARIS
		"#if 0",
		/* v3.4
		 * noticed alignment problems with some Solaris
		 * compilers, if widest field isn't wordsized
		 */
#else
		"#if VECTORSZ<65536",
#endif
		"	unsigned short _vsz;",
		"#else",
		"	unsigned long  _vsz;",
		"#endif",
	"#endif",

	"#ifdef HAS_LAST",	/* cannot go before _cnt - see hstore() */
	"	uchar  _last;	/* pid executed in last step */",
	"#endif",
	"#ifdef EVENT_TRACE",
		"#if nstates_event<256",
	"	uchar _event;",
		"#else",
	"	unsigned short _event;",
		"#endif",
	"#endif",
	0,
};

static char *Addp0[] = {
	/* addproc(....parlist... */ ")",
	 /* CHANGED. HSFSPIN: now is a pointer and this is not a good name for C++. */
#if 0
	"{	int k, j, h = now._nr_pr;",
	"	uchar *o_this = this;\n",
#endif
	"{",			     
	"#ifndef HSFSPIN",
	"	int k, j, h = now._nr_pr;",
	"	uchar *o_this = this;\n",
	"#else",
	"	int k, j, h = now->_nr_pr;",
	"	uchar *o_this = this_p;\n",
	"#endif /* HSFSPIN */",
        /* CHANGED. HSFSPIN: end. */
	"#ifndef INLINE",
	"	if (TstOnly) return (h < MAXPROC);",
	"#endif",
	"#ifndef NOBOUNDCHECK",
	"/* redefine Index only within this procedure */",
	"#undef Index",
	"#define Index(x, y)	Boundcheck(x, y, 0, 0, 0)",
	"#endif",
	"	if (h >= MAXPROC)",
	"		Uerror(\"too many processes\");",
	"	switch (n) {",
	"	case 0: j = sizeof(P0); break;",
	0,
};

static char *Addp1[] = {
	"	default: Uerror(\"bad proc - addproc\");",
	"	}",
	"	if (vsize%%WS)",
	"		proc_skip[h] = WS-(vsize%%WS);",
	"	else",
	"		proc_skip[h] = 0;",
	"#ifndef NOCOMP",
	"	for (k = vsize + proc_skip[h]; k > vsize; k--)",
	"		Mask[k-1] = 1; /* align */",
	"#endif",
	"	vsize += proc_skip[h];",
	"	proc_offset[h] = vsize;",
	"#ifdef SVDUMP",
	"	if (vprefix > 0)",
	"	{	int dummy = 0;",
	"		write(svfd, (uchar *) &dummy, sizeof(int)); /* mark */",
	"		write(svfd, (uchar *) &h, sizeof(int));",
	"		write(svfd, (uchar *) &n, sizeof(int));",
	"		write(svfd, (uchar *) &proc_offset[h], sizeof(int));",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"		write(svfd, (uchar *) &now, vprefix-4*sizeof(int)); /* padd */",
#endif
	"#ifndef HSFSPIN",
	"		write(svfd, (uchar *) &now, vprefix-4*sizeof(int)); /* padd */",
	"#else",
	"		write(svfd, (uchar *) now, vprefix-4*sizeof(int)); /* padd */",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"	}",
	"#endif",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"	now._nr_pr += 1;",
	"	if (fairness && ((int) now._nr_pr + 1 >= (8*NFAIR)/2))",
#endif
	"#ifndef HSFSPIN",
	"	now._nr_pr += 1;",
	"	if (fairness && ((int) now._nr_pr + 1 >= (8*NFAIR)/2))",
	"#else",
	"	now->_nr_pr += 1;",
	"	if (fairness && ((int) now->_nr_pr + 1 >= (8*NFAIR)/2))",
	"#endif",
	/* CHANGED. HSFSPIN: end. */
	"	{	printf(\"Error: too many processes -- current\");",
	"		printf(\" max is %%d procs (-DNFAIR=%%d)\\n\",",
	"			(8*NFAIR)/2 - 2, NFAIR);",
	"		printf(\"\\trecompile with -DNFAIR=%%d\\n\",",
	"			NFAIR+1);",
	"		exit(1);",
	"	}",

	"	vsize += j;",
	"#ifndef NOVSZ",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"	now._vsz = vsize;",
#endif
	"#ifndef HSFSPIN",
	"	now._vsz = vsize;",
	"#else",
	"	now->_vsz = vsize;",
	"#endif",
	/* CHANGED. HSFSPIN: end. */
	"#endif",
	"#ifndef NOCOMP",
	"	for (k = 1; k <= Air[n]; k++)",
	"		Mask[vsize - k] = 1; /* pad */",
	"	Mask[vsize-j] = 1; /* _pid */",
	"#endif",
	/* CHANGED. HSFSPIN: max is not a good name. */
#if 0
	"	hmax = max(hmax, vsize);",
#endif
	"#ifndef HSFSPIN",
	"	hmax = max(hmax, vsize);",
	"#else",
	"	hmax = spin_max(hmax, vsize);",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"	if (vsize >= VECTORSZ)",
	"	{	printf(\"pan: error, VECTORSZ too small, recompile pan.c\");",
	"		printf(\" with -DVECTORSZ=N with N>%%d\\n\", vsize);",
	"		Uerror(\"aborting\");",
	"	}",
	"	memset((char *)pptr(h), 0, j);",
	/* CHANGED. HSFSPIN: this is not a good name. */
#if 0
	"	this = pptr(h);",
#endif
	"#ifndef HSFSPIN",
	"	this = pptr(h);",
	"#else",
	"	this_p = pptr(h);",
	"#endif",
	/* CHANGED. HSFSPIN: end. */
	"	if (BASE > 0 && h > 0)",
	/* CHANGED. HSFSPIN: this is not a good name. */
#if 0
	"		((P0 *)this)->_pid = h-BASE;",
	"	else",
	"		((P0 *)this)->_pid = h;",
#endif
	"#ifndef HSFSPIN",
	"		((P0 *)this)->_pid = h-BASE;",
	"	else",
	"		((P0 *)this)->_pid = h;",
	"#else",
	"		((P0 *)this_p)->_pid = h-BASE;",
	"	else",
	"		((P0 *)this_p)->_pid = h;",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"	switch (n) {",
	0,
};

static char *Addq0[] = {
	"int",
	"addqueue(int n, int is_rv)",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"{	int j=0, i = now._nr_qs, k;\n",
#endif
	"#ifndef HSFSPIN",
	"{	int j=0, i = now._nr_qs, k;\n",
	"#else",
	"{	int j=0, i = now->_nr_qs, k;\n",
	"#endif",
	/* CHANGED. HSFSPIN: end. */
	"	if (i >= MAXQ)",
	"		Uerror(\"too many queues\");",
	"	switch (n) {",
	0,
};

static char *Addq1[] = {
	"	default: Uerror(\"bad queue - addqueue\");",
	"	}",
	"	if (vsize%%WS)",
	"		q_skip[i] = WS-(vsize%%WS);",
	"	else",
	"		q_skip[i] = 0;",
	"#ifndef NOCOMP",
	"	k = vsize; if (is_rv) k += j;",
	"	for (k += q_skip[i]; k > vsize; k--)",
	"		Mask[k-1] = 1; /* align */",
	"#endif",
	"	vsize += q_skip[i];",
	"	q_offset[i] = vsize;",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"	now._nr_qs += 1;",
#endif
	"#ifndef HSFSPIN",
	"	now._nr_qs += 1;",
	"#else",
	"	now->_nr_qs += 1;",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"	vsize += j;",
	"#ifndef NOVSZ",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"	now._vsz = vsize;",
#endif
	"#ifndef HSFSPIN",
	"	now._vsz = vsize;",
	"#else",
	"	now->_vsz = vsize;",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"#endif",
	/* CHANGED. HSFSPIN: max is not a good name. */
#if 0
	"	hmax = max(hmax, vsize);",
#endif
	"#ifndef HSFSPIN",
	"	hmax = max(hmax, vsize);",
	"#else",
	"	hmax = spin_max(hmax, vsize);",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"	if (vsize >= VECTORSZ)",
	"		Uerror(\"VECTORSZ is too small, edit pan.h\");",
	"	memset((char *)qptr(i), 0, j);",
	"	((Q0 *)qptr(i))->_t = n;",
	"	return i+1;",
	"}\n",
	0,
};

static char *Addq11[] = {
	"{	int j, k; uchar *z;\n",
	"	if (!into--)",
	"	uerror(\"ref to uninitialized chan name (sending)\");",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"	if (into >= (int) now._nr_qs || into < 0)",
#endif
	"#ifndef HSFSPIN",
	"	if (into >= (int) now._nr_qs || into < 0)",
	"#else",
	"	if (into >= (int) now->_nr_qs || into < 0)",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"		Uerror(\"qsend bad queue#\");",
	"	z = qptr(into);",
	"	j = ((Q0 *)qptr(into))->Qlen;",
	"	switch (((Q0 *)qptr(into))->_t) {",
	0,
};

static char *Addq2[] = {
	"	case 0: printf(\"queue %%d was deleted\\n\", into+1);",
	"	default: Uerror(\"bad queue - qsend\");",
	"	}",
	"#ifdef EVENT_TRACE",
	"	if (in_s_scope(into+1))",
	"		require('s', into);",
	"#endif",
	"}\n",
	"#if SYNC",
	"int",
	"q_zero(int from)",
	"{	if (!from--)",
	"	uerror(\"ref to uninitialized chan name (q_zero)\");",
	"	switch(((Q0 *)qptr(from))->_t) {",
	0,
};

static char *Addq3[] = {
	"	case 0: printf(\"queue %%d was deleted\\n\", from+1);",
	"	}",
	"	Uerror(\"bad queue q-zero\");",
	"	return -1;",
	"}",
	"int",
	"not_RV(int from)",
	"{	if (q_zero(from))",
	"	{	printf(\"==>> a test of the contents of a rv \");",
	"		printf(\"channel always returns FALSE\\n\");",
	"		uerror(\"error to poll rendezvous channel\");",
	"	}",
	"	return 1;",
	"}",
	"#endif",
	"#ifndef XUSAFE",
	"void",
	"setq_claim(int x, int m, char *s, int y, char *p)",
	"{	if (x == 0)",
	"	uerror(\"x[rs] claim on uninitialized channel\");",
	"	if (x < 0 || x > MAXQ)",
	"		Uerror(\"cannot happen setq_claim\");",
	"	q_claim[x] |= m;",
	"	p_name[y] = p;",
	"	q_name[x] = s;",
	"	if (m&2) q_S_check(x, y);",
	"	if (m&1) q_R_check(x, y);",
	"}",
	"short q_sender[MAXQ+1];",
	"int",
	"q_S_check(int x, int who)",
	"{	if (!q_sender[x])",
	"	{	q_sender[x] = who+1;",
	"#if SYNC",
	"		if (q_zero(x))",
	"		{	printf(\"chan %%s (%%d), \",",
	"				q_name[x], x-1);",
	"			printf(\"sndr proc %%s (%%d)\\n\",",
	"				p_name[who], who);",
	"			uerror(\"xs chans cannot be used for rv\");",
	"		}",
	"#endif",
	"	} else",
	"	if (q_sender[x] != who+1)",
	"	{	printf(\"pan: xs assertion violated: \");",
	"		printf(\"access to chan <%%s> (%%d)\\npan: by \",",
	"			q_name[x], x-1);",
	"		printf(\"%%s (proc %%d) and by %%s (proc %%d)\\n\",",
	"			p_name[q_sender[x]-1], q_sender[x]-1,",
	"			p_name[who], who);",
	"		uerror(\"error, partial order reduction invalid\");",
	"	}",
	"	return 1;",
	"}",
	"short q_recver[MAXQ+1];",
	"int",
	"q_R_check(int x, int who)",
	"{	if (!q_recver[x])",
	"	{	q_recver[x] = who+1;",
	"#if SYNC",
	"		if (q_zero(x))",
	"		{	printf(\"chan %%s (%%d), \",",
	"				q_name[x], x-1);",
	"			printf(\"recv proc %%s (%%d)\\n\",",
	"				p_name[who], who);",
	"			uerror(\"xr chans cannot be used for rv\");",
	"		}",
	"#endif",
	"	} else",
	"	if (q_recver[x] != who+1)",
	"	{	printf(\"pan: xr assertion violated: \");",
	"		printf(\"access to chan %%s (%%d)\\n\",",
	"			q_name[x], x-1);",
	"		printf(\"pan: by %%s (proc %%d) \",",
	"			p_name[q_recver[x]-1], q_recver[x]-1);",
	"		printf(\"and by %%s (proc %%d)\\n\",",
	"			p_name[who], who);",
	"		uerror(\"error, partial order reduction invalid\");",
	"	}",
	"	return 1;",
	"}",
	"#endif",
	"int",
	"q_len(int x)",
	"{	if (!x--)",
	"	uerror(\"ref to uninitialized chan name (len)\");",
	"	return ((Q0 *)qptr(x))->Qlen;",
	"}\n",
	"int",
	"q_full(int from)",
	"{	if (!from--)",
	"	uerror(\"ref to uninitialized chan name (qfull)\");",
	"	switch(((Q0 *)qptr(from))->_t) {",
	0,
};

static char *Addq4[] = {
	"	case 0: printf(\"queue %%d was deleted\\n\", from+1);",
	"	}",
	"	Uerror(\"bad queue - q_full\");",
	"	return 0;",
	"}\n",
	"#ifdef HAS_UNLESS",
	"int",
	"q_e_f(int from)",
	"{	/* empty or full */",
	"	return !q_len(from) || q_full(from);",
	"}",
	"#endif",
	"int",
	"qrecv(int from, int slot, int fld, int done)",
	"{	uchar *z;",
	"	int j, k, r=0;\n",
	"	if (!from--)",
	"	uerror(\"ref to uninitialized chan name (receiving)\");",
	/* CHANGED. HSFSPIN: now is a pointer. */
#if 0
	"	if (from >= (int) now._nr_qs || from < 0)",
#endif
	"#ifndef HSFSPIN",
	"	if (from >= (int) now._nr_qs || from < 0)",
	"#else",
	"	if (from >= (int) now->_nr_qs || from < 0)",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"		Uerror(\"qrecv bad queue#\");",
	"	z = qptr(from);",
	"#ifdef EVENT_TRACE",
	"	if (done && (in_r_scope(from+1)))",
	"		require('r', from);",
	"#endif",
	"	switch (((Q0 *)qptr(from))->_t) {",
	0,
};

static char *Addq5[] = {
	"	case 0: printf(\"queue %%d was deleted\\n\", from+1);",
	"	default: Uerror(\"bad queue - qrecv\");",
	"	}",
	"	return r;",
	"}\n",
	"#ifndef BITSTATE",
	"#ifdef COLLAPSE",
	"long",
	"col_q(int i, char *z)",
	"{	int j, k;",
	"	char *x, *y;",
	"	Q0 *ptr = (Q0 *) qptr(i);",
	"	switch (ptr->_t) {",
	0,
};

static char *Code0[] = {
	"void",
	"run(void)",
	/* CHANGED. HSFSPIN. */
#if 0
	"{	int i;",
	"	memset((char *)&now, 0, sizeof(State));",
	"	vsize = sizeof(State) - VECTORSZ;",
	"#ifndef NOVSZ",
	"	now._vsz = vsize;",
	"#endif",
	"/* optional provisioning statements, e.g. to */",
	"/* set hidden variables, used as constants */",
	"#ifdef PROV",
	"#include PROV",
	"#endif",
#endif
	"{",
	"#ifndef HSFSPIN",
	"	int i;",
	"	memset((char *)&now, 0, sizeof(State));",
	"	vsize = sizeof(State) - VECTORSZ;",
	"#ifndef NOVSZ",
	"	now._vsz = vsize;",
	"#endif",
	"/* optional provisioning statements, e.g. to */",
	"/* set hidden variables, used as constants */",
	"#ifdef PROV",
	"#include PROV",
	"#endif",
	"#else",
	"",
	"       noptr=new unsigned char[VECTORSZ];",
	"       memset(noptr,VECTORSZ,0);",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"	settable();",
	0,
};

static char *R0[] = {
        /* CHANGED. HSFSPIN: max is not a good name, do not use emalloc(), dangerous table. */
#if 0
	"	Maxbody = max(Maxbody, sizeof(P%d));",
	"	reached[%d] = reached%d;",
	"	accpstate[%d] = (uchar *) emalloc(nstates%d);",
	"	progstate[%d] = (uchar *) emalloc(nstates%d);",
	"	stopstate[%d] = (uchar *) emalloc(nstates%d);",
	"	visstate[%d] = (uchar *) emalloc(nstates%d);",
	"	stopstate[%d][endstate%d] = 1;",
#endif
	"#ifndef HSFSPIN /* may appear several times */",
	"	Maxbody = max(Maxbody, sizeof(P%d));",
	"	reached[%d] = reached%d;",
	"	accpstate[%d] = (uchar *) emalloc(nstates%d);",
	"	progstate[%d] = (uchar *) emalloc(nstates%d);",
	"	stopstate[%d] = (uchar *) emalloc(nstates%d);",
	"	visstate[%d] = (uchar *) emalloc(nstates%d);",
	"	stopstate[%d][endstate%d] = 1;",
	"#endif /* may appear several times */",
	"#ifdef HSFSPIN /* may appear several times */",
	"	Maxbody = spin_max(Maxbody, sizeof(P%d));",
	"       reached[%d] = reached%d;",
	"	accpstate[%d] = new unsigned char[nstates%d];",
	"       memset(accpstate[%d], 0, nstates%d);",
	"	progstate[%d] = new unsigned char[nstates%d];",
	"       memset(progstate[%d], 0, nstates%d);",
	"	stopstate[%d] = new unsigned char[nstates%d];",
	"       memset(stopstate[%d], 0, nstates%d);",
	"	visstate[%d] = new unsigned char[nstates%d];",
	"       memset(visstate[%d], 0, nstates%d);",
	"	stopstate[%d][endstate%d] = 1;",
	"	dangstate[%d] = new unsigned char[nstates%d];",
	"       memset(dangstate[%d], 0, nstates%d);",	
	"#endif /* HSFSPIN */ /* may appear several times */",
	/* CHANGED. HSFSPIN: end. */
	0,
};

static char *R0a[] = {
	"	retrans(%d, nstates%d, start%d, src_ln%d, reached%d);",
	0,
};
static char *R0b[] = {
	"	if (state_tables)",
	"	{ printf(\"\\nTransition Type: \");",
	"	  printf(\"A=atomic; D=d_step; L=local; G=global\\n\");",
	"	  printf(\"Source-State Labels: \");",
	"	  printf(\"p=progress; e=end; a=accept;\\n\");",
	"#ifdef MERGED",
	"	  printf(\"Note: statement merging was used. Only the first\\n\");",
	"	  printf(\"      stmnt executed in each merge sequence is shown\\n\");",
	"	  printf(\"      (use spin -a -o3 to disable statement merging)\\n\");",
	"#endif",
	"	  exit(0);",
	"	}",
	0,
};

static char *Code1[] = {
	"#ifdef NP",
	"#define ACCEPT_LAB	1 /* at least 1 in np_ */",
	"#else",
	"#define ACCEPT_LAB	%d /* user-defined accept labels */",
	"#endif",
	0,
};

static char *Code3[] = {
	"#define PROG_LAB	%d /* progress labels */",
	0,
};

static char *R2[] = {
	"uchar *accpstate[%d];",
	"uchar *progstate[%d];",
	"uchar *reached[%d];",
	"uchar *stopstate[%d];",
	"uchar *visstate[%d];",
	/* NEW. HSFSPIN: dangerous states table. */
	"#ifdef HSFSPIN",
	"uchar *dangstate[%d];",
	"#endif /* HSFSPIN */",
	/* NEW. HSFSPIN: end. */
	0,
};
static char *R3[] = {
        /* CHANGED. HSFSPIN: max is not a good name. */
#if 0
	"	Maxbody = max(Maxbody, sizeof(Q%d));",
#endif
	"#ifndef HSFSPIN /* may appear several times */",
	"	Maxbody = max(Maxbody, sizeof(Q%d));",
	"#endif /* may appear several times */",
	"#if HSF-SPIN /* may appear several times */",
	"	Maxbody = spin_max(Maxbody, sizeof(Q%d));",
	"#endif",
	/* CHANGED. HSFSPIN: end. */
	0,
};
static char *R4[] = {
	"	r_ck(reached%d, nstates%d, %d, src_ln%d, src_file%d);",
	0,
};
static char *R5[] = {
	"	case %d: j = sizeof(P%d); break;",
	0,
};
static char *R6[] = {
	"	}",
	/* CHANGED. HSFSPIN: this is not a good name in C++. */
#if 0
	"	this = o_this;",
#endif
	"#ifndef HSFSPIN",
	"	this = o_this;",
	"#else",
	"	this_p = o_this;",
	"#endif /* HSFSPIN */",
	/* CHANGED. HSFSPIN: end. */
	"	return h-BASE;",
	"#ifndef NOBOUNDCHECK",
	"#undef Index",
	"#define Index(x, y)	Boundcheck(x, y, II, tt, t)",
	"#endif",
	"}\n",
	"#if defined(BITSTATE) && defined(COLLAPSE)",
	"/* just to allow compilation, to generate the error */",
	"long col_p(int i, char *z) { return 0; }",
	"long col_q(int i, char *z) { return 0; }",
	"#endif",
	"#ifndef BITSTATE",
	"#ifdef COLLAPSE",
	"long",
	"col_p(int i, char *z)",
	"{	int j, k; unsigned long ordinal(char *, long, short);",
	"	char *x, *y;",
	"	P0 *ptr = (P0 *) pptr(i);",
	"	switch (ptr->_t) {",
	"	case 0: j = sizeof(P0); break;",
	0,
};
static char *R8a[] = {
	"	default: Uerror(\"bad proctype - collapse\");",
	"	}",
	"	if (z) x = z; else x = scratch;",
	"	y = (char *) ptr; k = proc_offset[i];",

	"	for ( ; j > 0; j--, y++)",
	"		if (!Mask[k++]) *x++ = *y;",
	"	if (z) return (long) (x - z);",

	"	for (j = 0; j < WS-1; j++)",
	"		*x++ = 0;",
	"	x -= j;",

	"	return ordinal(scratch, x-scratch, 2+ptr->_t);",
	"}",
	"#endif",
	"#endif",
	0,
};
static char *R8b[] = {
	"	default: Uerror(\"bad qtype - collapse\");",
	"	}",
	"	if (z) x = z; else x = scratch;",
	"	y = (char *) ptr; k = q_offset[i];",

	"	/* no need to store the empty slots at the end */",
	"	j -= (q_max[ptr->_t] - ptr->Qlen) * ((j - 2)/q_max[ptr->_t]);",

	"	for ( ; j > 0; j--, y++)",
	"		if (!Mask[k++]) *x++ = *y;",
	"	if (z) return (long) (x - z);",

	"	for (j = 0; j < WS-1; j++)",
	"		*x++ = 0;",
	"	x -= j;",
	"	return ordinal(scratch, x-scratch, 1); /* chan */",
	"}",
	"#endif",
	"#endif",
	0,
};
static char *R9[] = {
	"typedef struct Q%d {",
	"	uchar Qlen;	/* q_size */",
	"	uchar _t;	/* q_type */",
	"	struct {",
	0,
};
static char *R10[] = {
	"typedef struct Q0 {\t/* generic q */",
	"	uchar Qlen, _t;",
	/* NEW. HSFSPIN. */
	"#ifdef HSFSPIN",
	"       struct {",
	"              uchar fld0;",
	"       } contents[1];",	
	"#endif",
	/* NEW. HSFSPIN: end. */
	"} Q0;",
	0,
};
static char *R12[] = {
	"\t\tcase %d: r = ((Q%d *)z)->contents[slot].fld%d; break;",
	0,
};
char *R13[] = {
        /* AVOIDED. HSFSPIN: unnecessary things. */
        "#ifndef HSFSPIN",
	"int ",
	"unsend(int into)",
	"{	int m=0, j, k; uchar *z;\n",
	"	if (!into--)",
	"		uerror(\"ref to uninitialized chan (unsend)\");",
	"	z = qptr(into);",
	"	j = ((Q0 *)z)->Qlen;",
	"	((Q0 *)z)->Qlen = --j;",
	"	switch (((Q0 *)qptr(into))->_t) {",
	0,
};
char *R14[] = {
	"	default: Uerror(\"bad queue - unsend\");",
	"	}",
	"	return m;",
	"}\n",
	"void",
	"unrecv(int from, int slot, int fld, int fldvar, int strt)",
	"{	int j; uchar *z;\n",
	"	if (!from--)",
	"		uerror(\"ref to uninitialized chan (unrecv)\");",
	"	z = qptr(from);",
	"	j = ((Q0 *)z)->Qlen;",
	"	if (strt) ((Q0 *)z)->Qlen = j+1;",
	"	switch (((Q0 *)qptr(from))->_t) {",
	0,
};
char *R15[] = {
	"	default: Uerror(\"bad queue - qrecv\");",
	"	}",
	"}",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	0,
};
static char *Proto[] = {
	"",
	"/** function prototypes **/",
	/* AVOIDED. HSFSPIN: do not use emalloc(). */
	"#ifndef HSFSPIN",
       	"char *emalloc(unsigned long);",
	"char *Malloc(unsigned long);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"int Boundcheck(int, int, int, int, Trans *);",
	"/* int abort(void); */",
	"int addqueue(int, int);",
	"/* int atoi(char *); */",
	"int close(int);",
#ifndef PC
	"int creat(char *, unsigned short);",
	"int write(int, void *, unsigned);",
#endif
	"int delproc(int, int);",
	"int endstate(void);",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"int hstore(char *, int, short);",
"#ifdef MA",
	"int gstore(char *, int, uchar);",
"#endif",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"int q_cond(short, Trans *);",
	"int q_full(int);",
	"int q_len(int);",
	"int q_zero(int);",
	/* NEW. HSFSPIN: need declaration before use in do_transit(). */
	"#ifdef HSFSPIN",
	"#if SYNC",
	"int not_RV(int from);",
	"#endif",
	"#endif /* HSFSPIN */",
	/* NEW. HSFSPIN: end. */
	"int qrecv(int, int, int, int);",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"int unsend(int);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"void *sbrk(int);",
	"void Uerror(char *);",
	"void assert(int, char *, int, int, Trans *);",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"void checkcycles(void);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"void crack(int, int, Trans *, short *);",
	"void d_hash(uchar *, int);",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"void delq(int);",
	"void do_reach(void);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"void exit(int);",
	"void hinit(void);",
	"void imed(Trans *, int, int);",
	"void new_state(void);",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"void p_restor(int);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"void putpeg(int, int);",
	"void putrail(void);",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"void q_restor(void);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"void retrans(int, int, int, short *, uchar *);",
	"void settable(void);",
	"void setq_claim(int, int, char *, int, char *);",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"void sv_restor(void);",
	"void sv_save(char *);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"void tagtable(int, int, int, short *, uchar *);",
	"void uerror(char *);",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"void unrecv(int, int, int, int, int);",
	"void usage(FILE *);",
	"void wrap_stats(void);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"void xrefsrc(int, S_F_MAP *, int, int);",
	"#if defined(FULLSTACK) && defined(BITSTATE)",
	/* AVOIDED. HSFSPIN: unnecessary things. */
	"#ifndef HSFSPIN",
	"int  onstack_now(void);",
	"void onstack_init(void);",
	"void onstack_put(void);",
	"void onstack_zap(void);",
	"#endif /* HSFSPIN */",
	/* AVOIDED. HSFSPIN: end. */
	"#endif",
	"#ifndef XUSAFE",
	"int q_S_check(int, int);",
	"int q_R_check(int, int);",
	"uchar q_claim[MAXQ+1];",
	"char *q_name[MAXQ+1];",
	"char *p_name[MAXPROC+1];",
	"#endif",
	0,
};

static char *SvMap[] = {
	"void",
	"to_compile(void)",
	"{	char ctd[1024], carg[64]; int n;",
	"#ifdef BITSTATE",
	"	strcpy(ctd, \"-DBITSTATE \");",
	"#else",
	"	strcpy(ctd, \"\");",
	"#endif",
	"#ifdef PC",
	"	strcat(ctd, \"-DPC \");",
	"#endif",
	"#ifdef NOVSZ",
	"	strcat(ctd, \"-DNOVSZ \");",
	"#endif",
	"#ifdef MEMCNT",
		"#ifdef PC",
		"	n = 25;",
		"#else",
		"	n = 28;",
		"#endif",
	"	if (MEMCNT != n)",
	"	{	sprintf(carg, \"-DMEMCNT=%%d \", MEMCNT);",
	"		strcat(ctd, carg);",
	"	}",
	"#endif",
	"#ifdef MEMLIM",
	"	sprintf(carg, \"-DMEMLIM=%%d \", MEMLIM);",
	"	strcat(ctd, carg);",
	"#endif",
	"#ifdef NOCLAIM",
	"	strcat(ctd, \"-DNOCLAIM \");",
	"#endif",
	"#ifdef SAFETY",
	"	strcat(ctd, \"-DSAFETY \");",
	"#else",
		"#ifdef NOFAIR",
		"	strcat(ctd, \"-DNOFAIR \");",
		"#else",
			"#ifdef NFAIR",
		"	if (NFAIR != 2)",
		"	{	sprintf(carg, \"-DNFAIR=%%d \", NFAIR);",
		"		strcat(ctd, carg);",
		"	}",
			"#endif",
		"#endif",
	"#endif",
	"#ifdef NOREDUCE",
	"	strcat(ctd, \"-DNOREDUCE \");",
	"#else",
		"#ifdef XUSAFE",
		"	strcat(ctd, \"-DXUSAFE \");",
		"#endif",
	"#endif",
	"#ifdef NP",
	"	strcat(ctd, \"-DNP \");",
	"#endif",
	"#ifdef PEG",
	"	strcat(ctd, \"-DPEG \");",
	"#endif",
	"#ifdef VAR_RANGES",
	"	strcat(ctd, \"-DVAR_RANGES \");",
	"#endif",
	"#ifdef HC0",
	"	strcat(ctd, \"-DHC0 \");",
	"#endif",
	"#ifdef HC1",
	"	strcat(ctd, \"-DHC1 \");",
	"#endif",
	"#ifdef HC2",
	"	strcat(ctd, \"-DHC2 \");",
	"#endif",
	"#ifdef HC3",
	"	strcat(ctd, \"-DHC3 \");",
	"#endif",
	"#ifdef HC4",
	"	strcat(ctd, \"-DHC4 \");",
	"#endif",
	"#ifdef CHECK",
	"	strcat(ctd, \"-DCHECK \");",
	"#endif",
	"#ifdef CTL",
	"	strcat(ctd, \"-DCTL \");",
	"#endif",
	"#ifdef NIBIS",
	"	strcat(ctd, \"-DNIBIS \");",
	"#endif",
	"#ifdef NOBOUNDCHECK",
	"	strcat(ctd, \"-DNOBOUNDCHECK \");",
	"#endif",
	"#ifdef NOSTUTTER",
	"	strcat(ctd, \"-DNOSTUTTER \");",
	"#endif",
	"#ifdef REACH",
	"	strcat(ctd, \"-DREACH \");",
	"#endif",
	"#ifdef PRINTF",
	"	strcat(ctd, \"-DPRINTF \");",
	"#endif",
	"#ifdef OTIM",
	"	strcat(ctd, \"-DOTIM \");",
	"#endif",
	"#ifdef COLLAPSE",
	"	strcat(ctd, \"-DCOLLAPSE \");",
	"#endif",
	"#ifdef SVDUMP",
	"	strcat(ctd, \"-DSVDUMP \");",
	"#endif",
	"#ifdef VECTORSZ",
	"	if (VECTORSZ != 1024)",
	"	{	sprintf(carg, \"-DVECTORSZ=%%d \", VECTORSZ);",
	"		strcat(ctd, carg);",
	"	}",
	"#endif",
	"#ifdef VERBOSE",
	"	strcat(ctd, \"-DVERBOSE \");",
	"#endif",
	"#ifdef CHECK",
	"	strcat(ctd, \"-DCHECK \");",
	"#endif",
	"#ifdef SDUMP",
	"	strcat(ctd, \"-DSDUMP \");",
	"#endif",
	"#ifdef COVEST",
	"		strcat(ctd, \"-DCOVEST \");",
	"#endif",
	"		printf(\"Compiled as: cc -o pan %%span.c\", ctd);",
	"#if defined(COVEST) && defined(BITSTATE)",
	"		printf(\" -lm\\n\");",
	"#else",
	"		printf(\"\\n\");",
	"#endif",
	"}",
	0,
};
