⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <math.h>#include "pic.h"#include "y.tab.h"int whatpos(obj *p, int corner, double *px, double *py);void makeattr(int type, int sub, YYSTYPE val);YYSTYPE getblk(obj *, char *);setdir(int n)	/* set direction (hvmode) from LEFT, RIGHT, etc. */{	switch (n) {	case UP:	hvmode = U_DIR; break;	case DOWN:	hvmode = D_DIR; break;	case LEFT:	hvmode = L_DIR; break;	case RIGHT:	hvmode = R_DIR; break;	} 	return(hvmode);}curdir(void)	/* convert current dir (hvmode) to RIGHT, LEFT, etc. */{	switch (hvmode) {	case R_DIR:	return RIGHT;	case L_DIR:	return LEFT;	case U_DIR:	return UP;	case D_DIR:	return DOWN;	}	ERROR "can't happen curdir" FATAL;	return 0;}double getcomp(obj *p, int t)	/* return component of a position */{	switch (t) {	case DOTX:		return p->o_x;	case DOTY:		return p->o_y;	case DOTWID:		switch (p->o_type) {		case BOX:		case BLOCK:		case TEXT:			return p->o_val[0];		case CIRCLE:		case ELLIPSE:			return 2 * p->o_val[0];		case LINE:		case ARROW:			return p->o_val[0] - p->o_x;		case PLACE:			return 0;		}	case DOTHT:		switch (p->o_type) {		case BOX:		case BLOCK:		case TEXT:			return p->o_val[1];		case CIRCLE:		case ELLIPSE:			return 2 * p->o_val[1];		case LINE:		case ARROW:			return p->o_val[1] - p->o_y;		case PLACE:			return 0;		}	case DOTRAD:		switch (p->o_type) {		case CIRCLE:		case ELLIPSE:			return p->o_val[0];		}	}	ERROR "you asked for a weird dimension or position" WARNING;	return 0;}double	exprlist[100];int	nexpr	= 0;void exprsave(double f){	exprlist[nexpr++] = f;}char *sprintgen(char *fmt){	char buf[1000];	sprintf(buf, fmt, exprlist[0], exprlist[1], exprlist[2], exprlist[3], exprlist[4]);	nexpr = 0;	free(fmt);	return tostring(buf);}void makefattr(int type, int sub, double f)	/* double attr */{	YYSTYPE val;	val.f = f;	makeattr(type, sub, val);}void makeoattr(int type, obj *o)	/* obj* attr */{	YYSTYPE val;	val.o = o;	makeattr(type, 0, val);}void makeiattr(int type, int i)	/* int attr */{	YYSTYPE val;	val.i = i;	makeattr(type, 0, val);}void maketattr(int sub, char *p)	/* text attribute: takes two */{	YYSTYPE val;	val.p = p;	makeattr(TEXTATTR, sub, val);}void addtattr(int sub)		/* add text attrib to existing item */{	attr[nattr-1].a_sub |= sub;}void makevattr(char *p)	/* varname attribute */{	YYSTYPE val;	val.p = p;	makeattr(VARNAME, 0, val);}void makeattr(int type, int sub, YYSTYPE val)	/* add attribute type and val */{	if (type == 0 && val.i == 0) {	/* clear table for next stat */		nattr = 0;		return;	}	if (nattr >= nattrlist)		attr = (Attr *) grow((char *)attr, "attr", nattrlist += 100, sizeof(Attr));	dprintf("attr %d:  %d %d %d\n", nattr, type, sub, val.i);	attr[nattr].a_type = type;	attr[nattr].a_sub = sub;	attr[nattr].a_val = val;	nattr++;}void printexpr(double f)	/* print expression for debugging */{	printf("%g\n", f);}void printpos(obj *p)	/* print position for debugging */{	printf("%g, %g\n", p->o_x, p->o_y);}char *tostring(char *s){	register char *p;	p = malloc(strlen(s)+1);	if (p == NULL)		ERROR "out of space in tostring on %s", s FATAL;	strcpy(p, s);	return(p);}obj *makepos(double x, double y)	/* make a position cell */{	obj *p;	p = makenode(PLACE, 0);	p->o_x = x;	p->o_y = y;	return(p);}obj *makebetween(double f, obj *p1, obj *p2)	/* make position between p1 and p2 */{	obj *p;	dprintf("fraction = %.2f\n", f);	p = makenode(PLACE, 0);	p->o_x = p1->o_x + f * (p2->o_x - p1->o_x);	p->o_y = p1->o_y + f * (p2->o_y - p1->o_y);	return(p);}obj *getpos(obj *p, int corner)	/* find position of point */{	double x, y;	whatpos(p, corner, &x, &y);	return makepos(x, y);}int whatpos(obj *p, int corner, double *px, double *py)	/* what is the position (no side effect) */{	double x, y, x1, y1;	dprintf("whatpos %o %d %d\n", p, p->o_type, corner);	x = p->o_x;	y = p->o_y;	if (p->o_type != PLACE && p->o_type != MOVE) {		x1 = p->o_val[0];		y1 = p->o_val[1];	}	switch (p->o_type) {	case PLACE:		break;	case BOX:	case BLOCK:	case TEXT:		switch (corner) {		case NORTH:	y += y1 / 2; break;		case SOUTH:	y -= y1 / 2; break;		case EAST:	x += x1 / 2; break;		case WEST:	x -= x1 / 2; break;		case NE:	x += x1 / 2; y += y1 / 2; break;		case SW:	x -= x1 / 2; y -= y1 / 2; break;		case SE:	x += x1 / 2; y -= y1 / 2; break;		case NW:	x -= x1 / 2; y += y1 / 2; break;		case START:			if (p->o_type == BLOCK)				return whatpos(objlist[(int)p->o_val[2]], START, px, py);		case END:			if (p->o_type == BLOCK)				return whatpos(objlist[(int)p->o_val[3]], END, px, py);		}		break;	case ARC:		switch (corner) {		case START:			if (p->o_attr & CW_ARC) {				x = p->o_val[2]; y = p->o_val[3];			} else {				x = x1; y = y1;			}			break;		case END:			if (p->o_attr & CW_ARC) {				x = x1; y = y1;			} else {				x = p->o_val[2]; y = p->o_val[3];			}			break;		}		if (corner == START || corner == END)			break;		x1 = y1 = sqrt((x1-x)*(x1-x) + (y1-y)*(y1-y));		/* Fall Through! */	case CIRCLE:	case ELLIPSE:		switch (corner) {		case NORTH:	y += y1; break;		case SOUTH:	y -= y1; break;		case EAST:	x += x1; break;		case WEST:	x -= x1; break;		case NE:	x += 0.707 * x1; y += 0.707 * y1; break;		case SE:	x += 0.707 * x1; y -= 0.707 * y1; break;		case NW:	x -= 0.707 * x1; y += 0.707 * y1; break;		case SW:	x -= 0.707 * x1; y -= 0.707 * y1; break;		}		break;	case LINE:	case SPLINE:	case ARROW:		switch (corner) {		case START:	break;	/* already in place */		case END:	x = x1; y = y1; break;		default: /* change! */		case CENTER:	x = (x+x1)/2; y = (y+y1)/2; break;		case NORTH:	if (y1 > y) { x = x1; y = y1; } break;		case SOUTH:	if (y1 < y) { x = x1; y = y1; } break;		case EAST:	if (x1 > x) { x = x1; y = y1; } break;		case WEST:	if (x1 < x) { x = x1; y = y1; } break;		}		break;	case MOVE:		/* really ought to be same as line... */		break;	}	dprintf("whatpos returns %g %g\n", x, y);	*px = x;	*py = y;	return 1;}obj *gethere(void)	/* make a place for curx,cury */{	dprintf("gethere %g %g\n", curx, cury);	return(makepos(curx, cury));}obj *getlast(int n, int t)	/* find n-th previous occurrence of type t */{	int i, k;	obj *p;	k = n;	for (i = nobj-1; i >= 0; i--) {		p = objlist[i];		if (p->o_type == BLOCKEND) {			i = p->o_val[4];			continue;		}		if (p->o_type != t)			continue;		if (--k > 0)			continue;	/* not there yet */		dprintf("got a last of x,y= %g,%g\n", p->o_x, p->o_y);		return(p);	}	ERROR "there is no %dth last", n FATAL;	return(NULL);}obj *getfirst(int n, int t)	/* find n-th occurrence of type t */{	int i, k;	obj *p;	k = n;	for (i = 0; i < nobj; i++) {		p = objlist[i];		if (p->o_type == BLOCK && t != BLOCK) {	/* skip whole block */			i = p->o_val[5] + 1;			continue;		}		if (p->o_type != t)			continue;		if (--k > 0)			continue;	/* not there yet */		dprintf("got a first of x,y= %g,%g\n", p->o_x, p->o_y);		return(p);	}	ERROR "there is no %dth ", n FATAL;	return(NULL);}double getblkvar(obj *p, char *s)	/* find variable s2 in block p */{	YYSTYPE y;	y = getblk(p, s);	return y.f;}obj *getblock(obj *p, char *s)	/* find variable s in block p */{	YYSTYPE y;	y = getblk(p, s);	return y.o;}YYSTYPE getblk(obj *p, char *s)	/* find union type for s in p */{	static YYSTYPE bug;	struct symtab *stp;	if (p->o_type != BLOCK) {		ERROR ".%s is not in that block", s WARNING;		return(bug);	}	for (stp = p->o_symtab; stp != NULL; stp = stp->s_next)		if (strcmp(s, stp->s_name) == 0) {			dprintf("getblk %s found x,y= %g,%g\n",				s, (stp->s_val.o)->o_x, (stp->s_val.o)->o_y);			return(stp->s_val);		}	ERROR "there is no .%s in that []", s WARNING;	return(bug);}obj *fixpos(obj *p, double x, double y){	dprintf("fixpos returns %g %g\n", p->o_x + x, p->o_y + y);	return makepos(p->o_x + x, p->o_y + y);}obj *addpos(obj *p, obj *q){	dprintf("addpos returns %g %g\n", p->o_x+q->o_x, p->o_y+q->o_y);	return makepos(p->o_x+q->o_x, p->o_y+q->o_y);}obj *subpos(obj *p, obj *q){	dprintf("subpos returns %g %g\n", p->o_x-q->o_x, p->o_y-q->o_y);	return makepos(p->o_x-q->o_x, p->o_y-q->o_y);}obj *makenode(int type, int n){	obj *p;	p = (obj *) calloc(1, sizeof(obj) + (n-1)*sizeof(ofloat));	if (p == NULL)		ERROR "out of space in makenode" FATAL;	p->o_type = type;	p->o_count = n;	p->o_nobj = nobj;	p->o_mode = hvmode;	p->o_x = curx;	p->o_y = cury;	p->o_nt1 = ntext1;	p->o_nt2 = ntext;	ntext1 = ntext;	/* ready for next caller */	if (nobj >= nobjlist)		objlist = (obj **) grow((char *) objlist, "objlist",			nobjlist *= 2, sizeof(obj *));	objlist[nobj++] = p;	return(p);}void extreme(double x, double y)	/* record max and min x and y values */{	if (x > xmax)		xmax = x;	if (y > ymax)		ymax = y;	if (x < xmin)		xmin = x;	if (y < ymin)		ymin = y;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -