henesyinit from vn5c1081e6 years agoHistory
909 lines · 16.4 KB · C
RawDownload
#include "lib9.h"#include "kernel.h"#include "image.h"#include "tk.h" #define	O(t, e)		((long)(&((t*)0)->e)) static char* pdist(TkTop*, TkOption*, void*, char**, char*, char*);static char* pstab(TkTop*, TkOption*, void*, char**, char*, char*);static char* ptext(TkTop*, TkOption*, void*, char**, char*, char*);static char* pwinp(TkTop*, TkOption*, void*, char**, char*, char*);static char* pbmap(TkTop*, TkOption*, void*, char**, char*, char*);static char* pbool(TkTop*, TkOption*, void*, char**, char*, char*);static char* pfont(TkTop*, TkOption*, void*, char**, char*, char*);static char* pfrac(TkTop*, TkOption*, void*, char**, char*, char*);static char* pctag(TkTop*, TkOption*, void*, char**, char*, char*);static char* ptabs(TkTop*, TkOption*, void*, char**, char*, char*);static char* pcolr(TkTop*, TkOption*, void*, char**, char*, char*);static char* pimag(TkTop*, TkOption*, void*, char**, char*, char*);static char* psize(TkTop*, TkOption*, void*, char**, char*, char*);static char* pevim(TkTop*, TkOption*, void*, char**, char*, char*); static char* (*oparse[])(TkTop*, TkOption*, void*, char**, char*, char*) ={	/* OPTdist */	pdist,	/* OPTstab */	pstab,	/* OPTtext */	ptext,	/* OPTwinp */	pwinp,	/* OPTflag */	pstab,	/* OPTbmap */	pbmap,	/* OPTbool */	pbool,	/* OPTfont */	pfont,	/* OPTfrac */	pfrac,	/* OPTctag */	pctag,	/* OPTtabs */	ptabs,	/* OPTcolr */	pcolr,	/* OPTimag */	pimag,	/* OPTsize */	psize,	/* OPTevim */	pevim,}; char*tkskip(char *s, char *bl){	char *p; 	while(*s) {		for(p = bl; *p; p++)			if(*p == *s)				break;		if(*p == '\0')			return s;			s++;	}	return s;} /* XXX - Tad: error propagation? */char*tkword(TkTop *t, char *str, char *buf, char *ebuf){	int c, lev;	char *val, *e, *p, *cmd; 	/*	 * ebuf is one beyond last byte in buf; leave room for nul byte in	 * all cases.	 */	--ebuf; 	str = tkskip(str, " \t");	lev = 1;	switch(*str) {	case '{':		/* XXX - DBK: According to Ousterhout (p.37), while back=		 * slashed braces don't count toward finding the matching		 * closing braces, the backslashes should not be removed.		 * Presumably this also applies to other backslashed		 * characters: the backslash should not be removed.		 */		str++;		while(*str && buf < ebuf) {			c = *str++;			if(c == '\\') {				if(*str == '}' || *str == '{' || *str == '\\')					c = *str++;			}			else			if(c == '}') {				lev--;				if(lev == 0)					break;			}			else			if(c == '{')				lev++;			*buf++ = c;		}		break;	case '[':		/* XXX - DBK: According to Ousterhout (p. 33) command		 * substitution may occur anywhere within a word, not		 * only (as here) at the beginning.		 */		cmd = malloc(strlen(str));		if ( cmd == nil ) {			buf[0] = '\0';	/* DBK - Why not an error message? */			return str;		}		p = cmd;		str++;		while(*str) {			c = *str++;			if(c == '\\') {				if(*str == ']' || *str == '[' || *str == '\\')					c = *str++;			}			else			if(c == ']') {				lev--;				if(lev == 0)					break;			}			else			if(c == '[')				lev++;			*p++ = c;		}		*p = '\0';		val = nil;		e = tkexec(t, cmd, &val);		free(cmd);		 /* XXX - Tad: is this appropriate behavior?		  *	      Am I sure that the error doesn't need to be		  *	      propagated back to the caller?		  */		if(e == nil && val != nil) {			strncpy(buf, val, ebuf-buf);			buf = ebuf;			free(val);		}		break;	case '\'':		str++;		while(*str && buf < ebuf)			*buf++ = *str++;		break;	default:		/* XXX - DBK: See comment above about command substitution.		 * Also, any backslashed character should be replaced by		 * itself (e.g. to put a space, tab, or [ into a word.		 * We assume that the C compiler has already done the		 * standard ANSI C substitutions.  (But should we?)		 */		while(*str && *str != ' ' && *str != '\t' && buf < ebuf)			*buf++ = *str++;	}	*buf = '\0';	return str;} static TkOption*Getopt(TkOption *o, char *buf){	while(o->o != nil) {		if(strcmp(buf, o->o) == 0)			return o;		o++;	}	return nil;} TkName*tkmkname(char *name){	TkName *n; 	n = malloc(sizeof(struct TkName)+strlen(name));	if(n == nil)		return nil;	strcpy(n->name, name);	n->link = nil;	n->obj = nil;	return n;} char*tkparse(TkTop *t, char *str, TkOptab *ot, TkName **nl){	int l;	TkOptab *ft;	TkOption *o;	TkName *f, *n;	char *e, *buf, *ebuf; 	l = strlen(str);	buf = malloc(l);	if(buf == 0)		return TkNomem;	ebuf = buf + l; 	e = nil;	while(e == nil) {		str = tkword(t, str, buf, ebuf);		switch(*buf) {		case '\0':			goto done;		case '-':			for(ft = ot; ft->ptr; ft++) {				o = Getopt(ft->optab, buf+1);				if(o != nil) {					e = oparse[o->type](t, o, ft->ptr, &str, buf, ebuf);					break;				}			}			if(ft->ptr == nil)				e = TkBadop;			break;		default:			if(nl == nil) {				e = TkBadop;				break;			}			n = tkmkname(buf);			if(n == nil) {				e = TkNomem;				break;			}			if(*nl == nil)				*nl = n;			else {				for(f = *nl; f->link; f = f->link)					;				f->link = n;			}		}			} 	if(e != nil && nl != nil)		tkfreename(*nl);done:	free(buf);	return e;} char*tkconflist(TkOptab *ot, char **val){	TkOption *o;	char *f, *e; 	f = "-%s";	while(ot->ptr != nil) {		o = ot->optab;		while(o->o != nil) {			e = tkvalue(val, f, o->o);			if(e != nil)				return e;			f = " -%s";			o++;		}		ot++;	}	return nil;} char*tkgencget(TkOptab *ft, char *arg, char **val){	Tk *w;	char *c;	Point g;	TkEnv *e;	TkStab *s;	TkOption *o;	int wh, con, i, n, *v;	char *r, *buf, *fmt; 	buf = mallocz(Tkmaxitem, 0);	if(buf == nil)		return TkNomem; 	tkitem(buf, arg);	r = buf;	if(*r == '-')		r++;	if(strcmp(r, "actx") == 0 || strcmp(r, "acty") == 0) {		w = ft->ptr;		g = tkposn(w);		n = g.y;		if(r[3] == 'x')			n = g.x;		free(buf);		return tkvalue(val, "%d", n);	}	o = nil;	while(ft->ptr) {		o = Getopt(ft->optab, r);		if(o != nil)			break;		ft++;	}	if(o == nil) {		free(buf);		return TkBadop;	} 	switch(o->type) {	default:		free(buf);		return TkBadop;	case OPTdist:		free(buf);		return tkvalue(val, "%d", OPTION(ft->ptr, int, o->offset));	case OPTsize:		w = ft->ptr;		if(strcmp(r, "width") == 0)			wh = w->req.width;		else			wh = w->req.height;		free(buf);		return tkvalue(val, "%d", wh);	case OPTtext:		c = OPTION(ft->ptr, char*, o->offset);		if(c == nil)			c = "";		free(buf);		return tkvalue(val, "%s", c);	case OPTwinp:		w = OPTION(ft->ptr, Tk*, o->offset);		if(w == nil || w->name == nil)			c = "";		else			c = w->name->name;		free(buf);		return tkvalue(val, "%s", c);	case OPTstab:		s = o->aux;		c = "";		con = OPTION(ft->ptr, int, o->offset);		while(s->val) {			if(con == s->con) {				c = s->val;				break;			}			s++;		}		free(buf);		return tkvalue(val, "%s", c);	case OPTflag:		s = o->aux;		c = "";		con = OPTION(ft->ptr, int, o->offset);		while(s->val) {			if(s->con == 0)				c = s->val;			if(con & s->con) {				c = s->val;				break;			}			s++;		}		free(buf);		return tkvalue(val, "%s", c);	case OPTfont:		e = OPTION(ft->ptr, TkEnv*, o->offset);		free(buf);		return tkvalue(val, "%s", e->font->name);	case OPTcolr:		e = OPTION(ft->ptr, TkEnv*, o->offset);		i = AUXI(o->aux);		free(buf);		return tkvalue(val, "#%.6x", cmap2rgb(e->colors[i]));	case OPTfrac:		v = &OPTION(ft->ptr, int, o->offset);		n = (int)o->aux;		if(n == 0)			n = 1;		fmt = "%s";		for(i = 0; i < n; i++) {			tkfprint(buf, *v++);			r = tkvalue(val, fmt, buf);			if(r != nil) {				free(buf);				return r;			}			fmt = " %s";		}		free(buf);		return nil;	}} static char*pdist(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){	int d;	char *p; 	USED(buf);	USED(ebuf);	p = tkfrac(t, *str, &d, OPTION(place, TkEnv*, AUXI(o->aux)));	if(p == nil)		return TkBadvl;	*str = p;	OPTION(place, int, o->offset) = TKF2I(d);	return nil;} static char*psize(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){	Tk *tk;	char *p;	int d, off; 	USED(ebuf);	p = tkfrac(t, *str, &d, OPTION(place, TkEnv*, AUXI(o->aux)));	if(p == nil)		return TkBadvl;	*str = p; 	tk = place;	if(strcmp(buf+1, "width") == 0) {		tk->flag |= Tksetwidth;		off = O(Tk, req.width);	}	else {		tk->flag |= Tksetheight;		off = O(Tk, req.height);	}	OPTION(place, int, off) = TKF2I(d);	return nil;} static char*pstab(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){	char *p;	int mask;	TkStab *s, *c; 	p = tkword(t, *str, buf, ebuf);	if(*buf == '\0')		return TkOparg;	*str = p; 	for(s = o->aux; s->val; s++)		if(strcmp(s->val, buf) == 0)			break;	if(s->val == nil)		return TkBadvl; 	if(o->type == OPTstab) {		OPTION(place, int, o->offset) = s->con;		return nil;	} 	mask = 0;	for(c = o->aux; c->val; c++)		mask |= c->con; 	OPTION(place, int, o->offset) &= ~mask;	OPTION(place, int, o->offset) |= s->con;	return nil;} static char*ptext(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){	char **p; 	*str = tkword(t, *str, buf, ebuf); 	p = &OPTION(place, char*, o->offset);	if(*p != nil)		free(*p);	if(buf[0] == '\0')		*p = nil;	else {		*p = strdup(buf);		if(*p == nil)			return TkNomem;	}	return nil;} static char*pimag(TkTop *t, TkOption *o, void *place, char **str, char *buf, char *ebuf){	int locked;	Display *d;	TkImg **p, *i; 	i = nil;	p = &OPTION(place, TkImg*, o->offset);	*str = tkword(t, *str, buf, ebuf);	if(*buf != '\0') {		i = tkname2img(t, buf);		if(i == nil)

Lines 1–500 of 909.