if ((size_t) co == cm->max)
{ while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max]))
cm->max--;
assert(cm->free >= 0); while ((size_t) cm->free > cm->max)
cm->free = cm->cd[cm->free].sub; if (cm->free > 0)
{
assert(cm->free < cm->max);
pco = cm->free;
nco = cm->cd[pco].sub; while (nco > 0) if ((size_t) nco > cm->max)
{ /* take this one out of freelist */
nco = cm->cd[nco].sub;
cm->cd[pco].sub = nco;
} else
{
assert(nco < cm->max);
pco = nco;
nco = cm->cd[pco].sub;
}
}
} else
{
cd->sub = cm->free;
cm->free = (color) (cd - cm->cd);
}
}
/* *pseudocolor-allocateafalsecolor,tobemanagedbyothermeans
*/ static color
pseudocolor(struct colormap *cm)
{
color co; struct colordesc *cd;
co = newcolor(cm); if (CISERR()) return COLORLESS;
cd = &cm->cd[co];
cd->nschrs = 0;
cd->nuchrs = 1; /* pretend it is in the upper map */
cd->sub = NOSUB;
cd->arcs = NULL;
cd->firstchr = CHR_MIN;
cd->flags = PSEUDO; return co;
}
/* *subcolor-allocateanewsubcolor(ifnecessary)tothischr * *Thisworksonlyforchrsthatmapintothelowcolormap.
*/ static color
subcolor(struct colormap *cm, chr c)
{
color co; /* current color of c */
color sco; /* new subcolor */
assert(c <= MAX_SIMPLE_CHR);
co = cm->locolormap[c - CHR_MIN];
sco = newsub(cm, co); if (CISERR()) return COLORLESS;
assert(sco != COLORLESS);
if (co == sco) /* already in an open subcolor */ return co; /* rest is redundant */
cm->cd[co].nschrs--; if (cm->cd[sco].nschrs == 0)
cm->cd[sco].firstchr = c;
cm->cd[sco].nschrs++;
cm->locolormap[c - CHR_MIN] = sco; return sco;
}
/* *subcolorhi-allocateanewsubcolor(ifnecessary)tothiscolormapentry * *Thisisthesameprocessingassubcolor(),butforentriesinthehigh *colormap,whichdonotnecessarilycorrespondtoexactlyonechrcode.
*/ static color
subcolorhi(struct colormap *cm, color *pco)
{
color co; /* current color of entry */
color sco; /* new subcolor */
co = *pco;
sco = newsub(cm, co); if (CISERR()) return COLORLESS;
assert(sco != COLORLESS);
if (co == sco) /* already in an open subcolor */ return co; /* rest is redundant */
cm->cd[co].nuchrs--;
cm->cd[sco].nuchrs++;
*pco = sco; return sco;
}
/* *newsub-allocateanewsubcolor(ifnecessary)foracolor
*/ static color
newsub(struct colormap *cm,
color co)
{
color sco; /* new subcolor */
sco = cm->cd[co].sub; if (sco == NOSUB)
{ /* color has no open subcolor */ /* optimization: singly-referenced color need not be subcolored */ if ((cm->cd[co].nschrs + cm->cd[co].nuchrs) == 1) return co;
sco = newcolor(cm); /* must create subcolor */ if (sco == COLORLESS)
{
assert(CISERR()); return COLORLESS;
}
cm->cd[co].sub = sco;
cm->cd[sco].sub = sco; /* open subcolor points to self */
}
assert(sco != NOSUB);
return sco;
}
/* *newhicolorrow-getanewrowinthehicolormap,cloningitfromoldrow * *Returnsarrayindexofnewrow.Notethearraymightmove.
*/ staticint
newhicolorrow(struct colormap *cm, int oldrow)
{ int newrow = cm->hiarrayrows;
color *newrowptr; int i;
/* Assign a fresh array row index, enlarging storage if needed */ if (newrow >= cm->maxarrayrows)
{
color *newarray;
/* Duplicate existing columns to the right, and increase ref counts */ /* Must work backwards in the array because we realloc'd in place */ for (r = cm->hiarrayrows - 1; r >= 0; r--)
{
color *oldrowptr = &newarray[r * cm->hiarraycols];
color *newrowptr = &newarray[r * cm->hiarraycols * 2];
color *newrowptr2 = newrowptr + cm->hiarraycols;
for (c = 0; c < cm->hiarraycols; c++)
{
color co = oldrowptr[c];
/* *subcolorcvec-allocatenewsubcolorstocvecmembers,fillinarcs * *Foreachchr"c"representedbythecvec,dotheequivalentof *newarc(v->nfa,PLAIN,subcolor(v->cm,c),lp,rp); * *Notethatintypicalcases,manyofthesubcolorsarethesame. *Whilenewarc()woulddiscardduplicatearcrequests,wecansave *somecyclesbynotcallingitrepetitivelytobeginwith.Thisis *mechanizedwiththe"lastsubcolor"statevariable.
*/ staticvoid
subcolorcvec(struct vars *v, struct cvec *cv, struct state *lp, struct state *rp)
{ struct colormap *cm = v->cm;
color lastsubcolor = COLORLESS;
chr ch,
from,
to; const chr *p; int i;
/* ordinary characters */ for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--)
{
ch = *p;
subcoloronechr(v, ch, lp, rp, &lastsubcolor);
NOERR();
}
/* and the ranges */ for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--)
{
from = *p;
to = *(p + 1); if (from <= MAX_SIMPLE_CHR)
{ /* deal with simple chars one at a time */
chr lim = (to <= MAX_SIMPLE_CHR) ? to : MAX_SIMPLE_CHR;
while (from <= lim)
{
color sco = subcolor(cm, from);
NOERR(); if (sco != lastsubcolor)
{
newarc(v->nfa, PLAIN, sco, lp, rp);
NOERR();
lastsubcolor = sco;
}
from++;
}
} /* deal with any part of the range that's above MAX_SIMPLE_CHR */ if (from < to)
subcoloronerange(v, from, to, lp, rp, &lastsubcolor); elseif (from == to)
subcoloronechr(v, from, lp, rp, &lastsubcolor);
NOERR();
}
/* and deal with cclass if any */ if (cv->cclasscode >= 0)
{ int classbit;
color *pco; int r,
c;
/* Enlarge array if we don't have a column bit assignment for cclass */ if (cm->classbits[cv->cclasscode] == 0)
{
cm->classbits[cv->cclasscode] = cm->hiarraycols;
newhicolorcols(cm);
NOERR();
} /* Apply subcolorhi() and make arc for each entry in relevant cols */
classbit = cm->classbits[cv->cclasscode];
pco = cm->hicolormap; for (r = 0; r < cm->hiarrayrows; r++)
{ for (c = 0; c < cm->hiarraycols; c++)
{ if (c & classbit)
{
color sco = subcolorhi(cm, pco);
NOERR(); /* add the arc if needed */ if (sco != lastsubcolor)
{
newarc(v->nfa, PLAIN, sco, lp, rp);
NOERR();
lastsubcolor = sco;
}
}
pco++;
}
}
}
}
/* *subcoloronechr-dosubcolorcvec'sworkforasingletonchr * *Wecouldjustletsubcoloronerangedothis,butit'sabitmoreefficient *ifweexploitthesingle-chrcase.Also,callersfinditusefulforthis *tobeabletohandlebothlowandhighchrcodes.
*/ staticvoid
subcoloronechr(struct vars *v,
chr ch, struct state *lp, struct state *rp,
color *lastsubcolor)
{ struct colormap *cm = v->cm;
colormaprange *newranges; int numnewranges;
colormaprange *oldrange; int oldrangen; int newrow;
/* Easy case for low chr codes */ if (ch <= MAX_SIMPLE_CHR)
{
color sco = subcolor(cm, ch);
/* Ranges before target are unchanged */ for (oldrange = cm->cmranges, oldrangen = 0;
oldrangen < cm->numcmranges;
oldrange++, oldrangen++)
{ if (oldrange->cmax >= ch) break;
newranges[numnewranges++] = *oldrange;
}
/* Match target chr against current range */ if (oldrangen >= cm->numcmranges || oldrange->cmin > ch)
{ /* chr does not belong to any existing range, make a new one */
newranges[numnewranges].cmin = ch;
newranges[numnewranges].cmax = ch; /* row state should be cloned from the "all others" row */
newranges[numnewranges].rownum = newrow = newhicolorrow(cm, 0);
numnewranges++;
} elseif (oldrange->cmin == oldrange->cmax)
{ /* we have an existing singleton range matching the chr */
newranges[numnewranges++] = *oldrange;
newrow = oldrange->rownum; /* we've now fully processed this old range */
oldrange++, oldrangen++;
} else
{ /* chr is a subset of this existing range, must split it */ if (ch > oldrange->cmin)
{ /* emit portion of old range before chr */
newranges[numnewranges].cmin = oldrange->cmin;
newranges[numnewranges].cmax = ch - 1;
newranges[numnewranges].rownum = oldrange->rownum;
numnewranges++;
} /* emit chr as singleton range, initially cloning from range */
newranges[numnewranges].cmin = ch;
newranges[numnewranges].cmax = ch;
newranges[numnewranges].rownum = newrow =
newhicolorrow(cm, oldrange->rownum);
numnewranges++; if (ch < oldrange->cmax)
{ /* emit portion of old range after chr */
newranges[numnewranges].cmin = ch + 1;
newranges[numnewranges].cmax = oldrange->cmax; /* must clone the row if we are making two new ranges from old */
newranges[numnewranges].rownum =
(ch > oldrange->cmin) ? newhicolorrow(cm, oldrange->rownum) :
oldrange->rownum;
numnewranges++;
} /* we've now fully processed this old range */
oldrange++, oldrangen++;
}
/* Update colors in newrow and create arcs as needed */
subcoloronerow(v, newrow, lp, rp, lastsubcolor);
/* Ranges after target are unchanged */ for (; oldrangen < cm->numcmranges; oldrange++, oldrangen++)
{
newranges[numnewranges++] = *oldrange;
}
/* Assert our original space estimate was adequate */
assert(numnewranges <= (cm->numcmranges + 2));
/* And finally, store back the updated list of ranges */ if (cm->cmranges != NULL)
FREE(cm->cmranges);
cm->cmranges = newranges;
cm->numcmranges = numnewranges;
}
/* *subcoloronerange-dosubcolorcvec'sworkforahighrange
*/ staticvoid
subcoloronerange(struct vars *v,
chr from,
chr to, struct state *lp, struct state *rp,
color *lastsubcolor)
{ struct colormap *cm = v->cm;
colormaprange *newranges; int numnewranges;
colormaprange *oldrange; int oldrangen; int newrow;
/* Caller should take care of non-high-range cases */
assert(from > MAX_SIMPLE_CHR);
assert(from < to);
/* Ranges before target are unchanged */ for (oldrange = cm->cmranges, oldrangen = 0;
oldrangen < cm->numcmranges;
oldrange++, oldrangen++)
{ if (oldrange->cmax >= from) break;
newranges[numnewranges++] = *oldrange;
}
/* *Dealwithrangesthat(partially)overlapthetarget.Asweprocess *eachsuchrange,increase"from"toremovethedealt-withcharacters *fromthetargetrange.
*/ while (oldrangen < cm->numcmranges && oldrange->cmin <= to)
{ if (from < oldrange->cmin)
{ /* Handle portion of new range that corresponds to no old range */
newranges[numnewranges].cmin = from;
newranges[numnewranges].cmax = oldrange->cmin - 1; /* row state should be cloned from the "all others" row */
newranges[numnewranges].rownum = newrow = newhicolorrow(cm, 0);
numnewranges++; /* Update colors in newrow and create arcs as needed */
subcoloronerow(v, newrow, lp, rp, lastsubcolor); /* We've now fully processed the part of new range before old */
from = oldrange->cmin;
}
if (from <= oldrange->cmin && to >= oldrange->cmax)
{ /* old range is fully contained in new, process it in-place */
newranges[numnewranges++] = *oldrange;
newrow = oldrange->rownum;
from = oldrange->cmax + 1;
} else
{ /* some part of old range does not overlap new range */ if (from > oldrange->cmin)
{ /* emit portion of old range before new range */
newranges[numnewranges].cmin = oldrange->cmin;
newranges[numnewranges].cmax = from - 1;
newranges[numnewranges].rownum = oldrange->rownum;
numnewranges++;
} /* emit common subrange, initially cloning from old range */
newranges[numnewranges].cmin = from;
newranges[numnewranges].cmax =
(to < oldrange->cmax) ? to : oldrange->cmax;
newranges[numnewranges].rownum = newrow =
newhicolorrow(cm, oldrange->rownum);
numnewranges++; if (to < oldrange->cmax)
{ /* emit portion of old range after new range */
newranges[numnewranges].cmin = to + 1;
newranges[numnewranges].cmax = oldrange->cmax; /* must clone the row if we are making two new ranges from old */
newranges[numnewranges].rownum =
(from > oldrange->cmin) ? newhicolorrow(cm, oldrange->rownum) :
oldrange->rownum;
numnewranges++;
}
from = oldrange->cmax + 1;
} /* Update colors in newrow and create arcs as needed */
subcoloronerow(v, newrow, lp, rp, lastsubcolor); /* we've now fully processed this old range */
oldrange++, oldrangen++;
}
if (from <= to)
{ /* Handle portion of new range that corresponds to no old range */
newranges[numnewranges].cmin = from;
newranges[numnewranges].cmax = to; /* row state should be cloned from the "all others" row */
newranges[numnewranges].rownum = newrow = newhicolorrow(cm, 0);
numnewranges++; /* Update colors in newrow and create arcs as needed */
subcoloronerow(v, newrow, lp, rp, lastsubcolor);
}
/* Ranges after target are unchanged */ for (; oldrangen < cm->numcmranges; oldrange++, oldrangen++)
{
newranges[numnewranges++] = *oldrange;
}
/* Assert our original space estimate was adequate */
assert(numnewranges <= (cm->numcmranges * 2 + 1));
/* And finally, store back the updated list of ranges */ if (cm->cmranges != NULL)
FREE(cm->cmranges);
cm->cmranges = newranges;
cm->numcmranges = numnewranges;
}
/* *subcoloronerow-dosubcolorcvec'sworkforonenewrowinthehighcolormap
*/ staticvoid
subcoloronerow(struct vars *v, int rownum, struct state *lp, struct state *rp,
color *lastsubcolor)
{ struct colormap *cm = v->cm;
color *pco; int i;
/* Apply subcolorhi() and make arc for each entry in row */
pco = &cm->hicolormap[rownum * cm->hiarraycols]; for (i = 0; i < cm->hiarraycols; pco++, i++)
{
color sco = subcolorhi(cm, pco);
NOERR(); /* make the arc if needed */ if (sco != *lastsubcolor)
{
newarc(v->nfa, PLAIN, sco, lp, rp);
NOERR();
*lastsubcolor = sco;
}
}
}
/* Gotta do it the hard way. Skip subcolors, pseudocolors, and "but" */ 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-addarcsofcomplementarycolors * *Weaddarcsofallcolorsthatarenotpseudocolorsanddonotmatch *anyofthe"of"state'sPLAINoutarcs. * *Thecallingsequenceoughttobereconciledwithcloneouts().
*/ staticvoid
colorcomplement(struct nfa *nfa, struct colormap *cm, int type, struct state *of, struct state *from, struct state *to)
{ struct colordesc *cd; struct colordesc *end = CDEND(cm);
color co; struct arc *a;
/* Otherwise, transiently mark the colors that appear in of's out-arcs */ for (a = of->outs; a != NULL; a = a->outchain)
{ if (a->type == PLAIN)
{
assert(a->co >= 0);
cd = &cm->cd[a->co];
assert(!UNUSEDCOLOR(cd));
cd->flags |= COLMARK;
}
fprintf(f, "max %ld\n", (long) cm->max);
end = CDEND(cm); for (cd = cm->cd + 1, co = 1; cd < end; cd++, co++) /* skip 0 */
{ if (!UNUSEDCOLOR(cd))
{
assert(cd->nschrs > 0 || cd->nuchrs > 0); if (cd->flags & PSEUDO)
fprintf(f, "#%2ld(ps): ", (long) co); else
fprintf(f, "#%2ld(%2d): ", (long) co, cd->nschrs + cd->nuchrs);
/* *Unfortunately,it'shardtodothisnextbitmoreefficiently.
*/ for (c = CHR_MIN; c <= MAX_SIMPLE_CHR; c++) if (GETCOLOR(cm, c) == co)
dumpchr(c, f);
fprintf(f, "\n");
}
} /* dump the high colormap if it contains anything interesting */ if (cm->hiarrayrows > 1 || cm->hiarraycols > 1)
{ int r,
c; const color *rowptr;
fprintf(f, "other:\t"); for (c = 0; c < cm->hiarraycols; c++)
{
fprintf(f, "\t%ld", (long) cm->hicolormap[c]);
}
fprintf(f, "\n"); for (r = 0; r < cm->numcmranges; r++)
{
dumpchr(cm->cmranges[r].cmin, f);
fprintf(f, "..");
dumpchr(cm->cmranges[r].cmax, f);
fprintf(f, ":");
rowptr = &cm->hicolormap[cm->cmranges[r].rownum * cm->hiarraycols]; for (c = 0; c < cm->hiarraycols; c++)
{
fprintf(f, "\t%ld", (long) rowptr[c]);
}
fprintf(f, "\n");
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.