regc_color.c

来自「tcl是工具命令语言」· C语言 代码 · 共 779 行 · 第 1/2 页

C
779
字号
		cm->cd[sco].sub = sco;	/* open subcolor points to self */	}	assert(sco != NOSUB);	return sco;}/* - subrange - allocate new subcolors to this range of chrs, fill in arcs ^ static VOID subrange(struct vars *, pchr, pchr, struct state *, ^ 	struct state *); */static VOIDsubrange(v, from, to, lp, rp)struct vars *v;pchr from;pchr to;struct state *lp;struct state *rp;{	uchr uf;	int i;	assert(from <= to);	/* first, align "from" on a tree-block boundary */	uf = (uchr)from;	i = (int)( ((uf + BYTTAB-1) & (uchr)~BYTMASK) - uf );	for (; from <= to && i > 0; i--, from++)		newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);	if (from > to)			/* didn't reach a boundary */		return;	/* deal with whole blocks */	for (; to - from >= BYTTAB; from += BYTTAB)		subblock(v, from, lp, rp);	/* clean up any remaining partial table */	for (; from <= to; from++)		newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);}/* - subblock - allocate new subcolors for one tree block of chrs, fill in arcs ^ static VOID subblock(struct vars *, pchr, struct state *, struct state *); */static VOIDsubblock(v, start, lp, rp)struct vars *v;pchr start;			/* first of BYTTAB chrs */struct state *lp;struct state *rp;{	uchr uc = start;	struct colormap *cm = v->cm;	int shift;	int level;	int i;	int b;	union tree *t;	union tree *cb;	union tree *fillt;	union tree *lastt;	int previ;	int ndone;	color co;	color sco;	assert((uc % BYTTAB) == 0);	/* find its color block, making new pointer blocks as needed */	t = cm->tree;	fillt = NULL;	for (level = 0, shift = BYTBITS * (NBYTS - 1); shift > 0;						level++, shift -= BYTBITS) {		b = (uc >> shift) & BYTMASK;		lastt = t;		t = lastt->tptr[b];		assert(t != NULL);		fillt = &cm->tree[level+1];		if (t == fillt && shift > BYTBITS) {	/* need new ptr block */			t = (union tree *)MALLOC(sizeof(struct ptrs));			if (t == NULL) {				CERR(REG_ESPACE);				return;			}			memcpy(VS(t->tptr), VS(fillt->tptr),						BYTTAB*sizeof(union tree *));			lastt->tptr[b] = t;		}	}	/* special cases:  fill block or solid block */	co = t->tcolor[0];	cb = cm->cd[co].block;	if (t == fillt || t == cb) {		/* either way, we want a subcolor solid block */		sco = newsub(cm, co);		t = cm->cd[sco].block;		if (t == NULL) {	/* must set it up */			t = (union tree *)MALLOC(sizeof(struct colors));			if (t == NULL) {				CERR(REG_ESPACE);				return;			}			for (i = 0; i < BYTTAB; i++)				t->tcolor[i] = sco;			cm->cd[sco].block = t;		}		/* find loop must have run at least once */		lastt->tptr[b] = t;		newarc(v->nfa, PLAIN, sco, lp, rp);		cm->cd[co].nchrs -= BYTTAB;		cm->cd[sco].nchrs += BYTTAB;		return;	}	/* general case, a mixed block to be altered */	i = 0;	while (i < BYTTAB) {		co = t->tcolor[i];		sco = newsub(cm, co);		newarc(v->nfa, PLAIN, sco, lp, rp);		previ = i;		do {			t->tcolor[i++] = sco;		} while (i < BYTTAB && t->tcolor[i] == co);		ndone = i - previ;		cm->cd[co].nchrs -= ndone;		cm->cd[sco].nchrs += ndone;	}}/* - okcolors - promote subcolors to full colors ^ static VOID okcolors(struct nfa *, struct colormap *); */static VOIDokcolors(nfa, cm)struct nfa *nfa;struct colormap *cm;{	struct colordesc *cd;	struct colordesc *end = CDEND(cm);	struct colordesc *scd;	struct arc *a;	color co;	color sco;	for (cd = cm->cd, co = 0; cd < end; cd++, co++) {		sco = cd->sub;		if (UNUSEDCOLOR(cd) || sco == NOSUB) {			/* has no subcolor, no further action */		} else if (sco == co) {			/* is subcolor, let parent deal with it */		} else if (cd->nchrs == 0) {			/* parent empty, its arcs change color to subcolor */			cd->sub = NOSUB;			scd = &cm->cd[sco];			assert(scd->nchrs > 0);			assert(scd->sub == sco);			scd->sub = NOSUB;			while ((a = cd->arcs) != NULL) {				assert(a->co == co);				/* uncolorchain(cm, a); */				cd->arcs = a->colorchain;				a->co = sco;				/* colorchain(cm, a); */				a->colorchain = scd->arcs;				scd->arcs = a;			}			freecolor(cm, co);		} else {			/* parent's arcs must gain parallel subcolor arcs */			cd->sub = NOSUB;			scd = &cm->cd[sco];			assert(scd->nchrs > 0);			assert(scd->sub == sco);			scd->sub = NOSUB;			for (a = cd->arcs; a != NULL; a = a->colorchain) {				assert(a->co == co);				newarc(nfa, a->type, sco, a->from, a->to);			}		}	}}/* - colorchain - add this arc to the color chain of its color ^ static VOID colorchain(struct colormap *, struct arc *); */static VOIDcolorchain(cm, a)struct colormap *cm;struct arc *a;{	struct colordesc *cd = &cm->cd[a->co];	a->colorchain = cd->arcs;	cd->arcs = a;}/* - uncolorchain - delete this arc from the color chain of its color ^ static VOID uncolorchain(struct colormap *, struct arc *); */static VOIDuncolorchain(cm, a)struct colormap *cm;struct arc *a;{	struct colordesc *cd = &cm->cd[a->co];	struct arc *aa;	aa = cd->arcs;	if (aa == a)		/* easy case */		cd->arcs = a->colorchain;	else {		for (; aa != NULL && aa->colorchain != a; aa = aa->colorchain)			continue;		assert(aa != NULL);		aa->colorchain = a->colorchain;	}	a->colorchain = NULL;	/* paranoia */}/* - singleton - is this character in its own color? ^ static int singleton(struct colormap *, pchr c); */static int			/* predicate */singleton(cm, c)struct colormap *cm;pchr c;{	color co;			/* color of c */	co = GETCOLOR(cm, c);	if (cm->cd[co].nchrs == 1 && cm->cd[co].sub == NOSUB)		return 1;	return 0;}/* - rainbow - add arcs of all full colors (but one) between specified states ^ static VOID rainbow(struct nfa *, struct colormap *, int, pcolor, ^ 	struct state *, struct state *); */static VOIDrainbow(nfa, cm, type, but, from, to)struct nfa *nfa;struct colormap *cm;int type;pcolor but;			/* COLORLESS if no exceptions */struct state *from;struct state *to;{	struct colordesc *cd;	struct colordesc *end = CDEND(cm);	color co;	for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)		if (!UNUSEDCOLOR(cd) && cd->sub != co && co != but &&							!(cd->flags&PSEUDO))			newarc(nfa, type, co, from, to);}/* - colorcomplement - add arcs of complementary colors * The calling sequence ought to be reconciled with cloneouts(). ^ static VOID colorcomplement(struct nfa *, struct colormap *, int, ^ 	struct state *, struct state *, struct state *); */static VOIDcolorcomplement(nfa, cm, type, of, from, to)struct nfa *nfa;struct colormap *cm;int type;struct state *of;		/* complements of this guy's PLAIN outarcs */struct state *from;struct state *to;{	struct colordesc *cd;	struct colordesc *end = CDEND(cm);	color co;	assert(of != from);	for (cd = cm->cd, co = 0; cd < end && !CISERR(); cd++, co++)		if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO))			if (findarc(of, PLAIN, co) == NULL)				newarc(nfa, type, co, from, to);}#ifdef REG_DEBUG/* ^ #ifdef REG_DEBUG *//* - dumpcolors - debugging output ^ static VOID dumpcolors(struct colormap *, FILE *); */static VOIDdumpcolors(cm, f)struct colormap *cm;FILE *f;{	struct colordesc *cd;	struct colordesc *end;	color co;	chr c;	char *has;	fprintf(f, "max %ld\n", (long)cm->max);	if (NBYTS > 1)		fillcheck(cm, cm->tree, 0, f);	end = CDEND(cm);	for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++)	/* skip 0 */		if (!UNUSEDCOLOR(cd)) {			assert(cd->nchrs > 0);			has = (cd->block != NULL) ? "#" : "";			if (cd->flags&PSEUDO)				fprintf(f, "#%2ld%s(ps): ", (long)co, has);			else				fprintf(f, "#%2ld%s(%2d): ", (long)co,							has, cd->nchrs);			/* it's hard to do this more efficiently */			for (c = CHR_MIN; c < CHR_MAX; c++)				if (GETCOLOR(cm, c) == co)					dumpchr(c, f);			assert(c == CHR_MAX);			if (GETCOLOR(cm, c) == co)				dumpchr(c, f);			fprintf(f, "\n");		}}/* - fillcheck - check proper filling of a tree ^ static VOID fillcheck(struct colormap *, union tree *, int, FILE *); */static VOIDfillcheck(cm, tree, level, f)struct colormap *cm;union tree *tree;int level;			/* level number (top == 0) of this block */FILE *f;{	int i;	union tree *t;	union tree *fillt = &cm->tree[level+1];	assert(level < NBYTS-1);	/* this level has pointers */	for (i = BYTTAB-1; i >= 0; i--) {		t = tree->tptr[i];		if (t == NULL)			fprintf(f, "NULL found in filled tree!\n");		else if (t == fillt)			{}		else if (level < NBYTS-2)	/* more pointer blocks below */			fillcheck(cm, t, level+1, f);	}}/* - dumpchr - print a chr * Kind of char-centric but works well enough for debug use. ^ static VOID dumpchr(pchr, FILE *); */static VOIDdumpchr(c, f)pchr c;FILE *f;{	if (c == '\\')		fprintf(f, "\\\\");	else if (c > ' ' && c <= '~')		putc((char)c, f);	else		fprintf(f, "\\u%04lx", (long)c);}/* ^ #endif */#endif				/* ifdef REG_DEBUG */

⌨️ 快捷键说明

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