xref: /plan9-contrib/sys/src/cmd/spin/msc_tcl.c (revision de2caf28f9ba1a56e70be94a699435d36eb50311)
1*de2caf28SDavid du Colombier /***** spin: msc_tcl.c *****/
2*de2caf28SDavid du Colombier 
3*de2caf28SDavid du Colombier /*
4*de2caf28SDavid du Colombier  * This file is part of the public release of Spin. It is subject to the
5*de2caf28SDavid du Colombier  * terms in the LICENSE file that is included in this source directory.
6*de2caf28SDavid du Colombier  * Tool documentation is available at http://spinroot.com
7*de2caf28SDavid du Colombier  */
8*de2caf28SDavid du Colombier 
9*de2caf28SDavid du Colombier #include <stdlib.h>
10*de2caf28SDavid du Colombier #include "spin.h"
11*de2caf28SDavid du Colombier #include "version.h"
12*de2caf28SDavid du Colombier 
13*de2caf28SDavid du Colombier #define MW	500	/* page width */
14*de2caf28SDavid du Colombier #define RH	100	/* right margin */
15*de2caf28SDavid du Colombier #define WW	 80	/* distance between process lines */
16*de2caf28SDavid du Colombier #define HH	 12	/* vertical distance between steps */
17*de2caf28SDavid du Colombier #define LW	  2	/* line width of message arrows */
18*de2caf28SDavid du Colombier 
19*de2caf28SDavid du Colombier #define RVC	"darkred"	/* rendezvous arrows */
20*de2caf28SDavid du Colombier #define MPC	"darkblue"	/* asynchronous message passing arrow */
21*de2caf28SDavid du Colombier #define GRC	"lightgrey"	/* grid lines */
22*de2caf28SDavid du Colombier 
23*de2caf28SDavid du Colombier static int	MH = 600;	/* anticipated page-length */
24*de2caf28SDavid du Colombier static FILE	*pfd;
25*de2caf28SDavid du Colombier static char	**I;		/* initial procs */
26*de2caf28SDavid du Colombier static int	*D,*R;		/* maps between depth (stepnr) and ldepth (msc-step) */
27*de2caf28SDavid du Colombier static short	*M;		/* x location of each box at index y */
28*de2caf28SDavid du Colombier static short	*T;		/* y index of match for each box at index y */
29*de2caf28SDavid du Colombier static char	**L;		/* text labels */
30*de2caf28SDavid du Colombier static int	ProcLine[256];	/* active processes */
31*de2caf28SDavid du Colombier static int	UsedLine[256];	/* process line has at least one entry */
32*de2caf28SDavid du Colombier static int	ldepth = 1;
33*de2caf28SDavid du Colombier static int	maxx, TotSteps = 2*4096; /* max nr of steps for simulation output */
34*de2caf28SDavid du Colombier static float	Scaler = (float) 1.0;
35*de2caf28SDavid du Colombier 
36*de2caf28SDavid du Colombier static int	xscale = 2;
37*de2caf28SDavid du Colombier static int	yscale = 1;
38*de2caf28SDavid du Colombier static int	no_box;
39*de2caf28SDavid du Colombier 
40*de2caf28SDavid du Colombier extern int	ntrail, s_trail, prno, depth;
41*de2caf28SDavid du Colombier extern short	Have_claim;
42*de2caf28SDavid du Colombier extern Symbol	*oFname;
43*de2caf28SDavid du Colombier 
44*de2caf28SDavid du Colombier extern void	exit(int);
45*de2caf28SDavid du Colombier extern void	putpostlude(void);
46*de2caf28SDavid du Colombier 
47*de2caf28SDavid du Colombier static void	putpages(void);
48*de2caf28SDavid du Colombier 
49*de2caf28SDavid du Colombier static void
psline(int x0,int y0,int x1,int y1,char * color)50*de2caf28SDavid du Colombier psline(int x0, int y0, int x1, int y1, char *color)
51*de2caf28SDavid du Colombier {	char *side = "last";
52*de2caf28SDavid du Colombier 
53*de2caf28SDavid du Colombier 	if (x0 == x1)	/* gridline */
54*de2caf28SDavid du Colombier 	{	fprintf(pfd, ".c create line %d %d %d %d -fill %s -tags grid -width 1 \n",
55*de2caf28SDavid du Colombier 			xscale*(x0+1)*WW-20, yscale*y0+20,
56*de2caf28SDavid du Colombier 			xscale*(x1+1)*WW-20, yscale*y1+20, color);
57*de2caf28SDavid du Colombier 		fprintf(pfd, ".c lower grid\n");
58*de2caf28SDavid du Colombier 	} else
59*de2caf28SDavid du Colombier 	{	int xm = xscale*(x0+1)*WW + (xscale*(x1 - x0)*WW)/2 - 20;	/* mid x */
60*de2caf28SDavid du Colombier 
61*de2caf28SDavid du Colombier 		if (y1 - y0  <= HH+20)
62*de2caf28SDavid du Colombier 		{	y1 = y0+20; /* close enough to horizontal - looks better */
63*de2caf28SDavid du Colombier 		}
64*de2caf28SDavid du Colombier 
65*de2caf28SDavid du Colombier 		fprintf(pfd, ".c create line %d %d %d %d -fill %s -tags mesg -width %d\n",
66*de2caf28SDavid du Colombier 			xscale*(x0+1)*WW-20, yscale*y0+20+10,
67*de2caf28SDavid du Colombier 			xm,                  yscale*y0+20+10, color, LW);
68*de2caf28SDavid du Colombier 
69*de2caf28SDavid du Colombier 		if (y1 != y0+20)
70*de2caf28SDavid du Colombier 		{	fprintf(pfd, ".c create line %d %d %d %d -fill %s -tags mesg -width %d\n",
71*de2caf28SDavid du Colombier 				xm, yscale*y0+20+10,
72*de2caf28SDavid du Colombier 				xm, yscale*y1+20-10, color, LW);
73*de2caf28SDavid du Colombier 		}
74*de2caf28SDavid du Colombier 
75*de2caf28SDavid du Colombier 		fprintf(pfd, ".c create line %d %d %d %d -fill %s -width %d ",
76*de2caf28SDavid du Colombier 			xm,                  yscale*y1+20-10,
77*de2caf28SDavid du Colombier 			xscale*(x1+1)*WW-20, yscale*y1+20-10, color, LW);
78*de2caf28SDavid du Colombier 
79*de2caf28SDavid du Colombier 		if (strcmp(color, RVC) == 0)
80*de2caf28SDavid du Colombier 		{	side = "both";
81*de2caf28SDavid du Colombier 		}
82*de2caf28SDavid du Colombier 		fprintf(pfd, "-arrow %s -arrowshape {5 5 5} -tags mesg\n", side);
83*de2caf28SDavid du Colombier 		fprintf(pfd, ".c raise mesg\n");
84*de2caf28SDavid du Colombier 	}
85*de2caf28SDavid du Colombier }
86*de2caf28SDavid du Colombier 
87*de2caf28SDavid du Colombier static void
colbox(int ix,int iy,int w,int h_unused,char * color)88*de2caf28SDavid du Colombier colbox(int ix, int iy, int w, int h_unused, char *color)
89*de2caf28SDavid du Colombier {	int x = ix*WW;
90*de2caf28SDavid du Colombier 	int y = iy*HH;
91*de2caf28SDavid du Colombier 
92*de2caf28SDavid du Colombier 	if (ix < 0 || ix > 255)
93*de2caf28SDavid du Colombier 	{	fprintf(stderr, "saw ix=%d\n", ix);
94*de2caf28SDavid du Colombier 		fatal("msc_tcl: unexpected\n", (char *) 0);
95*de2caf28SDavid du Colombier 	}
96*de2caf28SDavid du Colombier 
97*de2caf28SDavid du Colombier 	if (ProcLine[ix] < iy)
98*de2caf28SDavid du Colombier 	{	/* if (ProcLine[ix] > 0) */
99*de2caf28SDavid du Colombier 		{	psline(ix-1, ProcLine[ix]*HH+HH+4,
100*de2caf28SDavid du Colombier 			       ix-1, iy*HH-HH, GRC);
101*de2caf28SDavid du Colombier 		}
102*de2caf28SDavid du Colombier 		fprintf(pfd, "# ProcLine[%d] from %d to %d (Used %d nobox %d)\n",
103*de2caf28SDavid du Colombier 			ix, ProcLine[ix], iy, UsedLine[ix], no_box);
104*de2caf28SDavid du Colombier 		ProcLine[ix] = iy;
105*de2caf28SDavid du Colombier 	} else
106*de2caf28SDavid du Colombier 	{	fprintf(pfd, "# ProcLine[%d] stays at %d (Used %d nobox %d)\n",
107*de2caf28SDavid du Colombier 			ix, ProcLine[ix], UsedLine[ix], no_box);
108*de2caf28SDavid du Colombier 	}
109*de2caf28SDavid du Colombier 
110*de2caf28SDavid du Colombier 	if (UsedLine[ix])
111*de2caf28SDavid du Colombier 	{	no_box = 2;
112*de2caf28SDavid du Colombier 	}
113*de2caf28SDavid du Colombier 
114*de2caf28SDavid du Colombier 	if (strcmp(color, "black") == 0)
115*de2caf28SDavid du Colombier 	{	if (no_box == 0)	/* shadow */
116*de2caf28SDavid du Colombier 		{	fprintf(pfd, ".c create rectangle %d %d %d %d -fill black\n",
117*de2caf28SDavid du Colombier 				xscale*x-(xscale*4*w/3)-20+4, (yscale*y-10)+20+2,
118*de2caf28SDavid du Colombier 				xscale*x+(xscale*4*w/3)-20,   (yscale*y+10)+20+2);
119*de2caf28SDavid du Colombier 		}
120*de2caf28SDavid du Colombier 	} else
121*de2caf28SDavid du Colombier 	{	if (no_box == 0)	/* box with outline */
122*de2caf28SDavid du Colombier 		{	fprintf(pfd, ".c create rectangle %d %d %d %d -fill ivory\n",
123*de2caf28SDavid du Colombier 				xscale*x-(xscale*4*w/3)-20, (yscale*y-10)+20,
124*de2caf28SDavid du Colombier 				xscale*x+(xscale*4*w/3)-20, (yscale*y+10)+20);
125*de2caf28SDavid du Colombier 			UsedLine[ix]++;
126*de2caf28SDavid du Colombier 		} else			/* no outline */
127*de2caf28SDavid du Colombier 		{	fprintf(pfd, ".c create rectangle %d %d %d %d -fill white -width 0\n",
128*de2caf28SDavid du Colombier 				xscale*x-(xscale*4*w/3)-20, (yscale*y-10)+20,
129*de2caf28SDavid du Colombier 				xscale*x+(xscale*4*w/3)-20, (yscale*y+10)+20);
130*de2caf28SDavid du Colombier 	}	}
131*de2caf28SDavid du Colombier 	if (no_box > 0)
132*de2caf28SDavid du Colombier 	{	no_box--;
133*de2caf28SDavid du Colombier 	}
134*de2caf28SDavid du Colombier }
135*de2caf28SDavid du Colombier 
136*de2caf28SDavid du Colombier static void
stepnumber(int i)137*de2caf28SDavid du Colombier stepnumber(int i)
138*de2caf28SDavid du Colombier {	int y = (yscale*i*HH) + 20;
139*de2caf28SDavid du Colombier 
140*de2caf28SDavid du Colombier 	fprintf(pfd, ".c create text %d %d -fill #eef -text \"%d\"\n",
141*de2caf28SDavid du Colombier 		-10+(xscale*WW)/2, y, i);
142*de2caf28SDavid du Colombier 
143*de2caf28SDavid du Colombier 	/* horizontal dashed grid line */
144*de2caf28SDavid du Colombier 	fprintf(pfd, ".c create line %d %d %d %d -fill #eef -dash {6 4}\n",
145*de2caf28SDavid du Colombier 		-20+WW*xscale, y, (maxx+1)*WW*xscale-20, y);
146*de2caf28SDavid du Colombier }
147*de2caf28SDavid du Colombier 
148*de2caf28SDavid du Colombier static void
spitbox(int ix,int y,char * s)149*de2caf28SDavid du Colombier spitbox(int ix, int y, char *s)
150*de2caf28SDavid du Colombier {	float bw;	/* box width */
151*de2caf28SDavid du Colombier 	char d[256], *t, *z;
152*de2caf28SDavid du Colombier 	int a, i, x = ix+1;
153*de2caf28SDavid du Colombier 	char *color = "black";
154*de2caf28SDavid du Colombier 
155*de2caf28SDavid du Colombier 	if (y > 0)
156*de2caf28SDavid du Colombier 	{	stepnumber(y);
157*de2caf28SDavid du Colombier 	}
158*de2caf28SDavid du Colombier 
159*de2caf28SDavid du Colombier 	bw = (float)1.8*(float)strlen(s);	/* guess at default font width */
160*de2caf28SDavid du Colombier 	colbox(x, y, (int) (bw+1.0), 5, "black");
161*de2caf28SDavid du Colombier 	if (s[0] == '~')
162*de2caf28SDavid du Colombier 	{	switch (s[1]) {
163*de2caf28SDavid du Colombier 		default :
164*de2caf28SDavid du Colombier 		case 'R': color = "red";   break;
165*de2caf28SDavid du Colombier 		case 'B': color = "blue";  break;
166*de2caf28SDavid du Colombier 		case 'G': color = "green"; break;
167*de2caf28SDavid du Colombier 		}
168*de2caf28SDavid du Colombier 		s += 2;
169*de2caf28SDavid du Colombier 	} else if (strchr(s, '!'))
170*de2caf28SDavid du Colombier 	{	color = "ivory";
171*de2caf28SDavid du Colombier 	} else if (strchr(s, '?'))
172*de2caf28SDavid du Colombier 	{	color = "azure";
173*de2caf28SDavid du Colombier 	} else
174*de2caf28SDavid du Colombier 	{	color = "pink";
175*de2caf28SDavid du Colombier 		if (sscanf(s, "%d:%250s", &a, d) == 2
176*de2caf28SDavid du Colombier 		&&  a >= 0 && a < TotSteps)
177*de2caf28SDavid du Colombier 		{	if (!I[a]  || strlen(I[a]) <= strlen(s))
178*de2caf28SDavid du Colombier 			{	I[a] = (char *) emalloc((int) strlen(s)+1);
179*de2caf28SDavid du Colombier 			}
180*de2caf28SDavid du Colombier 			strcpy(I[a], s);
181*de2caf28SDavid du Colombier 	}	}
182*de2caf28SDavid du Colombier 
183*de2caf28SDavid du Colombier 	colbox(x, y, (int) bw, 4, color);
184*de2caf28SDavid du Colombier 
185*de2caf28SDavid du Colombier 	z = t = (char *) emalloc(2*strlen(s)+1);
186*de2caf28SDavid du Colombier 
187*de2caf28SDavid du Colombier 	for (i = 0; i < (int) strlen(s); i++)
188*de2caf28SDavid du Colombier 	{	if (s[i] == '\n')
189*de2caf28SDavid du Colombier 		{	continue;
190*de2caf28SDavid du Colombier 		}
191*de2caf28SDavid du Colombier 		if (s[i] == '[' || s[i] == ']')
192*de2caf28SDavid du Colombier 		{	*t++ = '\\';
193*de2caf28SDavid du Colombier 		}
194*de2caf28SDavid du Colombier 		*t++ = s[i];
195*de2caf28SDavid du Colombier 	}
196*de2caf28SDavid du Colombier 
197*de2caf28SDavid du Colombier 	fprintf(pfd, ".c create text %d %d -text \"%s\"\n",
198*de2caf28SDavid du Colombier 		xscale*x*WW-20, yscale*y*HH+20, z);
199*de2caf28SDavid du Colombier }
200*de2caf28SDavid du Colombier 
201*de2caf28SDavid du Colombier static void
putpages(void)202*de2caf28SDavid du Colombier putpages(void)
203*de2caf28SDavid du Colombier {	int i, lasti=0; float nmh;
204*de2caf28SDavid du Colombier 
205*de2caf28SDavid du Colombier 	if (maxx*xscale*WW > MW-RH/2)
206*de2caf28SDavid du Colombier 	{	Scaler = (float) (MW-RH/2) / (float) (maxx*xscale*WW);
207*de2caf28SDavid du Colombier 		nmh = (float) MH; nmh /= Scaler; MH = (int) nmh;
208*de2caf28SDavid du Colombier 		fprintf(pfd, "# Scaler %f, MH %d\n", Scaler, MH);
209*de2caf28SDavid du Colombier 	}
210*de2caf28SDavid du Colombier 	if (ldepth >= TotSteps)
211*de2caf28SDavid du Colombier 	{	ldepth = TotSteps-1;
212*de2caf28SDavid du Colombier 	}
213*de2caf28SDavid du Colombier 
214*de2caf28SDavid du Colombier /* W: (maxx+2)*xscale*WW  */
215*de2caf28SDavid du Colombier /* H: ldepth*HH*yscale+50 */
216*de2caf28SDavid du Colombier 	fprintf(pfd, "wm title . \"scenario\"\n");
217*de2caf28SDavid du Colombier 	fprintf(pfd, "wm geometry . %dx600+650+100\n", (maxx+2)*xscale*WW);
218*de2caf28SDavid du Colombier 
219*de2caf28SDavid du Colombier 	fprintf(pfd, "canvas .c -width 800 -height 800 \\\n");
220*de2caf28SDavid du Colombier 	fprintf(pfd, "	-scrollregion {0c -1c 30c 100c} \\\n");
221*de2caf28SDavid du Colombier 	fprintf(pfd, "	-xscrollcommand \".hscroll set\" \\\n");
222*de2caf28SDavid du Colombier 	fprintf(pfd, "	-yscrollcommand \".vscroll set\" \\\n");
223*de2caf28SDavid du Colombier 	fprintf(pfd, "	-bg white -relief raised -bd 2\n");
224*de2caf28SDavid du Colombier 
225*de2caf28SDavid du Colombier 	fprintf(pfd, "scrollbar .vscroll -relief sunken ");
226*de2caf28SDavid du Colombier 	fprintf(pfd, " -command \".c yview\"\n");
227*de2caf28SDavid du Colombier 	fprintf(pfd, "scrollbar .hscroll -relief sunken -orient horiz ");
228*de2caf28SDavid du Colombier 	fprintf(pfd, " -command \".c xview\"\n");
229*de2caf28SDavid du Colombier 
230*de2caf28SDavid du Colombier 	fprintf(pfd, "pack append . \\\n");
231*de2caf28SDavid du Colombier 	fprintf(pfd, "	.vscroll {right filly} \\\n");
232*de2caf28SDavid du Colombier 	fprintf(pfd, "	.hscroll {bottom fillx} \\\n");
233*de2caf28SDavid du Colombier 	fprintf(pfd, "	.c {top expand fill}\n");
234*de2caf28SDavid du Colombier 
235*de2caf28SDavid du Colombier 	fprintf(pfd, ".c yview moveto 0\n");
236*de2caf28SDavid du Colombier 
237*de2caf28SDavid du Colombier 	for (i = TotSteps-1; i >= 0; i--)
238*de2caf28SDavid du Colombier 	{	if (I[i])
239*de2caf28SDavid du Colombier 		{	spitbox(i, -1, I[i]);
240*de2caf28SDavid du Colombier 	}	}
241*de2caf28SDavid du Colombier 
242*de2caf28SDavid du Colombier 	for (i = 0; i <= ldepth; i++)
243*de2caf28SDavid du Colombier 	{	if (!M[i] && !L[i])
244*de2caf28SDavid du Colombier 		{	continue;	/* no box */
245*de2caf28SDavid du Colombier 		}
246*de2caf28SDavid du Colombier 		if (T[i] > 0)		/* arrow */
247*de2caf28SDavid du Colombier 		{	if (T[i] == i)	/* rv handshake */
248*de2caf28SDavid du Colombier 			{	psline(	M[lasti], lasti*HH,
249*de2caf28SDavid du Colombier 					M[i],     i*HH, RVC);
250*de2caf28SDavid du Colombier 			} else
251*de2caf28SDavid du Colombier 			{	psline(	M[i],     i*HH,
252*de2caf28SDavid du Colombier 					M[T[i]],  T[i]*HH, MPC);
253*de2caf28SDavid du Colombier 		}	}
254*de2caf28SDavid du Colombier 		if (L[i])
255*de2caf28SDavid du Colombier 		{	spitbox(M[i], i, L[i]);
256*de2caf28SDavid du Colombier 			lasti = i;
257*de2caf28SDavid du Colombier 	}	}
258*de2caf28SDavid du Colombier }
259*de2caf28SDavid du Colombier 
260*de2caf28SDavid du Colombier static void
putbox(int x)261*de2caf28SDavid du Colombier putbox(int x)
262*de2caf28SDavid du Colombier {
263*de2caf28SDavid du Colombier 	if (ldepth >= TotSteps)
264*de2caf28SDavid du Colombier 	{	fprintf(stderr, "max length of %d steps exceeded - ps file truncated\n",
265*de2caf28SDavid du Colombier 			TotSteps);
266*de2caf28SDavid du Colombier 		putpostlude();
267*de2caf28SDavid du Colombier 	}
268*de2caf28SDavid du Colombier 	M[ldepth] = x;
269*de2caf28SDavid du Colombier 	if (x > maxx)
270*de2caf28SDavid du Colombier 	{	maxx = x;
271*de2caf28SDavid du Colombier 		fprintf(pfd, "# maxx %d\n", x);
272*de2caf28SDavid du Colombier 	}
273*de2caf28SDavid du Colombier }
274*de2caf28SDavid du Colombier 
275*de2caf28SDavid du Colombier /* functions called externally: */
276*de2caf28SDavid du Colombier 
277*de2caf28SDavid du Colombier extern int WhatSeed(void);
278*de2caf28SDavid du Colombier 
279*de2caf28SDavid du Colombier void
putpostlude(void)280*de2caf28SDavid du Colombier putpostlude(void)
281*de2caf28SDavid du Colombier {	char cmd[512];
282*de2caf28SDavid du Colombier 
283*de2caf28SDavid du Colombier 	putpages();
284*de2caf28SDavid du Colombier 	fprintf(pfd, ".c lower grid\n");
285*de2caf28SDavid du Colombier 	fprintf(pfd, ".c raise mesg\n");
286*de2caf28SDavid du Colombier 	fclose(pfd);
287*de2caf28SDavid du Colombier 
288*de2caf28SDavid du Colombier 	fprintf(stderr, "seed used: -n%d\n", WhatSeed());
289*de2caf28SDavid du Colombier 	sprintf(cmd, "wish -f %s.tcl &", oFname?oFname->name:"msc");
290*de2caf28SDavid du Colombier 	fprintf(stderr, "%s\n", cmd);
291*de2caf28SDavid du Colombier 	(void) unlink("pan.pre");
292*de2caf28SDavid du Colombier 	exit (system(cmd));
293*de2caf28SDavid du Colombier }
294*de2caf28SDavid du Colombier 
295*de2caf28SDavid du Colombier void
putprelude(void)296*de2caf28SDavid du Colombier putprelude(void)
297*de2caf28SDavid du Colombier {	char snap[256]; FILE *fd;
298*de2caf28SDavid du Colombier 
299*de2caf28SDavid du Colombier 	sprintf(snap, "%s.tcl", oFname?oFname->name:"msc");
300*de2caf28SDavid du Colombier 	if (!(pfd = fopen(snap, MFLAGS)))
301*de2caf28SDavid du Colombier 	{	fatal("cannot create file '%s'", snap);
302*de2caf28SDavid du Colombier 	}
303*de2caf28SDavid du Colombier 	if (s_trail)
304*de2caf28SDavid du Colombier 	{	if (ntrail)
305*de2caf28SDavid du Colombier 		sprintf(snap, "%s%d.trail", oFname?oFname->name:"msc", ntrail);
306*de2caf28SDavid du Colombier 		else
307*de2caf28SDavid du Colombier 		sprintf(snap, "%s.trail", oFname?oFname->name:"msc");
308*de2caf28SDavid du Colombier 		if (!(fd = fopen(snap, "r")))
309*de2caf28SDavid du Colombier 		{	snap[strlen(snap)-2] = '\0';
310*de2caf28SDavid du Colombier 			if (!(fd = fopen(snap, "r")))
311*de2caf28SDavid du Colombier 				fatal("cannot open trail file", (char *) 0);
312*de2caf28SDavid du Colombier 		}
313*de2caf28SDavid du Colombier 		TotSteps = 1;
314*de2caf28SDavid du Colombier 		while (fgets(snap, 256, fd)) TotSteps++;
315*de2caf28SDavid du Colombier 		fclose(fd);
316*de2caf28SDavid du Colombier 	}
317*de2caf28SDavid du Colombier 	TotSteps *= 2;
318*de2caf28SDavid du Colombier 	R = (int   *) emalloc(TotSteps * sizeof(int));
319*de2caf28SDavid du Colombier 	D = (int   *) emalloc(TotSteps * sizeof(int));
320*de2caf28SDavid du Colombier 	M = (short *) emalloc(TotSteps * sizeof(short));
321*de2caf28SDavid du Colombier 	T = (short *) emalloc(TotSteps * sizeof(short));
322*de2caf28SDavid du Colombier 	L = (char **) emalloc(TotSteps * sizeof(char *));
323*de2caf28SDavid du Colombier 	I = (char **) emalloc(TotSteps * sizeof(char *));
324*de2caf28SDavid du Colombier }
325*de2caf28SDavid du Colombier 
326*de2caf28SDavid du Colombier void
putarrow(int from,int to)327*de2caf28SDavid du Colombier putarrow(int from, int to)
328*de2caf28SDavid du Colombier {
329*de2caf28SDavid du Colombier 	/* from rv if from == to */
330*de2caf28SDavid du Colombier 	/* which means that D[from] == D[to] */
331*de2caf28SDavid du Colombier 	/* which means that T[x] == x */
332*de2caf28SDavid du Colombier 
333*de2caf28SDavid du Colombier 	if (from    < TotSteps
334*de2caf28SDavid du Colombier 	&&  to      < TotSteps
335*de2caf28SDavid du Colombier 	&&  D[from] < TotSteps)
336*de2caf28SDavid du Colombier 	{	T[D[from]] = D[to];
337*de2caf28SDavid du Colombier 	}
338*de2caf28SDavid du Colombier }
339*de2caf28SDavid du Colombier 
340*de2caf28SDavid du Colombier void
pstext(int x,char * s)341*de2caf28SDavid du Colombier pstext(int x, char *s)
342*de2caf28SDavid du Colombier {	char *tmp = emalloc((int) strlen(s)+1);
343*de2caf28SDavid du Colombier 
344*de2caf28SDavid du Colombier 	strcpy(tmp, s);
345*de2caf28SDavid du Colombier 	if (depth == 0)
346*de2caf28SDavid du Colombier 	{	I[x] = tmp;
347*de2caf28SDavid du Colombier 	} else
348*de2caf28SDavid du Colombier 	{	if (depth >= TotSteps || ldepth >= TotSteps)
349*de2caf28SDavid du Colombier 		{	fprintf(stderr, "spin: error: max nr of %d steps exceeded\n",
350*de2caf28SDavid du Colombier 				TotSteps);
351*de2caf28SDavid du Colombier 			fatal("use -uN to limit steps", (char *) 0);
352*de2caf28SDavid du Colombier 		}
353*de2caf28SDavid du Colombier 		putbox(x);
354*de2caf28SDavid du Colombier 		D[depth] = ldepth;
355*de2caf28SDavid du Colombier 		R[ldepth] = depth;
356*de2caf28SDavid du Colombier 		L[ldepth] = tmp;
357*de2caf28SDavid du Colombier 		ldepth += 2;
358*de2caf28SDavid du Colombier 	}
359*de2caf28SDavid du Colombier }
360*de2caf28SDavid du Colombier 
361*de2caf28SDavid du Colombier void
dotag(FILE * fd,char * s)362*de2caf28SDavid du Colombier dotag(FILE *fd, char *s)
363*de2caf28SDavid du Colombier {	extern int columns, notabs; extern RunList *X_lst;
364*de2caf28SDavid du Colombier 	int i = (!strncmp(s, "MSC: ", 5))?5:0;
365*de2caf28SDavid du Colombier 	int pid = s_trail ? (prno - Have_claim) : (X_lst?X_lst->pid:0);
366*de2caf28SDavid du Colombier 
367*de2caf28SDavid du Colombier 	if (pid < 0) { pid = 0; }
368*de2caf28SDavid du Colombier 
369*de2caf28SDavid du Colombier 	if (columns == 2)
370*de2caf28SDavid du Colombier 	{	pstext(pid, &s[i]);
371*de2caf28SDavid du Colombier 	} else
372*de2caf28SDavid du Colombier 	{	if (!notabs)
373*de2caf28SDavid du Colombier 		{	printf("  ");
374*de2caf28SDavid du Colombier 			for (i = 0; i <= pid; i++)
375*de2caf28SDavid du Colombier 			{	printf("    ");
376*de2caf28SDavid du Colombier 		}	}
377*de2caf28SDavid du Colombier 		fprintf(fd, "%s", s);
378*de2caf28SDavid du Colombier 		fflush(fd);
379*de2caf28SDavid du Colombier 	}
380*de2caf28SDavid du Colombier }
381