Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_fixcpp/sys/src/cmd/pic/misc.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <stdio.h>
2
#include <string.h>
3
#include <stdlib.h>
4
#include <math.h>
5
#include "pic.h"
6
#include "y.tab.h"
7
 
8
int whatpos(obj *p, int corner, double *px, double *py);
9
void makeattr(int type, int sub, YYSTYPE val);
10
YYSTYPE getblk(obj *, char *);
11
 
12
setdir(int n)	/* set direction (hvmode) from LEFT, RIGHT, etc. */
13
{
14
	switch (n) {
15
	case UP:	hvmode = U_DIR; break;
16
	case DOWN:	hvmode = D_DIR; break;
17
	case LEFT:	hvmode = L_DIR; break;
18
	case RIGHT:	hvmode = R_DIR; break;
19
	}
20
 	return(hvmode);
21
}
22
 
23
curdir(void)	/* convert current dir (hvmode) to RIGHT, LEFT, etc. */
24
{
25
	switch (hvmode) {
26
	case R_DIR:	return RIGHT;
27
	case L_DIR:	return LEFT;
28
	case U_DIR:	return UP;
29
	case D_DIR:	return DOWN;
30
	}
31
	ERROR "can't happen curdir" FATAL;
32
	return 0;
33
}
34
 
35
double getcomp(obj *p, int t)	/* return component of a position */
36
{
37
	switch (t) {
38
	case DOTX:
39
		return p->o_x;
40
	case DOTY:
41
		return p->o_y;
42
	case DOTWID:
43
		switch (p->o_type) {
44
		case BOX:
45
		case BLOCK:
46
		case TEXT:
47
			return p->o_val[0];
48
		case CIRCLE:
49
		case ELLIPSE:
50
			return 2 * p->o_val[0];
51
		case LINE:
52
		case ARROW:
53
			return p->o_val[0] - p->o_x;
54
		case PLACE:
55
			return 0;
56
		}
57
	case DOTHT:
58
		switch (p->o_type) {
59
		case BOX:
60
		case BLOCK:
61
		case TEXT:
62
			return p->o_val[1];
63
		case CIRCLE:
64
		case ELLIPSE:
65
			return 2 * p->o_val[1];
66
		case LINE:
67
		case ARROW:
68
			return p->o_val[1] - p->o_y;
69
		case PLACE:
70
			return 0;
71
		}
72
	case DOTRAD:
73
		switch (p->o_type) {
74
		case CIRCLE:
75
		case ELLIPSE:
76
			return p->o_val[0];
77
		}
78
	}
79
	ERROR "you asked for a weird dimension or position" WARNING;
80
	return 0;
81
}
82
 
83
double	exprlist[100];
84
int	nexpr	= 0;
85
 
86
void exprsave(double f)
87
{
88
	exprlist[nexpr++] = f;
89
}
90
 
91
char *sprintgen(char *fmt)
92
{
93
	char buf[1000];
94
 
95
	sprintf(buf, fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]);
96
	nexpr = 0;
97
	free(fmt);
98
	return tostring(buf);
99
}
100
 
101
void makefattr(int type, int sub, double f)	/* double attr */
102
{
103
	YYSTYPE val;
104
	val.f = f;
105
	makeattr(type, sub, val);
106
}
107
 
108
void makeoattr(int type, obj *o)	/* obj* attr */
109
{
110
	YYSTYPE val;
111
	val.o = o;
112
	makeattr(type, 0, val);
113
}
114
 
115
void makeiattr(int type, int i)	/* int attr */
116
{
117
	YYSTYPE val;
118
	val.i = i;
119
	makeattr(type, 0, val);
120
}
121
 
122
void maketattr(int sub, char *p)	/* text attribute: takes two */
123
{
124
	YYSTYPE val;
125
	val.p = p;
126
	makeattr(TEXTATTR, sub, val);
127
}
128
 
129
void addtattr(int sub)		/* add text attrib to existing item */
130
{
131
	attr[nattr-1].a_sub |= sub;
132
}
133
 
134
void makevattr(char *p)	/* varname attribute */
135
{
136
	YYSTYPE val;
137
	val.p = p;
138
	makeattr(VARNAME, 0, val);
139
}
140
 
141
void makeattr(int type, int sub, YYSTYPE val)	/* add attribute type and val */
142
{
143
	if (type == 0 && val.i == 0) {	/* clear table for next stat */
144
		nattr = 0;
145
		return;
146
	}
147
	if (nattr >= nattrlist)
148
		attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr));
149
	dprintf("attr %d:  %d %d %d\n", nattr, type, sub, val.i);
150
	attr[nattr].a_type = type;
151
	attr[nattr].a_sub = sub;
152
	attr[nattr].a_val = val;
153
	nattr++;
154
}
155
 
156
void printexpr(double f)	/* print expression for debugging */
157
{
158
	printf("%g\n", f);
159
}
160
 
161
void printpos(obj *p)	/* print position for debugging */
162
{
163
	printf("%g, %g\n", p->o_x, p->o_y);
164
}
165
 
166
char *tostring(char *s)
167
{
168
	register char *p;
169
 
170
	p = malloc(strlen(s)+1);
171
	if (p == NULL)
172
		ERROR "out of space in tostring on %s", s FATAL;
173
	strcpy(p, s);
174
	return(p);
175
}
176
 
177
obj *makepos(double x, double y)	/* make a position cell */
178
{
179
	obj *p;
180
 
181
	p = makenode(PLACE, 0);
182
	p->o_x = x;
183
	p->o_y = y;
184
	return(p);
185
}
186
 
187
obj *makebetween(double f, obj *p1, obj *p2)	/* make position between p1 and p2 */
188
{
189
	obj *p;
190
 
191
	dprintf("fraction = %.2f\n", f);
192
	p = makenode(PLACE, 0);
193
	p->o_x = p1->o_x + f * (p2->o_x - p1->o_x);
194
	p->o_y = p1->o_y + f * (p2->o_y - p1->o_y);
195
	return(p);
196
}
197
 
198
obj *getpos(obj *p, int corner)	/* find position of point */
199
{
200
	double x, y;
201
 
202
	whatpos(p, corner, &x, &y);
203
	return makepos(x, y);
204
}
205
 
206
int whatpos(obj *p, int corner, double *px, double *py)	/* what is the position (no side effect) */
207
{
208
	double x, y, x1, y1;
209
 
210
	if (p == NULL)
211
		ERROR "null object" FATAL;
212
	dprintf("whatpos %o %d %d\n", p, p->o_type, corner);
213
	x = p->o_x;
214
	y = p->o_y;
215
	if (p->o_type != PLACE && p->o_type != MOVE) {
216
		x1 = p->o_val[0];
217
		y1 = p->o_val[1];
218
	}
219
	switch (p->o_type) {
220
	case PLACE:
221
		break;
222
	case BOX:
223
	case BLOCK:
224
	case TEXT:
225
		switch (corner) {
226
		case NORTH:	y += y1 / 2; break;
227
		case SOUTH:	y -= y1 / 2; break;
228
		case EAST:	x += x1 / 2; break;
229
		case WEST:	x -= x1 / 2; break;
230
		case NE:	x += x1 / 2; y += y1 / 2; break;
231
		case SW:	x -= x1 / 2; y -= y1 / 2; break;
232
		case SE:	x += x1 / 2; y -= y1 / 2; break;
233
		case NW:	x -= x1 / 2; y += y1 / 2; break;
234
		case START:
235
			if (p->o_type == BLOCK)
236
				return whatpos(objlist[(int)p->o_val[2]], START, px, py);
237
		case END:
238
			if (p->o_type == BLOCK)
239
				return whatpos(objlist[(int)p->o_val[3]], END, px, py);
240
		}
241
		break;
242
	case ARC:
243
		switch (corner) {
244
		case START:
245
			if (p->o_attr & CW_ARC) {
246
				x = p->o_val[2]; y = p->o_val[3];
247
			} else {
248
				x = x1; y = y1;
249
			}
250
			break;
251
		case END:
252
			if (p->o_attr & CW_ARC) {
253
				x = x1; y = y1;
254
			} else {
255
				x = p->o_val[2]; y = p->o_val[3];
256
			}
257
			break;
258
		}
259
		if (corner == START || corner == END)
260
			break;
261
		x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y));
262
		/* Fall Through! */
263
	case CIRCLE:
264
	case ELLIPSE:
265
		switch (corner) {
266
		case NORTH:	y += y1; break;
267
		case SOUTH:	y -= y1; break;
268
		case EAST:	x += x1; break;
269
		case WEST:	x -= x1; break;
270
		case NE:	x += 0.707 * x1; y += 0.707 * y1; break;
271
		case SE:	x += 0.707 * x1; y -= 0.707 * y1; break;
272
		case NW:	x -= 0.707 * x1; y += 0.707 * y1; break;
273
		case SW:	x -= 0.707 * x1; y -= 0.707 * y1; break;
274
		}
275
		break;
276
	case LINE:
277
	case SPLINE:
278
	case ARROW:
279
		switch (corner) {
280
		case START:	break;	/* already in place */
281
		case END:	x = x1; y = y1; break;
282
		default: /* change! */
283
		case CENTER:	x = (x+x1)/2; y = (y+y1)/2; break;
284
		case NORTH:	if (y1 > y) { x = x1; y = y1; } break;
285
		case SOUTH:	if (y1 < y) { x = x1; y = y1; } break;
286
		case EAST:	if (x1 > x) { x = x1; y = y1; } break;
287
		case WEST:	if (x1 < x) { x = x1; y = y1; } break;
288
		}
289
		break;
290
	case MOVE:
291
		/* really ought to be same as line... */
292
		break;
293
	}
294
	dprintf("whatpos returns %g %g\n", x, y);
295
	*px = x;
296
	*py = y;
297
	return 1;
298
}
299
 
300
obj *gethere(void)	/* make a place for curx,cury */
301
{
302
	dprintf("gethere %g %g\n", curx, cury);
303
	return(makepos(curx, cury));
304
}
305
 
306
obj *getlast(int n, int t)	/* find n-th previous occurrence of type t */
307
{
308
	int i, k;
309
	obj *p;
310
 
311
	k = n;
312
	for (i = nobj-1; i >= 0; i--) {
313
		p = objlist[i];
314
		if (p->o_type == BLOCKEND) {
315
			i = p->o_val[4];
316
			continue;
317
		}
318
		if (p->o_type != t)
319
			continue;
320
		if (--k > 0)
321
			continue;	/* not there yet */
322
		dprintf("got a last of x,y= %g,%g\n", p->o_x, p->o_y);
323
		return(p);
324
	}
325
	ERROR "there is no %dth last", n FATAL;
326
	return(NULL);
327
}
328
 
329
obj *getfirst(int n, int t)	/* find n-th occurrence of type t */
330
{
331
	int i, k;
332
	obj *p;
333
 
334
	k = n;
335
	for (i = 0; i < nobj; i++) {
336
		p = objlist[i];
337
		if (p->o_type == BLOCK && t != BLOCK) {	/* skip whole block */
338
			i = p->o_val[5] + 1;
339
			continue;
340
		}
341
		if (p->o_type != t)
342
			continue;
343
		if (--k > 0)
344
			continue;	/* not there yet */
345
		dprintf("got a first of x,y= %g,%g\n", p->o_x, p->o_y);
346
		return(p);
347
	}
348
	ERROR "there is no %dth ", n FATAL;
349
	return(NULL);
350
}
351
 
352
double getblkvar(obj *p, char *s)	/* find variable s2 in block p */
353
{
354
	YYSTYPE y;
355
 
356
	y = getblk(p, s);
357
	return y.f;
358
}
359
 
360
obj *getblock(obj *p, char *s)	/* find variable s in block p */
361
{
362
	YYSTYPE y;
363
 
364
	y = getblk(p, s);
365
	return y.o;
366
}
367
 
368
YYSTYPE getblk(obj *p, char *s)	/* find union type for s in p */
369
{
370
	static YYSTYPE bug;
371
	struct symtab *stp;
372
 
373
	if (p->o_type != BLOCK) {
374
		ERROR ".%s is not in that block", s WARNING;
375
		return(bug);
376
	}
377
	for (stp = p->o_symtab; stp != NULL; stp = stp->s_next)
378
		if (strcmp(s, stp->s_name) == 0) {
379
			dprintf("getblk %s found x,y= %g,%g\n",
380
				s, (stp->s_val.o)->o_x, (stp->s_val.o)->o_y);
381
			return(stp->s_val);
382
		}
383
	ERROR "there is no .%s in that []", s WARNING;
384
	return(bug);
385
}
386
 
387
obj *fixpos(obj *p, double x, double y)
388
{
389
	dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y);
390
	return makepos(p->o_x + x, p->o_y + y);
391
}
392
 
393
obj *addpos(obj *p, obj *q)
394
{
395
	dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y);
396
	return makepos(p->o_x+q->o_x, p->o_y+q->o_y);
397
}
398
 
399
obj *subpos(obj *p, obj *q)
400
{
401
	dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y);
402
	return makepos(p->o_x-q->o_x, p->o_y-q->o_y);
403
}
404
 
405
obj *makenode(int type, int n)
406
{
407
	obj *p;
408
 
409
	p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(ofloat));
410
	if (p == NULL)
411
		ERROR "out of space in makenode" FATAL;
412
	p->o_type = type;
413
	p->o_count = n;
414
	p->o_nobj = nobj;
415
	p->o_mode = hvmode;
416
	p->o_x = curx;
417
	p->o_y = cury;
418
	p->o_nt1 = ntext1;
419
	p->o_nt2 = ntext;
420
	ntext1 = ntext;	/* ready for next caller */
421
	if (nobj >= nobjlist)
422
		objlist = (obj **) grow((char *) objlist, "objlist",
423
			nobjlist *= 2, sizeof(obj *));
424
	objlist[nobj++] = p;
425
	return(p);
426
}
427
 
428
void extreme(double x, double y)	/* record max and min x and y values */
429
{
430
	if (x > xmax)
431
		xmax = x;
432
	if (y > ymax)
433
		ymax = y;
434
	if (x < xmin)
435
		xmin = x;
436
	if (y < ymin)
437
		ymin = y;
438
}